Subversion Repository Public Repository

litesoft

Diff Revisions 948 vs 950 for /trunk/Java/core/Server/src/org/litesoft/orsup/DB_ImportSupport.java

Diff revisions: vs.
  @@ -1,449 +1,448 @@
1 - // This Source Code is in the Public Domain per: http://unlicense.org
2 - package org.litesoft.orsup;
3 -
4 - import org.litesoft.commonfoundation.base.*;
5 - import org.litesoft.commonfoundation.csv.*;
6 - import org.litesoft.commonfoundation.exceptions.*;
7 - import org.litesoft.commonfoundation.typeutils.Objects;
8 - import org.litesoft.commonfoundation.typeutils.*;
9 - import org.litesoft.core.simpletypes.temporal.*;
10 - import org.litesoft.core.util.*;
11 - import org.litesoft.logger.*;
12 - import org.litesoft.orsup.base.*;
13 - import org.litesoft.orsup.nonpublic.*;
14 - import org.litesoft.orsup.otherattributeaccessors.*;
15 - import org.litesoft.orsup.transact.*;
16 - import org.litesoft.util.*;
17 -
18 - import java.io.*;
19 - import java.lang.reflect.*;
20 - import java.util.*;
21 -
22 - public class DB_ImportSupport {
23 - public static final String TODAY_RELATIVE = ":T";
24 - public static final String DELTA_DATE_RELATIVE = ":DD";
25 - public static final String DELTA_DATE_SEP = "+T-";
26 - public static final String FILE_ATTRIBUTE = "@";
27 - public static final String SETTER_ATTRIBUTE = "()";
28 - public static final String PO_URL_ATTRIBUTE = ":";
29 -
30 - protected static class ImportFromMap {
31 - public void process( Logger pLogger, UnfilteringFinder pFinder, File pReferenceDir, Map<FauxPOref, Attributes> pLineMap )
32 - throws IOException {
33 - if ( pLineMap.isEmpty() ) {
34 - throw new IllegalArgumentException( "No Data Found" );
35 - }
36 - new Inner( pLogger, pFinder.createUnaugmentedTransaction(), pReferenceDir, pLineMap ).process().commit();
37 - }
38 -
39 - private class Inner {
40 - private Logger mLogger;
41 - private Transaction mTransaction;
42 - private File mReferenceDir;
43 - private Map<FauxPOref, Attributes> mLineMap;
44 - private Map<FauxPOref, PersistentObject<?>> mPOsByRef = new HashMap<FauxPOref, PersistentObject<?>>();
45 -
46 - private Inner( Logger pLogger, Transaction pTransaction, File pReferenceDir, Map<FauxPOref, Attributes> pLineMap ) {
47 - mLogger = pLogger;
48 - mTransaction = pTransaction;
49 - mReferenceDir = pReferenceDir;
50 - mLineMap = pLineMap;
51 - }
52 -
53 - public Transaction process() {
54 - for ( FauxPOref ref : mLineMap.keySet() ) {
55 - putLineInDB( ref );
56 - }
57 - return mTransaction;
58 - }
59 -
60 - private PersistentObject<?> putLineInDB( FauxPOref pPOref ) {
61 - PersistentObject<?> zPO = mPOsByRef.get( pPOref );
62 - if ( zPO == null ) // NOT Already created
63 - {
64 - mPOsByRef.put( pPOref, zPO = mTransaction.create( pPOref.getPersistedObjectRegistrationName() ) );
65 -
66 - Attributes attributes = mLineMap.get( pPOref );
67 - if ( attributes == null ) {
68 - throw new IllegalArgumentException( "No Attributes (Line) found for URL: " + pPOref );
69 - }
70 - mLogger.trace.log( "writing line to db for URL: ", pPOref );
71 -
72 - for ( String attrName : attributes.getNames() ) {
73 - String value = attributes.getValue( attrName );
74 -
75 - // If the attribute is calling a setter method ..
76 - if ( attrName.endsWith( SETTER_ATTRIBUTE ) ) {
77 - try {
78 - String methodName = attrName.substring( 0, attrName.length() - SETTER_ATTRIBUTE.length() );
79 - Method method = zPO.getClass().getMethod( methodName, String.class );
80 - if ( method != null ) {
81 - method.invoke( zPO, value );
82 - }
83 - }
84 - catch ( InvocationTargetException e ) {
85 - throw new RuntimeException( e );
86 - }
87 - catch ( NoSuchMethodException e ) {
88 - throw new RuntimeException( e );
89 - }
90 - catch ( IllegalAccessException e ) {
91 - throw new RuntimeException( e );
92 - }
93 - // Setter methods aren't actual attributes, so skip the rest of the iteration.
94 - continue;
95 - }
96 -
97 - boolean isURLAttribute = false;
98 - if ( attrName.endsWith( PO_URL_ATTRIBUTE ) ) {
99 - attrName = attrName.substring( 0, attrName.length() - PO_URL_ATTRIBUTE.length() );
100 - isURLAttribute = true;
101 - }
102 - if ( attrName.endsWith( FILE_ATTRIBUTE ) ) {
103 - attrName = attrName.substring( 0, attrName.length() - FILE_ATTRIBUTE.length() );
104 - value = readFileAttributeValue( value );
105 - }
106 -
107 - AttributeAccessorSCD scd = zPO.getMetaDataForPO().getAccessorSCDoptional( attrName );
108 - if ( scd == null ) {
109 - throw new IllegalArgumentException( zPO.getObjectName() + " does NOT appear to have an attribute named: '" + attrName + "'" );
110 - }
111 - if ( !(scd instanceof NonImportableFeature) ) {
112 - Object setValue = value;
113 - if ( AttributeAccessorSCD.Form.ToOne == scd.getForm() ) {
114 - if ( scd instanceof AttributeAccessorSCDtoOneVariable ) {
115 - PO_VarURLstringHelper zVarURL = new PO_VarURLstringHelper( value );
116 - FauxPOref childRef = new FauxPOref( mTransaction, zVarURL.getPersistentObjectURL() );
117 - PersistentObject<?> po = putLineInDB( childRef );
118 - setValue = new PO_VarURLstringHelper( zVarURL.getPersistedObjectAttributeName(), po.getPersistentObjectURL().toString() );
119 - } else {
120 - FauxPOref childRef = new FauxPOref( mTransaction, value );
121 - setValue = putLineInDB( childRef );
122 - }
123 - } else if ( looksLikeAReference( scd, value ) ) {
124 - // support quasi-foreign keys.
125 - FauxPOref childRef = new FauxPOref( mTransaction, value );
126 - setValue = putLineInDB( childRef );
127 - PersistentObject po = (PersistentObject) setValue;
128 - try {
129 - setValue = po.getPersistentObjectUniqueKey();
130 - }
131 - catch ( Exception e ) {
132 - e.printStackTrace();
133 - }
134 - } else if ( isURLAttribute ) {
135 - FauxPOref childRef = new FauxPOref( mTransaction, value );
136 - setValue = putLineInDB( childRef ).getPersistentObjectURL().toString();
137 - }
138 - zPO.setAttributeValue( attrName, setValue );
139 - }
140 - }
141 - }
142 - return zPO;
143 - }
144 -
145 - private boolean looksLikeAReference( AttributeAccessorSCD pScd, String pValue ) {
146 - if ( !(pScd.getColumnType().equals( Long.class )) ) {
147 - return false;
148 - }
149 - try {
150 - new FauxPOref( mTransaction, pValue );
151 - return true;
152 - }
153 - catch ( Exception e ) {
154 - return false;
155 - }
156 - }
157 -
158 - private String readFileAttributeValue( String fileReference ) {
159 - if ( fileReference.startsWith( "file:" ) ) {
160 - fileReference = fileReference.substring( "file:".length() );
161 - }
162 -
163 - File f;
164 - if ( null != mReferenceDir ) {
165 - f = new File( mReferenceDir, fileReference );
166 - } else {
167 - f = new File( fileReference );
168 - }
169 -
170 - return FileUtils.loadTextFileAsString( f, "\n" );
171 - }
172 - }
173 - }
174 -
175 - protected static class ImportToMap {
176 - private Map<FauxPOref, Attributes> mLineMap = new HashMap<FauxPOref, Attributes>();
177 -
178 - public ImportToMap process( Logger pLogger, Finder pFinder, Reader[] pReaders )
179 - throws IOException {
180 - if ( Objects.isNullOrEmpty( pReaders ) ) {
181 - throw new IllegalArgumentException( "No Readers provided" );
182 - }
183 - try {
184 - new Inner( pLogger, pFinder ).process( pReaders );
185 - }
186 - finally {
187 - for ( Reader reader : pReaders ) {
188 - try {
189 - reader.close();
190 - }
191 - catch ( IOException e ) {
192 - // Whatever!
193 - }
194 - }
195 - }
196 -
197 - return this;
198 - }
199 -
200 - public Map<FauxPOref, Attributes> getLineMap() {
201 - return mLineMap;
202 - }
203 -
204 - private class Inner {
205 - private Logger mLogger;
206 - private Finder mFinder;
207 - private StringBuilder mBuilder;
208 -
209 - private Inner( Logger pLogger, Finder pFinder ) {
210 - mLogger = pLogger;
211 - mFinder = pFinder;
212 - }
213 -
214 - public void process( Reader[] pReaders )
215 - throws IOException {
216 - if ( pReaders[0] instanceof ToStringInformative ) {
217 - mLogger.info.log( "Importing:" );
218 - }
219 - for ( Reader reader : pReaders ) {
220 - if ( reader instanceof ToStringInformative ) {
221 - mLogger.info.log( " ", reader );
222 - }
223 - BufferedReader bufRead = Utils.getBufferedReader( reader );
224 - mBuilder = new StringBuilder();
225 - for ( String line; null != (line = bufRead.readLine()); ) {
226 - putLineInMap( line );
227 - }
228 - if ( mBuilder.length() != 0 ) {
229 - throw new UnclosedQuoteException( " did not find end of line " + mBuilder );
230 - }
231 - }
232 - }
233 -
234 - private void putLineInMap( String pLine ) {
235 - if ( mBuilder.length() == 0 ) {
236 - pLine = pLine.trim();
237 - if ( (pLine.length() == 0) || (pLine.charAt( 0 ) == ';') || (pLine.charAt( 0 ) == '#') || pLine.startsWith( "//" ) ) {
238 - return;
239 - }
240 - }
241 - mBuilder.append( pLine );
242 - try {
243 - putBuilderInMap();
244 - mBuilder.setLength( 0 );
245 - }
246 - catch ( UnclosedQuoteException e ) {
247 - mBuilder.append( "\n" );
248 - }
249 - }
250 -
251 - private void putBuilderInMap() {
252 - String[] decodedData = new CsvSupport().decode( mBuilder.toString() );
253 - FauxPOref ref = new FauxPOref( mFinder, decodedData[0] );
254 - if ( mFinder.getMetaDataRequired( ref.getPersistedObjectRegistrationName() ).isImportable() ) {
255 - Attributes attributes = parseData( decodedData );
256 - if ( !attributes.isEmpty() ) {
257 - mLineMap.put( ref, attributes );
258 - }
259 - }
260 - }
261 -
262 - private Attributes parseData( String[] pDecodedData ) {
263 - Attributes zAttributes = new Attributes();
264 - for ( int i = 1; i < pDecodedData.length; ++i ) {
265 - String pair = Strings.noEmpty( pDecodedData[i] );
266 - if ( pair != null ) {
267 - int equidx = pair.indexOf( '=' );
268 - if ( equidx == -1 ) {
269 - throw new IllegalStateException( "No '=' in: " + pair );
270 - }
271 - String attr = pair.substring( 0, equidx ).trim();
272 - String value = pair.substring( equidx + 1 ).trim();
273 - zAttributes.setNameValue( attr, value );
274 - }
275 - }
276 - return zAttributes;
277 - }
278 - }
279 - }
280 -
281 - protected static class FauxPOref {
282 - public static int sWildcardSequence = 0;
283 -
284 - private MetaDataForPO mPOmd;
285 - private String mIdentifier;
286 -
287 - public FauxPOref( Finder pFinder, String pToString ) {
288 - PO_URLstringHelper helper = new PO_URLstringHelper( pToString );
289 - String zIdentifierOrRegistrationName = helper.getPersistedObjectRegistrationName();
290 - MetaDataForPO zMD = pFinder.getMetaDataOptionallyByIdentifier( zIdentifierOrRegistrationName );
291 - mPOmd = (zMD != null) ? zMD : pFinder.getMetaDataRequired( zIdentifierOrRegistrationName );
292 - mIdentifier = helper.getPersistentObjectUniqueKey();
293 - if ( "?".equals( mIdentifier ) ) {
294 - mIdentifier = "gened-" + ++sWildcardSequence;
295 - }
296 - }
297 -
298 - public MetaDataForPO getPOmd() {
299 - return mPOmd;
300 - }
301 -
302 - public String getPersistedObjectRegistrationName() {
303 - return mPOmd.getPOregistrationName();
304 - }
305 -
306 - public String getIdentifier() {
307 - return mIdentifier;
308 - }
309 -
310 - @Override
311 - public boolean equals( Object o ) {
312 - return (this == o) || ((o instanceof FauxPOref) && equals( (FauxPOref) o ));
313 - }
314 -
315 - public boolean equals( FauxPOref them ) {
316 - return (this == them) || //
317 - ((them != null) //
318 - && (this.mPOmd == them.mPOmd) //
319 - && this.mIdentifier.equals( them.mIdentifier ) //
320 - );
321 - }
322 -
323 - @Override
324 - public int hashCode() {
325 - return 31 * getPersistedObjectRegistrationName().hashCode() + mIdentifier.hashCode();
326 - }
327 -
328 - @Override
329 - public String toString() {
330 - return new PO_URLstringHelper( getPersistedObjectRegistrationName(), mIdentifier ).toString();
331 - }
332 - }
333 -
334 - protected static class Attributes {
335 - private Map<String, String> mNameValues = new HashMap<String, String>();
336 -
337 - public boolean isEmpty() {
338 - return mNameValues.isEmpty();
339 - }
340 -
341 - public String[] getNames() {
342 - return mNameValues.keySet().toArray( new String[mNameValues.size()] );
343 - }
344 -
345 - public String getValue( String pName ) {
346 - return mNameValues.get( pName );
347 - }
348 -
349 - public void setNameValue( String pName, String pValue ) {
350 - if ( pName.endsWith( TODAY_RELATIVE ) ) {
351 - pName = pName.substring( 0, pName.length() - TODAY_RELATIVE.length() ).trim();
352 - pValue = makeTodayRelative( pValue );
353 - } else if ( pName.endsWith( DELTA_DATE_RELATIVE ) ) {
354 - pName = pName.substring( 0, pName.length() - DELTA_DATE_RELATIVE.length() ).trim();
355 - pValue = makeDeltaDateRelative( pValue );
356 - }
357 - if ( pName.length() != 0 ) {
358 - String curValue = (pValue.length() == 0) ? mNameValues.get( pName ) : mNameValues.put( pName, pValue );
359 - if ( curValue != null ) {
360 - throw new IllegalArgumentException( "Duplicate Attribute for: " + pName );
361 - }
362 - }
363 - }
364 -
365 - private String makeTodayRelative( String pValue ) {
366 - boolean zAdd;
367 - switch ( (pValue = pValue + " ").charAt( 0 ) ) {
368 - case '+':
369 - zAdd = true;
370 - break;
371 - case '-':
372 - zAdd = false;
373 - break;
374 - default:
375 - throw new IllegalArgumentException( "Neither a '+' nor a '-' after '" + TODAY_RELATIVE + "='" );
376 - }
377 - String zYears, zMonths, zDays;
378 - String[] zParts = Strings.parseChar( pValue.substring( 1 ).trim(), '/' );
379 - switch ( zParts.length ) {
380 - case 3:
381 - zYears = zParts[0];
382 - zMonths = zParts[1];
383 - zDays = zParts[2];
384 - break;
385 - case 2:
386 - zYears = "";
387 - zMonths = zParts[0];
388 - zDays = zParts[1];
389 - break;
390 - case 1:
391 - zYears = zMonths = "";
392 - zDays = zParts[0];
393 - break;
394 - default:
395 - throw new IllegalArgumentException( "Too many '/'s after '" + TODAY_RELATIVE + "='" );
396 - }
397 - int iYears = parseInt( "Year", zYears );
398 - int iMonths = parseInt( "Month", zMonths );
399 - int iDays = parseInt( "Day", zDays );
400 -
401 - CalendarYMD zDesiredDate = CalendarYMD.today();
402 -
403 - if ( zAdd ) {
404 - zDesiredDate = zDesiredDate.addYears( iYears );
405 - zDesiredDate = zDesiredDate.addMonths( iMonths );
406 - zDesiredDate = zDesiredDate.addDays( iDays );
407 - } else {
408 - zDesiredDate = zDesiredDate.minusYears( iYears );
409 - zDesiredDate = zDesiredDate.minusMonths( iMonths );
410 - zDesiredDate = zDesiredDate.minusDays( iDays );
411 - }
412 -
413 - return zDesiredDate.toSQLvalue();
414 - }
415 -
416 - private String makeDeltaDateRelative( String pValue ) {
417 - int zAt = pValue.indexOf( DELTA_DATE_SEP );
418 - if ( zAt == -1 ) {
419 - throw new IllegalArgumentException( "No Delta Date Sep '" + DELTA_DATE_SEP + "'" );
420 - }
421 - CalendarYMD zDesiredDate = to_CalendarYMD( "Desired Date", pValue.substring( 0, zAt ) );
422 - CalendarYMD zDeltaDate = to_CalendarYMD( "Delta Date", pValue.substring( zAt + DELTA_DATE_SEP.length() ) );
423 - CalendarYMD zToday = CalendarYMD.today();
424 - zDesiredDate = zDesiredDate.addDays( zDeltaDate.daysTill( zToday ) );
425 - return zDesiredDate.toString();
426 - }
427 -
428 - private CalendarYMD to_CalendarYMD( String pWhat, String pString ) {
429 - try {
430 - return TypeConverter.to_CalendarYMD( pString.trim() );
431 - }
432 - catch ( RuntimeException e ) {
433 - throw new IllegalArgumentException( pWhat + ":" + e.getMessage(), e );
434 - }
435 - }
436 -
437 - private int parseInt( String pWhat, String pString ) {
438 - if ( (pString = pString.trim()).length() == 0 ) {
439 - return 0;
440 - }
441 - try {
442 - return Integer.parseInt( pString );
443 - }
444 - catch ( NumberFormatException e ) {
445 - throw new IllegalArgumentException( pWhat + ":" + e.getMessage(), e );
446 - }
447 - }
448 - }
449 - }
1 + // This Source Code is in the Public Domain per: http://unlicense.org
2 + package org.litesoft.orsup;
3 +
4 + import org.litesoft.commonfoundation.base.*;
5 + import org.litesoft.commonfoundation.csv.*;
6 + import org.litesoft.commonfoundation.exceptions.*;
7 + import org.litesoft.commonfoundation.typeutils.*;
8 + import org.litesoft.core.simpletypes.temporal.*;
9 + import org.litesoft.core.util.*;
10 + import org.litesoft.logger.*;
11 + import org.litesoft.orsup.base.*;
12 + import org.litesoft.orsup.nonpublic.*;
13 + import org.litesoft.orsup.otherattributeaccessors.*;
14 + import org.litesoft.orsup.transact.*;
15 + import org.litesoft.util.*;
16 +
17 + import java.io.*;
18 + import java.lang.reflect.*;
19 + import java.util.*;
20 +
21 + public class DB_ImportSupport {
22 + public static final String TODAY_RELATIVE = ":T";
23 + public static final String DELTA_DATE_RELATIVE = ":DD";
24 + public static final String DELTA_DATE_SEP = "+T-";
25 + public static final String FILE_ATTRIBUTE = "@";
26 + public static final String SETTER_ATTRIBUTE = "()";
27 + public static final String PO_URL_ATTRIBUTE = ":";
28 +
29 + protected static class ImportFromMap {
30 + public void process( Logger pLogger, UnfilteringFinder pFinder, File pReferenceDir, Map<FauxPOref, Attributes> pLineMap )
31 + throws IOException {
32 + if ( pLineMap.isEmpty() ) {
33 + throw new IllegalArgumentException( "No Data Found" );
34 + }
35 + new Inner( pLogger, pFinder.createUnaugmentedTransaction(), pReferenceDir, pLineMap ).process().commit();
36 + }
37 +
38 + private class Inner {
39 + private Logger mLogger;
40 + private Transaction mTransaction;
41 + private File mReferenceDir;
42 + private Map<FauxPOref, Attributes> mLineMap;
43 + private Map<FauxPOref, PersistentObject<?>> mPOsByRef = new HashMap<FauxPOref, PersistentObject<?>>();
44 +
45 + private Inner( Logger pLogger, Transaction pTransaction, File pReferenceDir, Map<FauxPOref, Attributes> pLineMap ) {
46 + mLogger = pLogger;
47 + mTransaction = pTransaction;
48 + mReferenceDir = pReferenceDir;
49 + mLineMap = pLineMap;
50 + }
51 +
52 + public Transaction process() {
53 + for ( FauxPOref ref : mLineMap.keySet() ) {
54 + putLineInDB( ref );
55 + }
56 + return mTransaction;
57 + }
58 +
59 + private PersistentObject<?> putLineInDB( FauxPOref pPOref ) {
60 + PersistentObject<?> zPO = mPOsByRef.get( pPOref );
61 + if ( zPO == null ) // NOT Already created
62 + {
63 + mPOsByRef.put( pPOref, zPO = mTransaction.create( pPOref.getPersistedObjectRegistrationName() ) );
64 +
65 + Attributes attributes = mLineMap.get( pPOref );
66 + if ( attributes == null ) {
67 + throw new IllegalArgumentException( "No Attributes (Line) found for URL: " + pPOref );
68 + }
69 + mLogger.trace.log( "writing line to db for URL: ", pPOref );
70 +
71 + for ( String attrName : attributes.getNames() ) {
72 + String value = attributes.getValue( attrName );
73 +
74 + // If the attribute is calling a setter method ..
75 + if ( attrName.endsWith( SETTER_ATTRIBUTE ) ) {
76 + try {
77 + String methodName = attrName.substring( 0, attrName.length() - SETTER_ATTRIBUTE.length() );
78 + Method method = zPO.getClass().getMethod( methodName, String.class );
79 + if ( method != null ) {
80 + method.invoke( zPO, value );
81 + }
82 + }
83 + catch ( InvocationTargetException e ) {
84 + throw new RuntimeException( e );
85 + }
86 + catch ( NoSuchMethodException e ) {
87 + throw new RuntimeException( e );
88 + }
89 + catch ( IllegalAccessException e ) {
90 + throw new RuntimeException( e );
91 + }
92 + // Setter methods aren't actual attributes, so skip the rest of the iteration.
93 + continue;
94 + }
95 +
96 + boolean isURLAttribute = false;
97 + if ( attrName.endsWith( PO_URL_ATTRIBUTE ) ) {
98 + attrName = attrName.substring( 0, attrName.length() - PO_URL_ATTRIBUTE.length() );
99 + isURLAttribute = true;
100 + }
101 + if ( attrName.endsWith( FILE_ATTRIBUTE ) ) {
102 + attrName = attrName.substring( 0, attrName.length() - FILE_ATTRIBUTE.length() );
103 + value = readFileAttributeValue( value );
104 + }
105 +
106 + AttributeAccessorSCD scd = zPO.getMetaDataForPO().getAccessorSCDoptional( attrName );
107 + if ( scd == null ) {
108 + throw new IllegalArgumentException( zPO.getObjectName() + " does NOT appear to have an attribute named: '" + attrName + "'" );
109 + }
110 + if ( !(scd instanceof NonImportableFeature) ) {
111 + Object setValue = value;
112 + if ( AttributeAccessorSCD.Form.ToOne == scd.getForm() ) {
113 + if ( scd instanceof AttributeAccessorSCDtoOneVariable ) {
114 + PO_VarURLstringHelper zVarURL = new PO_VarURLstringHelper( value );
115 + FauxPOref childRef = new FauxPOref( mTransaction, zVarURL.getPersistentObjectURL() );
116 + PersistentObject<?> po = putLineInDB( childRef );
117 + setValue = new PO_VarURLstringHelper( zVarURL.getPersistedObjectAttributeName(), po.getPersistentObjectURL().toString() );
118 + } else {
119 + FauxPOref childRef = new FauxPOref( mTransaction, value );
120 + setValue = putLineInDB( childRef );
121 + }
122 + } else if ( looksLikeAReference( scd, value ) ) {
123 + // support quasi-foreign keys.
124 + FauxPOref childRef = new FauxPOref( mTransaction, value );
125 + setValue = putLineInDB( childRef );
126 + PersistentObject po = (PersistentObject) setValue;
127 + try {
128 + setValue = po.getPersistentObjectUniqueKey();
129 + }
130 + catch ( Exception e ) {
131 + e.printStackTrace();
132 + }
133 + } else if ( isURLAttribute ) {
134 + FauxPOref childRef = new FauxPOref( mTransaction, value );
135 + setValue = putLineInDB( childRef ).getPersistentObjectURL().toString();
136 + }
137 + zPO.setAttributeValue( attrName, setValue );
138 + }
139 + }
140 + }
141 + return zPO;
142 + }
143 +
144 + private boolean looksLikeAReference( AttributeAccessorSCD pScd, String pValue ) {
145 + if ( !(pScd.getColumnType().equals( Long.class )) ) {
146 + return false;
147 + }
148 + try {
149 + new FauxPOref( mTransaction, pValue );
150 + return true;
151 + }
152 + catch ( Exception e ) {
153 + return false;
154 + }
155 + }
156 +
157 + private String readFileAttributeValue( String fileReference ) {
158 + if ( fileReference.startsWith( "file:" ) ) {
159 + fileReference = fileReference.substring( "file:".length() );
160 + }
161 +
162 + File f;
163 + if ( null != mReferenceDir ) {
164 + f = new File( mReferenceDir, fileReference );
165 + } else {
166 + f = new File( fileReference );
167 + }
168 +
169 + return FileUtils.loadTextFileAsString( f, "\n" );
170 + }
171 + }
172 + }
173 +
174 + protected static class ImportToMap {
175 + private Map<FauxPOref, Attributes> mLineMap = new HashMap<FauxPOref, Attributes>();
176 +
177 + public ImportToMap process( Logger pLogger, Finder pFinder, Reader[] pReaders )
178 + throws IOException {
179 + if ( Currently.isNullOrEmpty( pReaders ) ) {
180 + throw new IllegalArgumentException( "No Readers provided" );
181 + }
182 + try {
183 + new Inner( pLogger, pFinder ).process( pReaders );
184 + }
185 + finally {
186 + for ( Reader reader : pReaders ) {
187 + try {
188 + reader.close();
189 + }
190 + catch ( IOException e ) {
191 + // Whatever!
192 + }
193 + }
194 + }
195 +
196 + return this;
197 + }
198 +
199 + public Map<FauxPOref, Attributes> getLineMap() {
200 + return mLineMap;
201 + }
202 +
203 + private class Inner {
204 + private Logger mLogger;
205 + private Finder mFinder;
206 + private StringBuilder mBuilder;
207 +
208 + private Inner( Logger pLogger, Finder pFinder ) {
209 + mLogger = pLogger;
210 + mFinder = pFinder;
211 + }
212 +
213 + public void process( Reader[] pReaders )
214 + throws IOException {
215 + if ( pReaders[0] instanceof ToStringInformative ) {
216 + mLogger.info.log( "Importing:" );
217 + }
218 + for ( Reader reader : pReaders ) {
219 + if ( reader instanceof ToStringInformative ) {
220 + mLogger.info.log( " ", reader );
221 + }
222 + BufferedReader bufRead = Utils.getBufferedReader( reader );
223 + mBuilder = new StringBuilder();
224 + for ( String line; null != (line = bufRead.readLine()); ) {
225 + putLineInMap( line );
226 + }
227 + if ( mBuilder.length() != 0 ) {
228 + throw new UnclosedQuoteException( " did not find end of line " + mBuilder );
229 + }
230 + }
231 + }
232 +
233 + private void putLineInMap( String pLine ) {
234 + if ( mBuilder.length() == 0 ) {
235 + pLine = pLine.trim();
236 + if ( (pLine.length() == 0) || (pLine.charAt( 0 ) == ';') || (pLine.charAt( 0 ) == '#') || pLine.startsWith( "//" ) ) {
237 + return;
238 + }
239 + }
240 + mBuilder.append( pLine );
241 + try {
242 + putBuilderInMap();
243 + mBuilder.setLength( 0 );
244 + }
245 + catch ( UnclosedQuoteException e ) {
246 + mBuilder.append( "\n" );
247 + }
248 + }
249 +
250 + private void putBuilderInMap() {
251 + String[] decodedData = new CsvSupport().decode( mBuilder.toString() );
252 + FauxPOref ref = new FauxPOref( mFinder, decodedData[0] );
253 + if ( mFinder.getMetaDataRequired( ref.getPersistedObjectRegistrationName() ).isImportable() ) {
254 + Attributes attributes = parseData( decodedData );
255 + if ( !attributes.isEmpty() ) {
256 + mLineMap.put( ref, attributes );
257 + }
258 + }
259 + }
260 +
261 + private Attributes parseData( String[] pDecodedData ) {
262 + Attributes zAttributes = new Attributes();
263 + for ( int i = 1; i < pDecodedData.length; ++i ) {
264 + String pair = ConstrainTo.significantOrNull( pDecodedData[i] );
265 + if ( pair != null ) {
266 + int equidx = pair.indexOf( '=' );
267 + if ( equidx == -1 ) {
268 + throw new IllegalStateException( "No '=' in: " + pair );
269 + }
270 + String attr = pair.substring( 0, equidx ).trim();
271 + String value = pair.substring( equidx + 1 ).trim();
272 + zAttributes.setNameValue( attr, value );
273 + }
274 + }
275 + return zAttributes;
276 + }
277 + }
278 + }
279 +
280 + protected static class FauxPOref {
281 + public static int sWildcardSequence = 0;
282 +
283 + private MetaDataForPO mPOmd;
284 + private String mIdentifier;
285 +
286 + public FauxPOref( Finder pFinder, String pToString ) {
287 + PO_URLstringHelper helper = new PO_URLstringHelper( pToString );
288 + String zIdentifierOrRegistrationName = helper.getPersistedObjectRegistrationName();
289 + MetaDataForPO zMD = pFinder.getMetaDataOptionallyByIdentifier( zIdentifierOrRegistrationName );
290 + mPOmd = (zMD != null) ? zMD : pFinder.getMetaDataRequired( zIdentifierOrRegistrationName );
291 + mIdentifier = helper.getPersistentObjectUniqueKey();
292 + if ( "?".equals( mIdentifier ) ) {
293 + mIdentifier = "gened-" + ++sWildcardSequence;
294 + }
295 + }
296 +
297 + public MetaDataForPO getPOmd() {
298 + return mPOmd;
299 + }
300 +
301 + public String getPersistedObjectRegistrationName() {
302 + return mPOmd.getPOregistrationName();
303 + }
304 +
305 + public String getIdentifier() {
306 + return mIdentifier;
307 + }
308 +
309 + @Override
310 + public boolean equals( Object o ) {
311 + return (this == o) || ((o instanceof FauxPOref) && equals( (FauxPOref) o ));
312 + }
313 +
314 + public boolean equals( FauxPOref them ) {
315 + return (this == them) || //
316 + ((them != null) //
317 + && (this.mPOmd == them.mPOmd) //
318 + && this.mIdentifier.equals( them.mIdentifier ) //
319 + );
320 + }
321 +
322 + @Override
323 + public int hashCode() {
324 + return 31 * getPersistedObjectRegistrationName().hashCode() + mIdentifier.hashCode();
325 + }
326 +
327 + @Override
328 + public String toString() {
329 + return new PO_URLstringHelper( getPersistedObjectRegistrationName(), mIdentifier ).toString();
330 + }
331 + }
332 +
333 + protected static class Attributes {
334 + private Map<String, String> mNameValues = new HashMap<String, String>();
335 +
336 + public boolean isEmpty() {
337 + return mNameValues.isEmpty();
338 + }
339 +
340 + public String[] getNames() {
341 + return mNameValues.keySet().toArray( new String[mNameValues.size()] );
342 + }
343 +
344 + public String getValue( String pName ) {
345 + return mNameValues.get( pName );
346 + }
347 +
348 + public void setNameValue( String pName, String pValue ) {
349 + if ( pName.endsWith( TODAY_RELATIVE ) ) {
350 + pName = pName.substring( 0, pName.length() - TODAY_RELATIVE.length() ).trim();
351 + pValue = makeTodayRelative( pValue );
352 + } else if ( pName.endsWith( DELTA_DATE_RELATIVE ) ) {
353 + pName = pName.substring( 0, pName.length() - DELTA_DATE_RELATIVE.length() ).trim();
354 + pValue = makeDeltaDateRelative( pValue );
355 + }
356 + if ( pName.length() != 0 ) {
357 + String curValue = (pValue.length() == 0) ? mNameValues.get( pName ) : mNameValues.put( pName, pValue );
358 + if ( curValue != null ) {
359 + throw new IllegalArgumentException( "Duplicate Attribute for: " + pName );
360 + }
361 + }
362 + }
363 +
364 + private String makeTodayRelative( String pValue ) {
365 + boolean zAdd;
366 + switch ( (pValue = pValue + " ").charAt( 0 ) ) {
367 + case '+':
368 + zAdd = true;
369 + break;
370 + case '-':
371 + zAdd = false;
372 + break;
373 + default:
374 + throw new IllegalArgumentException( "Neither a '+' nor a '-' after '" + TODAY_RELATIVE + "='" );
375 + }
376 + String zYears, zMonths, zDays;
377 + String[] zParts = Strings.parseChar( pValue.substring( 1 ).trim(), '/' );
378 + switch ( zParts.length ) {
379 + case 3:
380 + zYears = zParts[0];
381 + zMonths = zParts[1];
382 + zDays = zParts[2];
383 + break;
384 + case 2:
385 + zYears = "";
386 + zMonths = zParts[0];
387 + zDays = zParts[1];
388 + break;
389 + case 1:
390 + zYears = zMonths = "";
391 + zDays = zParts[0];
392 + break;
393 + default:
394 + throw new IllegalArgumentException( "Too many '/'s after '" + TODAY_RELATIVE + "='" );
395 + }
396 + int iYears = parseInt( "Year", zYears );
397 + int iMonths = parseInt( "Month", zMonths );
398 + int iDays = parseInt( "Day", zDays );
399 +
400 + CalendarYMD zDesiredDate = CalendarYMD.today();
401 +
402 + if ( zAdd ) {
403 + zDesiredDate = zDesiredDate.addYears( iYears );
404 + zDesiredDate = zDesiredDate.addMonths( iMonths );
405 + zDesiredDate = zDesiredDate.addDays( iDays );
406 + } else {
407 + zDesiredDate = zDesiredDate.minusYears( iYears );
408 + zDesiredDate = zDesiredDate.minusMonths( iMonths );
409 + zDesiredDate = zDesiredDate.minusDays( iDays );
410 + }
411 +
412 + return zDesiredDate.toSQLvalue();
413 + }
414 +
415 + private String makeDeltaDateRelative( String pValue ) {
416 + int zAt = pValue.indexOf( DELTA_DATE_SEP );
417 + if ( zAt == -1 ) {
418 + throw new IllegalArgumentException( "No Delta Date Sep '" + DELTA_DATE_SEP + "'" );
419 + }
420 + CalendarYMD zDesiredDate = to_CalendarYMD( "Desired Date", pValue.substring( 0, zAt ) );
421 + CalendarYMD zDeltaDate = to_CalendarYMD( "Delta Date", pValue.substring( zAt + DELTA_DATE_SEP.length() ) );
422 + CalendarYMD zToday = CalendarYMD.today();
423 + zDesiredDate = zDesiredDate.addDays( zDeltaDate.daysTill( zToday ) );
424 + return zDesiredDate.toString();
425 + }
426 +
427 + private CalendarYMD to_CalendarYMD( String pWhat, String pString ) {
428 + try {
429 + return TypeConverter.to_CalendarYMD( pString.trim() );
430 + }
431 + catch ( RuntimeException e ) {
432 + throw new IllegalArgumentException( pWhat + ":" + e.getMessage(), e );
433 + }
434 + }
435 +
436 + private int parseInt( String pWhat, String pString ) {
437 + if ( (pString = pString.trim()).length() == 0 ) {
438 + return 0;
439 + }
440 + try {
441 + return Integer.parseInt( pString );
442 + }
443 + catch ( NumberFormatException e ) {
444 + throw new IllegalArgumentException( pWhat + ":" + e.getMessage(), e );
445 + }
446 + }
447 + }
448 + }