Subversion Repository Public Repository

litesoft

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

Diff revisions: vs.
  @@ -1,440 +1,537 @@
1 - // This Source Code is in the Public Domain per: http://unlicense.org
2 - package org.litesoft.util;
3 -
4 - import org.litesoft.commonfoundation.base.*;
5 - import org.litesoft.commonfoundation.exceptions.*;
6 - import org.litesoft.commonfoundation.stringmatching.*;
7 - import org.litesoft.commonfoundation.typeutils.Objects;
8 - import org.litesoft.commonfoundation.typeutils.*;
9 -
10 - import java.io.*;
11 - import java.util.*;
12 -
13 - public class FileUtils extends FileUtil {
14 - public static Reader[] filesToReaders( File pDir, String... pFileNames )
15 - throws FileNotFoundException {
16 - if ( Objects.isNullOrEmpty( pFileNames ) ) {
17 - throw new IllegalArgumentException( "No Files provided" );
18 - }
19 - Reader[] readers = new Reader[pFileNames.length];
20 - for ( int i = 0; i < pFileNames.length; i++ ) {
21 - File file = new File( pDir, pFileNames[i] );
22 - readers[i] = new InformativeFileReader( file );
23 - }
24 - return readers;
25 - }
26 -
27 - private static class InformativeFileReader extends FileReader implements ToStringInformative {
28 - private File mFile;
29 -
30 - private InformativeFileReader( File pFile )
31 - throws FileNotFoundException {
32 - super( pFile );
33 - mFile = pFile;
34 - }
35 -
36 - @Override
37 - public String toString() {
38 - return mFile.getAbsolutePath();
39 - }
40 - }
41 -
42 - public static void deleteIfExists( File pFile )
43 - throws FileSystemException {
44 - Objects.assertNotNull( "File", pFile );
45 - if ( pFile.isFile() ) {
46 - if ( !pFile.delete() || pFile.exists() ) {
47 - throw new FileSystemException( "Unable to delete: " + pFile.getAbsolutePath() );
48 - }
49 - }
50 - }
51 -
52 - public static FilenameFilter createFileNameFilter( String... pParts ) {
53 - StringMatcher zSM = StringMatcherFactory.createStartsWith( pParts );
54 - if ( zSM == null ) {
55 - throw new IllegalArgumentException( "Must Provide something to Filter on!" );
56 - }
57 - return new StringMatcherFilenameFilter( zSM );
58 - }
59 -
60 - @SuppressWarnings({"UnusedDeclaration"})
61 - public static String locateFile( String pFile )
62 - throws FileSystemException {
63 - try {
64 - File file = new File( pFile );
65 - while ( !file.isFile() ) {
66 - File parent = file.getParentFile();
67 - if ( parent != null ) {
68 - File grandparent = parent.getParentFile();
69 - if ( grandparent != null ) {
70 - file = new File( grandparent, pFile );
71 - continue;
72 - }
73 - }
74 - throw new FileNotFoundException( pFile );
75 - }
76 - return file.getAbsolutePath();
77 - }
78 - catch ( IOException e ) {
79 - throw new FileSystemException( e );
80 - }
81 - }
82 -
83 - public static byte[] load( File pFile, int pMaxAllowedSize )
84 - throws FileSystemException {
85 - Objects.assertNotNull( "File", pFile );
86 - try {
87 - if ( !pFile.exists() ) {
88 - throw new FileNotFoundException( pFile.getAbsolutePath() );
89 - }
90 - long fSize = pFile.length();
91 - if ( fSize > pMaxAllowedSize ) {
92 - throw new FileSystemException( "File (" + pFile + ") Too large (" + fSize + "), but max set to: " + pMaxAllowedSize );
93 - }
94 - int fileSize = (int) fSize;
95 - byte[] b = new byte[fileSize];
96 - InputStream is = new FileInputStream( pFile );
97 - boolean closed = false;
98 - try {
99 - int offset = 0;
100 - while ( offset < fileSize ) {
101 - int i = is.read( b, offset, fileSize - offset );
102 - if ( i < 1 ) {
103 - throw new FileSystemException( "Unable to read the entire file (" + pFile + "). Expected " + fileSize + ", but only got: " + offset );
104 - }
105 - offset += i;
106 - }
107 - if ( -1 != is.read() ) {
108 - throw new FileSystemException( "Read beyond file (" + pFile + ") size (" + fileSize + ")!" );
109 - }
110 - closed = true;
111 - is.close();
112 - }
113 - finally {
114 - if ( !closed ) {
115 - Utils.dispose( is );
116 - }
117 - }
118 - return b;
119 - }
120 - catch ( IOException e ) {
121 - throw new FileSystemException( e );
122 - }
123 - }
124 -
125 - public static void appendTextFile( File pFile, String... pLines )
126 - throws FileSystemException {
127 - Objects.assertNotNull( "File", pFile );
128 - File file = new File( pFile.getAbsolutePath() );
129 - addLines( file, true, pLines );
130 - }
131 -
132 - public static void store( File pFile, byte[] pBytes )
133 - throws FileSystemException {
134 - Objects.assertNotNull( "File", pFile );
135 - File file = Directories.insureParent( new File( pFile.getAbsolutePath() + ".new" ) );
136 - try {
137 - OutputStream os = new FileOutputStream( file );
138 - boolean closed = false;
139 - try {
140 - if ( (pBytes != null) && (pBytes.length != 0) ) {
141 - os.write( pBytes );
142 - }
143 - closed = true;
144 - os.close();
145 - }
146 - finally {
147 - if ( !closed ) {
148 - Utils.dispose( os );
149 - }
150 - }
151 - }
152 - catch ( IOException e ) {
153 - throw new FileSystemException( e );
154 - }
155 - rollIn( file, pFile, new File( pFile.getAbsolutePath() + ".bak" ) );
156 - }
157 -
158 - public static void storeTextFile( File pFile, String... pLines )
159 - throws FileSystemException {
160 - Objects.assertNotNull( "File", pFile );
161 - File file = new File( pFile.getAbsolutePath() + ".new" );
162 - addLines( file, false, pLines );
163 - rollIn( file, pFile, new File( pFile.getAbsolutePath() + ".bak" ) );
164 - }
165 -
166 - private static void addLines( File pFile, boolean pAppend, String... pLines )
167 - throws FileSystemException {
168 - try {
169 - addLines( createWriter( pFile, pAppend ), pLines );
170 - }
171 - catch ( IOException e ) {
172 - throw new FileSystemException( e );
173 - }
174 - }
175 -
176 - private static void addLines( BufferedWriter pWriter, String... pLines )
177 - throws IOException {
178 - boolean closed = false;
179 - try {
180 - for ( String line : Strings.deNull( pLines ) ) {
181 - if ( line != null ) {
182 - pWriter.write( line );
183 - pWriter.write( '\n' );
184 - }
185 - }
186 - closed = true;
187 - pWriter.close();
188 - }
189 - finally {
190 - if ( !closed ) {
191 - Utils.dispose( pWriter );
192 - }
193 - }
194 - }
195 -
196 - public static String[] loadTextFile( File pFile )
197 - throws FileSystemException {
198 - Objects.assertNotNull( "File", pFile );
199 - try {
200 - if ( !pFile.exists() ) {
201 - throw new FileNotFoundException( pFile.getAbsolutePath() );
202 - }
203 - List<String> lines = new LinkedList<String>();
204 - BufferedReader reader = createReader( pFile );
205 - boolean closed = false;
206 - try {
207 - for ( String line; null != (line = reader.readLine()); ) {
208 - lines.add( line );
209 - }
210 - closed = true;
211 - reader.close();
212 - }
213 - finally {
214 - if ( !closed ) {
215 - Utils.dispose( reader );
216 - }
217 - }
218 - return lines.toArray( new String[lines.size()] );
219 - }
220 - catch ( IOException e ) {
221 - throw new FileSystemException( e );
222 - }
223 - }
224 -
225 - @SuppressWarnings({"UnusedDeclaration"})
226 - public static String loadTextFileAsString( File pFile )
227 - throws FileSystemException {
228 - return loadTextFileAsString( pFile, null );
229 - }
230 -
231 - public static String loadTextFileAsString( File pFile, String pLineSeparator )
232 - throws FileSystemException {
233 - Objects.assertNotNull( "File", pFile );
234 - pLineSeparator = Strings.deNull( pLineSeparator, "\n" );
235 - try {
236 - if ( !pFile.exists() ) {
237 - throw new FileNotFoundException( pFile.getAbsolutePath() );
238 - }
239 -
240 - StringBuilder buffer = new StringBuilder();
241 - BufferedReader reader = createReader( pFile );
242 - boolean closed = false;
243 - try {
244 - int count = 0;
245 - for ( String line; null != (line = reader.readLine()); count++ ) {
246 - if ( count > 0 ) {
247 - buffer.append( pLineSeparator );
248 - }
249 - buffer.append( line );
250 - }
251 - closed = true;
252 - reader.close();
253 - }
254 - finally {
255 - if ( !closed ) {
256 - Utils.dispose( reader );
257 - }
258 - }
259 -
260 - return buffer.toString();
261 - }
262 - catch ( IOException e ) {
263 - throw new FileSystemException( e );
264 - }
265 - }
266 -
267 - public static void rollIn( File pNewFile, File pTargetFile, File pBackupFile )
268 - throws FileSystemException {
269 - Objects.assertNotNull( "NewFile", pNewFile );
270 - Objects.assertNotNull( "TargetFile", pTargetFile );
271 - Objects.assertNotNull( "BackupFile", pBackupFile );
272 - if ( !pNewFile.exists() ) {
273 - throw new FileSystemException( "Does not Exist: " + pNewFile.getPath() );
274 - }
275 - boolean targetExisted = false;
276 - if ( pTargetFile.exists() ) {
277 - targetExisted = true;
278 - deleteIfExists( pBackupFile );
279 - renameFromTo( pTargetFile, pBackupFile );
280 - }
281 - try {
282 - renameFromTo( pNewFile, pTargetFile );
283 - }
284 - catch ( FileSystemException e ) {
285 - if ( targetExisted ) {
286 - attemptToRollBack( pNewFile, pTargetFile, pBackupFile );
287 - }
288 - throw e;
289 - }
290 - }
291 -
292 - @SuppressWarnings({"ResultOfMethodCallIgnored"})
293 - private static void attemptToRollBack( File pNewFile, File pTargetFile, File pBackupFile ) {
294 - switch ( (pNewFile.exists() ? 0 : 4) + (pTargetFile.exists() ? 0 : 2) + (pBackupFile.exists() ? 0 : 1) ) {
295 - // What Happen'd
296 - case 0: // There: ------------- Nobody --------------
297 - case 2: // There: pTargetFile
298 - case 4: // There: pNewFile
299 - case 6: // There: pNewFile & pTargetFile
300 - case 7: // There: pNewFile & pTargetFile & pBackupFile
301 - return;
302 - case 3: // There: pTargetFile & pBackupFile
303 - pTargetFile.renameTo( pNewFile );
304 - // Fall Thru
305 - case 1: // There: pBackupFile
306 - case 5: // There: pNewFile & pBackupFile
307 - pBackupFile.renameTo( pTargetFile );
308 - break;
309 - }
310 - }
311 -
312 - /**
313 - * This method will rename the pSourceFile to the pDestinationFile name.
314 - * <p/>
315 - * It is Inherently fragile when dealing with multiple processes playing
316 - * in the same file system name spaces. It should therefore NOT be used
317 - * in a multi-process creation-consumption shared file system name space.
318 - * <p/>
319 - * Specifically there are two windows of opportunities for multiple processes
320 - * to mess with the "as linear" assumptions
321 - */
322 - private static void renameFromTo( File pSourceFile, File pDestinationFile )
323 - throws FileSystemException {
324 - Objects.assertNotNull( "SourceFile", pSourceFile );
325 - Objects.assertNotNull( "DestinationFile", pDestinationFile );
326 - // Win 1 Start
327 - if ( !pSourceFile.exists() ) {
328 - throw new FileSystemException( "SourceFile does not exist: " + pSourceFile.getAbsolutePath() );
329 - }
330 - if ( pDestinationFile.exists() ) {
331 - throw new FileSystemException( "DestinationFile already exists: " + pDestinationFile.getAbsolutePath() );
332 - }
333 - // Win 2 Start
334 - if ( !pSourceFile.renameTo( pDestinationFile ) ) // Win 1 End
335 - {
336 - throw renameFailed( pSourceFile, pDestinationFile, "Failed" );
337 - }
338 - boolean sThere = pSourceFile.exists();
339 - boolean dThere = pDestinationFile.exists();
340 - // Win 2 End
341 - if ( sThere ) {
342 - throw renameFailed( pSourceFile, pDestinationFile, "claims Succeess, but Source still there" + (dThere ? " and so is the Destination!" : "!") );
343 - }
344 - if ( !dThere ) {
345 - throw renameFailed( pSourceFile, pDestinationFile, "claims Succeess, but the Destination is NOT there!" );
346 - }
347 - }
348 -
349 - private static FileSystemException renameFailed( File pSourceFile, File pDestinationFile, String pAdditionalExplanation ) {
350 - throw new FileSystemException(
351 - "Rename (" + pSourceFile.getAbsolutePath() + ") to (" + pDestinationFile.getAbsolutePath() + ") " + pAdditionalExplanation );
352 - }
353 -
354 - private static class StringMatcherFilenameFilter implements FilenameFilter {
355 - private StringMatcher mSM;
356 -
357 - public StringMatcherFilenameFilter( StringMatcher pSM ) {
358 - mSM = pSM;
359 - }
360 -
361 - @Override
362 - public boolean accept( File dir, String name ) {
363 - return mSM.matches( name );
364 - }
365 - }
366 -
367 - public static void main( String[] args )
368 - throws Exception {
369 - File zFile = new File( "PersistanceTier/design/NextGEN.xml" );
370 - String[] lines = loadTextFile( zFile );
371 - process( lines );
372 - storeTextFile( zFile, lines );
373 - }
374 -
375 - private static void process( String[] pLines ) {
376 - for ( int i = 0; i < pLines.length; i++ ) {
377 - String zLine = pLines[i];
378 - if ( zLine != null ) {
379 - if ( zLine.trim().startsWith( "<column " ) ) {
380 - processColumn( pLines, i, findEONode( pLines, i ) );
381 - } else if ( zLine.trim().startsWith( "<foreignKey " ) ) {
382 - processForeignKey( pLines, i, findEONode( pLines, i ) );
383 - }
384 - }
385 - }
386 - }
387 -
388 - private static int findEONode( String[] pLines, int pFromIndex ) {
389 - int zThruIndex = pFromIndex;
390 - while ( zThruIndex < pLines.length ) {
391 - String zLine = pLines[zThruIndex];
392 - if ( (zLine != null) && zLine.trim().endsWith( ">" ) ) {
393 - break;
394 - }
395 - zThruIndex++;
396 - }
397 - return zThruIndex;
398 - }
399 -
400 - private static boolean isAttributeOneOf( String pLine, String... pOneOf ) {
401 - for ( String s : pOneOf ) {
402 - if ( pLine.startsWith( s + "=" ) ) {
403 - return true;
404 - }
405 - }
406 - return false;
407 - }
408 -
409 - private static void processColumn( String[] pLines, int pBegLine, int pEndLine ) {
410 - for ( int i = pBegLine + 1; i < pEndLine; i++ ) {
411 - String zLine = pLines[i];
412 - if ( zLine != null ) {
413 - zLine = zLine.trim();
414 - if ( zLine.equals( "type=\"foreignKey\"" ) ) // No More Columns as ForeignKeys
415 - {
416 - for ( int j = pBegLine; j <= pEndLine; j++ ) {
417 - pLines[j] = null;
418 - }
419 - return;
420 - }
421 - if ( isAttributeOneOf( zLine, "fkonly", "isContainer", "IsContainer", "ReferenceSortColumn", "ThemDependsOnUs", "UsDependsOnThem", "table",
422 - "updateReferencedPO" ) ) {
423 - pLines[i] = null;
424 - }
425 - }
426 - }
427 - }
428 -
429 - private static void processForeignKey( String[] pLines, int pBegLine, int pEndLine ) {
430 - for ( int i = pBegLine + 1; i < pEndLine; i++ ) {
431 - String zLine = pLines[i];
432 - if ( zLine != null ) {
433 - zLine = zLine.trim();
434 - if ( isAttributeOneOf( zLine, "fkonly", "isContainer", "IsContainer", "defaultValue", "enumeration", "len" ) ) {
435 - pLines[i] = null;
436 - }
437 - }
438 - }
439 - }
440 - }
1 + // This Source Code is in the Public Domain per: http://unlicense.org
2 + package org.litesoft.util;
3 +
4 + import org.litesoft.commonfoundation.base.*;
5 + import org.litesoft.commonfoundation.exceptions.*;
6 + import org.litesoft.commonfoundation.stringmatching.*;
7 +
8 + import java.io.*;
9 + import java.util.*;
10 +
11 + public class FileUtils extends FileUtil {
12 + public enum Change {New, Updated}
13 +
14 + public static OutputStream createOutputStream( File pFile )
15 + throws IOException {
16 + Confirm.isNotNull( "File", pFile );
17 + return new FileOutputStream( pFile );
18 + }
19 +
20 + public static InputStream createInputStream( File pFile )
21 + throws IOException {
22 + Confirm.isNotNull( "File", pFile );
23 + return new FileInputStream( pFile );
24 + }
25 +
26 + public static Reader[] filesToReaders( File pDir, String... pFileNames )
27 + throws FileNotFoundException {
28 + if ( Currently.isNullOrEmpty( pFileNames ) ) {
29 + throw new IllegalArgumentException( "No Files provided" );
30 + }
31 + Reader[] readers = new Reader[pFileNames.length];
32 + for ( int i = 0; i < pFileNames.length; i++ ) {
33 + File file = new File( pDir, pFileNames[i] );
34 + readers[i] = new InformativeFileReader( file );
35 + }
36 + return readers;
37 + }
38 +
39 + private static class InformativeFileReader extends FileReader implements ToStringInformative {
40 + private File mFile;
41 +
42 + private InformativeFileReader( File pFile )
43 + throws FileNotFoundException {
44 + super( pFile );
45 + mFile = pFile;
46 + }
47 +
48 + @Override
49 + public String toString() {
50 + return mFile.getAbsolutePath();
51 + }
52 + }
53 +
54 + public static void deleteIfExists( File pFile )
55 + throws FileSystemException {
56 + Confirm.isNotNull( "File", pFile );
57 + if ( pFile.isFile() ) {
58 + if ( !pFile.delete() || pFile.exists() ) {
59 + throw new FileSystemException( "Unable to delete: " + pFile.getAbsolutePath() );
60 + }
61 + }
62 + }
63 +
64 + public static FilenameFilter createFileNameFilter( String... pParts ) {
65 + StringMatcher zSM = StringMatcherFactory.createStartsWith( pParts );
66 + if ( zSM == null ) {
67 + throw new IllegalArgumentException( "Must Provide something to Filter on!" );
68 + }
69 + return new StringMatcherFilenameFilter( zSM );
70 + }
71 +
72 + @SuppressWarnings({"UnusedDeclaration"})
73 + public static String locateFile( String pFile )
74 + throws FileSystemException {
75 + try {
76 + File file = new File( pFile );
77 + while ( !file.isFile() ) {
78 + File parent = file.getParentFile();
79 + if ( parent != null ) {
80 + File grandparent = parent.getParentFile();
81 + if ( grandparent != null ) {
82 + file = new File( grandparent, pFile );
83 + continue;
84 + }
85 + }
86 + throw new FileNotFoundException( pFile );
87 + }
88 + return file.getAbsolutePath();
89 + }
90 + catch ( IOException e ) {
91 + throw new FileSystemException( e );
92 + }
93 + }
94 +
95 + public static byte[] load( File pFile, int pMaxAllowedSize )
96 + throws FileSystemException {
97 + Confirm.isNotNull( "File", pFile );
98 + try {
99 + if ( !pFile.exists() ) {
100 + throw new FileNotFoundException( pFile.getAbsolutePath() );
101 + }
102 + long fSize = pFile.length();
103 + if ( fSize > pMaxAllowedSize ) {
104 + throw new FileSystemException( "File (" + pFile + ") Too large (" + fSize + "), but max set to: " + pMaxAllowedSize );
105 + }
106 + int fileSize = (int) fSize;
107 + byte[] b = new byte[fileSize];
108 + InputStream is = new FileInputStream( pFile );
109 + boolean closed = false;
110 + try {
111 + int offset = 0;
112 + while ( offset < fileSize ) {
113 + int i = is.read( b, offset, fileSize - offset );
114 + if ( i < 1 ) {
115 + throw new FileSystemException( "Unable to read the entire file (" + pFile + "). Expected " + fileSize + ", but only got: " + offset );
116 + }
117 + offset += i;
118 + }
119 + if ( -1 != is.read() ) {
120 + throw new FileSystemException( "Read beyond file (" + pFile + ") size (" + fileSize + ")!" );
121 + }
122 + closed = true;
123 + is.close();
124 + }
125 + finally {
126 + if ( !closed ) {
127 + Utils.dispose( is );
128 + }
129 + }
130 + return b;
131 + }
132 + catch ( IOException e ) {
133 + throw new FileSystemException( e );
134 + }
135 + }
136 +
137 + public static void appendTextFile( File pFile, String... pLines )
138 + throws FileSystemException {
139 + Confirm.isNotNull( "File", pFile );
140 + File file = new File( pFile.getAbsolutePath() );
141 + addLines( file, true, pLines );
142 + }
143 +
144 + public static void store( File pFile, byte[] pBytes )
145 + throws FileSystemException {
146 + Confirm.isNotNull( "File", pFile );
147 + File file = Directories.insureParent( new File( pFile.getAbsolutePath() + ".new" ) );
148 + try {
149 + OutputStream os = new FileOutputStream( file );
150 + boolean closed = false;
151 + try {
152 + if ( (pBytes != null) && (pBytes.length != 0) ) {
153 + os.write( pBytes );
154 + }
155 + closed = true;
156 + os.close();
157 + }
158 + finally {
159 + if ( !closed ) {
160 + Utils.dispose( os );
161 + }
162 + }
163 + }
164 + catch ( IOException e ) {
165 + throw new FileSystemException( e );
166 + }
167 + rollIn( file, pFile, new File( pFile.getAbsolutePath() + ".bak" ) );
168 + }
169 +
170 + public static void storeTextFile( File pFile, String... pLines )
171 + throws FileSystemException {
172 + Confirm.isNotNull( "File", pFile );
173 + File file = new File( pFile.getAbsolutePath() + ".new" );
174 + addLines( file, false, pLines );
175 + rollIn( file, pFile, new File( pFile.getAbsolutePath() + ".bak" ) );
176 + }
177 +
178 + private static void addLines( File pFile, boolean pAppend, String... pLines )
179 + throws FileSystemException {
180 + try {
181 + addLines( createWriter( pFile, pAppend ), pLines );
182 + }
183 + catch ( IOException e ) {
184 + throw new FileSystemException( e );
185 + }
186 + }
187 +
188 + private static void addLines( BufferedWriter pWriter, String... pLines )
189 + throws IOException {
190 + boolean closed = false;
191 + try {
192 + for ( String line : ConstrainTo.notNullImmutableList( pLines ) ) {
193 + if ( line != null ) {
194 + pWriter.write( line );
195 + pWriter.write( '\n' );
196 + }
197 + }
198 + closed = true;
199 + pWriter.close();
200 + }
201 + finally {
202 + if ( !closed ) {
203 + Utils.dispose( pWriter );
204 + }
205 + }
206 + }
207 +
208 + public static String[] loadTextFile( File pFile )
209 + throws FileSystemException {
210 + Confirm.isNotNull( "File", pFile );
211 + try {
212 + if ( !pFile.exists() ) {
213 + throw new FileNotFoundException( pFile.getAbsolutePath() );
214 + }
215 + List<String> lines = new LinkedList<String>();
216 + BufferedReader reader = createReader( pFile );
217 + boolean closed = false;
218 + try {
219 + for ( String line; null != (line = reader.readLine()); ) {
220 + lines.add( line );
221 + }
222 + closed = true;
223 + reader.close();
224 + }
225 + finally {
226 + if ( !closed ) {
227 + Utils.dispose( reader );
228 + }
229 + }
230 + return lines.toArray( new String[lines.size()] );
231 + }
232 + catch ( IOException e ) {
233 + throw new FileSystemException( e );
234 + }
235 + }
236 +
237 + @SuppressWarnings({"UnusedDeclaration"})
238 + public static String loadTextFileAsString( File pFile )
239 + throws FileSystemException {
240 + return loadTextFileAsString( pFile, null );
241 + }
242 +
243 + public static String loadTextFileAsString( File pFile, String pLineTerminator )
244 + throws FileSystemException {
245 + Confirm.isNotNull( "File", pFile );
246 + pLineTerminator = ConstrainTo.notNull( pLineTerminator, "\n" );
247 + try {
248 + if ( !pFile.exists() ) {
249 + throw new FileNotFoundException( pFile.getAbsolutePath() );
250 + }
251 +
252 + StringBuilder buffer = new StringBuilder();
253 + BufferedReader reader = createReader( pFile );
254 + boolean closed = false;
255 + try {
256 + for ( String line; null != (line = reader.readLine()); ) {
257 + buffer.append( line ).append( pLineTerminator );
258 + }
259 + closed = true;
260 + reader.close();
261 + }
262 + finally {
263 + if ( !closed ) {
264 + Utils.dispose( reader );
265 + }
266 + }
267 +
268 + return buffer.toString();
269 + }
270 + catch ( IOException e ) {
271 + throw new FileSystemException( e );
272 + }
273 + }
274 +
275 + /**
276 + * @return Null if already exists and Not changed, otherwise either New of Updated!
277 + */
278 + public static Change storeFile( File pFile, List<byte[]> pContents )
279 + throws FileSystemException {
280 + if ( pFile.exists() && areEqual( loadFile( pFile ), pContents ) ) {
281 + return null;
282 + }
283 + File file = new File( pFile.getAbsolutePath() + ".new" );
284 + try {
285 + IOUtils.storeBytes( pContents, createOutputStream( file ) );
286 + }
287 + catch ( IOException e ) {
288 + throw new FileSystemException( "Unable to create OutputStream: " + file.getAbsolutePath() );
289 + }
290 + return rollIn( file, pFile, new File( pFile.getAbsolutePath() + ".bak" ) ) ? Change.Updated : Change.New;
291 + }
292 +
293 + public static List<byte[]> loadFile( File pFile )
294 + throws FileSystemException {
295 + Confirm.isNotNull( "File", pFile );
296 + try {
297 + if ( !pFile.exists() ) {
298 + throw new FileNotFoundException( pFile.getAbsolutePath() );
299 + }
300 + return IOUtils.loadBytes( createInputStream( pFile ) );
301 + }
302 + catch ( IOException e ) {
303 + throw new FileSystemException( e );
304 + }
305 + }
306 +
307 + /**
308 + * Roll in an Update.
309 + *
310 + * @return true if replaced an existing!
311 + */
312 + public static boolean rollIn( File pNewFile, File pTargetFile, File pBackupFile )
313 + throws FileSystemException {
314 + Confirm.isNotNull( "NewFile", pNewFile );
315 + Confirm.isNotNull( "TargetFile", pTargetFile );
316 + Confirm.isNotNull( "BackupFile", pBackupFile );
317 + if ( !pNewFile.exists() ) {
318 + throw new FileSystemException( "Does not Exist: " + pNewFile.getPath() );
319 + }
320 + boolean targetExisted = false;
321 + if ( pTargetFile.exists() ) {
322 + targetExisted = true;
323 + deleteIfExists( pBackupFile );
324 + renameFromTo( pTargetFile, pBackupFile );
325 + }
326 + try {
327 + renameFromTo( pNewFile, pTargetFile );
328 + return targetExisted;
329 + }
330 + catch ( FileSystemException e ) {
331 + if ( targetExisted ) {
332 + attemptToRollBack( pNewFile, pTargetFile, pBackupFile );
333 + }
334 + throw e;
335 + }
336 + }
337 +
338 + @SuppressWarnings({"ResultOfMethodCallIgnored"})
339 + private static void attemptToRollBack( File pNewFile, File pTargetFile, File pBackupFile ) {
340 + switch ( (pNewFile.exists() ? 0 : 4) + (pTargetFile.exists() ? 0 : 2) + (pBackupFile.exists() ? 0 : 1) ) {
341 + // What Happen'd
342 + case 0: // There: ------------- Nobody --------------
343 + case 2: // There: pTargetFile
344 + case 4: // There: pNewFile
345 + case 6: // There: pNewFile & pTargetFile
346 + case 7: // There: pNewFile & pTargetFile & pBackupFile
347 + return;
348 + case 3: // There: pTargetFile & pBackupFile
349 + pTargetFile.renameTo( pNewFile );
350 + // Fall Thru
351 + case 1: // There: pBackupFile
352 + case 5: // There: pNewFile & pBackupFile
353 + pBackupFile.renameTo( pTargetFile );
354 + break;
355 + }
356 + }
357 +
358 + /**
359 + * This method will rename the pSourceFile to the pDestinationFile name.
360 + * <p/>
361 + * It is Inherently fragile when dealing with multiple processes playing
362 + * in the same file system name spaces. It should therefore NOT be used
363 + * in a multi-process creation-consumption shared file system name space.
364 + * <p/>
365 + * Specifically there are two windows of opportunities for multiple processes
366 + * to mess with the "as linear" assumptions
367 + */
368 + private static void renameFromTo( File pSourceFile, File pDestinationFile )
369 + throws FileSystemException {
370 + Confirm.isNotNull( "SourceFile", pSourceFile );
371 + Confirm.isNotNull( "DestinationFile", pDestinationFile );
372 + // Win 1 Start
373 + if ( !pSourceFile.exists() ) {
374 + throw new FileSystemException( "SourceFile does not exist: " + pSourceFile.getAbsolutePath() );
375 + }
376 + if ( pDestinationFile.exists() ) {
377 + throw new FileSystemException( "DestinationFile already exists: " + pDestinationFile.getAbsolutePath() );
378 + }
379 + // Win 2 Start
380 + if ( !pSourceFile.renameTo( pDestinationFile ) ) // Win 1 End
381 + {
382 + throw renameFailed( pSourceFile, pDestinationFile, "Failed" );
383 + }
384 + boolean sThere = pSourceFile.exists();
385 + boolean dThere = pDestinationFile.exists();
386 + // Win 2 End
387 + if ( sThere ) {
388 + throw renameFailed( pSourceFile, pDestinationFile, "claims Succeess, but Source still there" + (dThere ? " and so is the Destination!" : "!") );
389 + }
390 + if ( !dThere ) {
391 + throw renameFailed( pSourceFile, pDestinationFile, "claims Succeess, but the Destination is NOT there!" );
392 + }
393 + }
394 +
395 + private static FileSystemException renameFailed( File pSourceFile, File pDestinationFile, String pAdditionalExplanation ) {
396 + throw new FileSystemException(
397 + "Rename (" + pSourceFile.getAbsolutePath() + ") to (" + pDestinationFile.getAbsolutePath() + ") " + pAdditionalExplanation );
398 + }
399 +
400 + private static class StringMatcherFilenameFilter implements FilenameFilter {
401 + private StringMatcher mSM;
402 +
403 + public StringMatcherFilenameFilter( StringMatcher pSM ) {
404 + mSM = pSM;
405 + }
406 +
407 + @Override
408 + public boolean accept( File dir, String name ) {
409 + return mSM.matches( name );
410 + }
411 + }
412 +
413 + public static void main( String[] args )
414 + throws Exception {
415 + File zFile = new File( "PersistanceTier/design/NextGEN.xml" );
416 + String[] lines = loadTextFile( zFile );
417 + process( lines );
418 + storeTextFile( zFile, lines );
419 + }
420 +
421 + private static void process( String[] pLines ) {
422 + for ( int i = 0; i < pLines.length; i++ ) {
423 + String zLine = pLines[i];
424 + if ( zLine != null ) {
425 + if ( zLine.trim().startsWith( "<column " ) ) {
426 + processColumn( pLines, i, findEONode( pLines, i ) );
427 + } else if ( zLine.trim().startsWith( "<foreignKey " ) ) {
428 + processForeignKey( pLines, i, findEONode( pLines, i ) );
429 + }
430 + }
431 + }
432 + }
433 +
434 + private static int findEONode( String[] pLines, int pFromIndex ) {
435 + int zThruIndex = pFromIndex;
436 + while ( zThruIndex < pLines.length ) {
437 + String zLine = pLines[zThruIndex];
438 + if ( (zLine != null) && zLine.trim().endsWith( ">" ) ) {
439 + break;
440 + }
441 + zThruIndex++;
442 + }
443 + return zThruIndex;
444 + }
445 +
446 + private static boolean isAttributeOneOf( String pLine, String... pOneOf ) {
447 + for ( String s : pOneOf ) {
448 + if ( pLine.startsWith( s + "=" ) ) {
449 + return true;
450 + }
451 + }
452 + return false;
453 + }
454 +
455 + private static void processColumn( String[] pLines, int pBegLine, int pEndLine ) {
456 + for ( int i = pBegLine + 1; i < pEndLine; i++ ) {
457 + String zLine = pLines[i];
458 + if ( zLine != null ) {
459 + zLine = zLine.trim();
460 + if ( zLine.equals( "type=\"foreignKey\"" ) ) // No More Columns as ForeignKeys
461 + {
462 + for ( int j = pBegLine; j <= pEndLine; j++ ) {
463 + pLines[j] = null;
464 + }
465 + return;
466 + }
467 + if ( isAttributeOneOf( zLine, "fkonly", "isContainer", "IsContainer", "ReferenceSortColumn", "ThemDependsOnUs", "UsDependsOnThem", "table",
468 + "updateReferencedPO" ) ) {
469 + pLines[i] = null;
470 + }
471 + }
472 + }
473 + }
474 +
475 + private static void processForeignKey( String[] pLines, int pBegLine, int pEndLine ) {
476 + for ( int i = pBegLine + 1; i < pEndLine; i++ ) {
477 + String zLine = pLines[i];
478 + if ( zLine != null ) {
479 + zLine = zLine.trim();
480 + if ( isAttributeOneOf( zLine, "fkonly", "isContainer", "IsContainer", "defaultValue", "enumeration", "len" ) ) {
481 + pLines[i] = null;
482 + }
483 + }
484 + }
485 + }
486 +
487 + private static boolean areEqual( List<byte[]> pBytes1, List<byte[]> pBytes2 ) {
488 + if ( byteCount( pBytes1 ) == byteCount( pBytes2 ) ) {
489 + ByteStream zStream1 = new ByteStream( pBytes1 );
490 + ByteStream zStream2 = new ByteStream( pBytes2 );
491 + for ( Byte zByte1; org.litesoft.commonfoundation.typeutils.Objects.areNonArraysEqual( zByte1 = zStream1.next(), zStream2.next() ); ) {
492 + if ( zByte1 == null ) {
493 + return true;
494 + }
495 + }
496 + }
497 + return false;
498 + }
499 +
500 + private static int byteCount( List<byte[]> pBytes ) {
501 + int zCount = 0;
502 + for ( byte[] zBlock : pBytes ) {
503 + zCount += zBlock.length;
504 + }
505 + return zCount;
506 + }
507 +
508 + private static class ByteStream {
509 + private final Iterator<byte[]> mIterator;
510 + private byte[] mCurrentBlock;
511 + private int mBlockOffset;
512 +
513 + public ByteStream( List<byte[]> pBytes ) {
514 + mIterator = pBytes.iterator();
515 + prepBlock();
516 + }
517 +
518 + private void prepBlock() {
519 + if ( mIterator.hasNext() ) {
520 + mCurrentBlock = mIterator.next();
521 + mBlockOffset = 0;
522 + } else {
523 + mCurrentBlock = null;
524 + mBlockOffset = -1;
525 + }
526 + }
527 +
528 + public Byte next() {
529 + for (; mBlockOffset != -1; prepBlock() ) {
530 + if ( mBlockOffset < mCurrentBlock.length ) {
531 + return mCurrentBlock[mBlockOffset++];
532 + }
533 + }
534 + return null;
535 + }
536 + }
537 + }