Subversion Repository Public Repository

litesoft

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

Diff revisions: vs.
  @@ -1,23 +1,19 @@
1 1 // This Source Code is in the Public Domain per: http://unlicense.org
2 2 package org.litesoft.util;
3 3
4 - import java.io.*;
5 -
6 4 import org.litesoft.commonfoundation.typeutils.*;
7 5
6 + import java.io.*;
8 7 import java.util.*;
9 8
10 - public class TriDirUpdater
11 - {
9 + public class TriDirUpdater {
12 10 public static final String VERSION = "1.0";
13 11
14 12 public static final int MAX_FILE_SIZE = 32 * 1024 * 1024;
15 13
16 - private static File checkPath( String pType, String pPath )
17 - {
14 + private static File checkPath( String pType, String pPath ) {
18 15 File zPath = new File( pPath );
19 - if ( !zPath.isDirectory() )
20 - {
16 + if ( !zPath.isDirectory() ) {
21 17 System.out.println( pType + " Path, Not a Directory: " + zPath.getAbsolutePath() );
22 18 System.exit( 2 );
23 19 }
  @@ -25,16 +21,13 @@
25 21 }
26 22
27 23 public static void main( String[] args )
28 - throws Exception
29 - {
24 + throws Exception {
30 25 System.out.println( "3 (Tri) Directory Updater vs " + VERSION );
31 26 String zEditor = System.getenv( "Editor" );
32 - if ( zEditor == null )
33 - {
27 + if ( zEditor == null ) {
34 28 throw new IllegalStateException( "No 'Editor' environment variable" );
35 29 }
36 - if ( args.length != 3 )
37 - {
30 + if ( args.length != 3 ) {
38 31 showHelp();
39 32 }
40 33
  @@ -44,8 +37,7 @@
44 37 checkPath( "Working", args[2] ) ).process();
45 38 }
46 39
47 - private static void showHelp()
48 - {
40 + private static void showHelp() {
49 41 System.out.println( "Requires 3 parameters:" );
50 42 System.out.println();
51 43 System.out.println( " 1) Update Directory Path" );
  @@ -88,44 +80,36 @@
88 80 private final File mUpdatePath;
89 81 private final TargetTree mOriginal, mWorking;
90 82
91 - private TriDirUpdater( String pEditor, File pUpdatePath, File pOriginalPath, File pWorkingPath )
92 - {
83 + private TriDirUpdater( String pEditor, File pUpdatePath, File pOriginalPath, File pWorkingPath ) {
93 84 mEditor = pEditor;
94 85 mUpdatePath = pUpdatePath;
95 86 mOriginal = new TargetTree( pOriginalPath );
96 87 mWorking = new TargetTree( pWorkingPath );
97 88 }
98 89
99 - private void process()
100 - {
90 + private void process() {
101 91 mOriginal.populate();
102 92 mWorking.populate();
103 93 Queue<String> zDirectoriesToProcess = new LinkedList<String>();
104 94 process( zDirectoriesToProcess, "", getDirectoryEntries( mUpdatePath ) );
105 - while ( !zDirectoriesToProcess.isEmpty() )
106 - {
95 + while ( !zDirectoriesToProcess.isEmpty() ) {
107 96 String zRelativeDirectoryPath = zDirectoriesToProcess.remove();
108 97 process( zDirectoriesToProcess, zRelativeDirectoryPath, getDirectoryEntries( new File( mUpdatePath, zRelativeDirectoryPath ) ) );
109 98 }
110 - for ( String zUnmatchedOriginalRelativePath : mOriginal.getRelativePaths() )
111 - {
99 + for ( String zUnmatchedOriginalRelativePath : mOriginal.getRelativePaths() ) {
112 100 processNoUpdateFile( zUnmatchedOriginalRelativePath );
113 101 }
114 102 }
115 103
116 - private void process( Queue<String> pDirectoryCollector, String pRelativeDirectoryPath, String[] pNames )
117 - {
118 - for ( String zName : pNames )
119 - {
104 + private void process( Queue<String> pDirectoryCollector, String pRelativeDirectoryPath, String[] pNames ) {
105 + for ( String zName : pNames ) {
120 106 String zRelativePath = relativePath( pRelativeDirectoryPath, zName );
121 107 File zFile = new File( mUpdatePath, zRelativePath );
122 - if ( zFile.isFile() )
123 - {
108 + if ( zFile.isFile() ) {
124 109 processUpdateFile( zRelativePath );
125 110 continue;
126 111 }
127 - if ( zFile.isDirectory() )
128 - {
112 + if ( zFile.isDirectory() ) {
129 113 pDirectoryCollector.add( zRelativePath );
130 114 continue;
131 115 }
  @@ -133,100 +117,81 @@
133 117 }
134 118 }
135 119
136 - private static String[] getDirectoryEntries( File pDirectory )
137 - {
120 + private static String[] getDirectoryEntries( File pDirectory ) {
138 121 String[] zFiles = pDirectory.list();
139 - if ( zFiles != null )
140 - {
122 + if ( zFiles != null ) {
141 123 return zFiles;
142 124 }
143 125 throw new IllegalStateException( "Unable to get Directory Listing from: " + pDirectory.getAbsolutePath() );
144 126 }
145 127
146 - private static String relativePath( String pRelativeDirectoryPath, String pName )
147 - {
128 + private static String relativePath( String pRelativeDirectoryPath, String pName ) {
148 129 return (pRelativeDirectoryPath.length() == 0) ? pName : pRelativeDirectoryPath + "/" + pName;
149 130 }
150 131
151 - private static class TargetTree
152 - {
132 + private static class TargetTree {
153 133 private final Map<String, File> mEntries = Maps.newHashMap();
154 134 private final File mBasePath;
155 135
156 - public TargetTree( File pBasePath )
157 - {
136 + public TargetTree( File pBasePath ) {
158 137 mBasePath = pBasePath;
159 138 }
160 139
161 - public void populate()
162 - {
140 + public void populate() {
163 141 populate( "", getDirectoryEntries( mBasePath ) );
164 142 }
165 143
166 - private void populate( String pRelativeDirectoryPath, String[] pNames )
167 - {
168 - for ( String zName : pNames )
169 - {
144 + private void populate( String pRelativeDirectoryPath, String[] pNames ) {
145 + for ( String zName : pNames ) {
170 146 String zRelativePath = relativePath( pRelativeDirectoryPath, zName );
171 147 File zFile = new File( mBasePath, zRelativePath );
172 - if ( zFile.isFile() )
173 - {
148 + if ( zFile.isFile() ) {
174 149 mEntries.put( zRelativePath, zFile );
175 150 continue;
176 151 }
177 - if ( !zFile.isDirectory() )
178 - {
152 + if ( !zFile.isDirectory() ) {
179 153 throw new IllegalStateException( "Neither a File or a Directory: " + zFile.getAbsolutePath() );
180 154 }
181 155 populate( zRelativePath, getDirectoryEntries( zFile ) );
182 156 }
183 157 }
184 158
185 - public File getFile( String pRelativePath )
186 - {
159 + public File getFile( String pRelativePath ) {
187 160 return mEntries.get( pRelativePath );
188 161 }
189 162
190 - public void removeEntry( String pRelativePath )
191 - {
163 + public void removeEntry( String pRelativePath ) {
192 164 mEntries.remove( pRelativePath );
193 165 }
194 166
195 - public String[] getRelativePaths()
196 - {
167 + public String[] getRelativePaths() {
197 168 return mEntries.keySet().toArray( new String[mEntries.size()] );
198 169 }
199 170
200 - public void delete( String pRelativePath )
201 - {
171 + public void delete( String pRelativePath ) {
202 172 FileUtils.deleteIfExists( mEntries.remove( pRelativePath ) );
203 173 }
204 174
205 - public void save( String pRelativePath, File pFile, byte[] pContents )
206 - {
175 + public void save( String pRelativePath, File pFile, byte[] pContents ) {
207 176 save( pFile, pContents );
208 177 removeEntry( pRelativePath );
209 178 }
210 179
211 - public void save( String pRelativePath, byte[] pContents )
212 - {
180 + public void save( String pRelativePath, byte[] pContents ) {
213 181 save( new File( mBasePath, pRelativePath ), pContents );
214 182 }
215 183
216 - private void save( File pFile, byte[] pContents )
217 - {
184 + private void save( File pFile, byte[] pContents ) {
218 185 FileUtils.store( pFile, pContents );
219 186 FileUtils.deleteIfExists( new File( pFile.getAbsolutePath() + ".bak" ) );
220 187 }
221 188 }
222 189
223 - private byte[] load( File pUpdateFile )
224 - {
190 + private byte[] load( File pUpdateFile ) {
225 191 return FileUtils.load( pUpdateFile, MAX_FILE_SIZE );
226 192 }
227 193
228 - private boolean different( byte[] pBytes1, byte[] pBytes2 )
229 - {
194 + private boolean different( byte[] pBytes1, byte[] pBytes2 ) {
230 195 return !Arrays.equals( pBytes1, pBytes2 );
231 196 }
232 197
  @@ -235,19 +200,16 @@
235 200 // No 'Original' file...
236 201 // Same - No Action taken...
237 202 // Different...
238 - private void processUpdateFile( String pRelativePath )
239 - {
203 + private void processUpdateFile( String pRelativePath ) {
240 204 File zUpdateFile = new File( mUpdatePath, pRelativePath );
241 205 byte[] zUpdateContents = load( zUpdateFile );
242 206 File zOriginalFile = mOriginal.getFile( pRelativePath );
243 - if ( zOriginalFile == null )
244 - {
207 + if ( zOriginalFile == null ) {
245 208 processUpdateButNoOriginal( pRelativePath, zUpdateFile, zUpdateContents );
246 209 return;
247 210 }
248 211 byte[] zOriginalContents = load( zOriginalFile );
249 - if ( different( zUpdateContents, zOriginalContents ) )
250 - {
212 + if ( different( zUpdateContents, zOriginalContents ) ) {
251 213 processUpdateDifferentThanOriginal( pRelativePath, zUpdateFile, zUpdateContents, zOriginalFile, zOriginalContents );
252 214 return;
253 215 }
  @@ -263,20 +225,16 @@
263 225 // - Offer Delete 'Working'?
264 226 // (if 'Working' is 0 length, then delete).
265 227 // Delete 'Original'.
266 - private void processNoUpdateFile( String pRelativePath )
267 - {
228 + private void processNoUpdateFile( String pRelativePath ) {
268 229 File zWorkingFile = mWorking.getFile( pRelativePath );
269 - if ( zWorkingFile != null )
270 - {
230 + if ( zWorkingFile != null ) {
271 231 File zOriginalFile = mOriginal.getFile( pRelativePath );
272 232 byte[] zWorkingContents = load( zWorkingFile );
273 233 byte[] zOriginalContents = load( zOriginalFile );
274 - if ( different( zOriginalContents, zWorkingContents ) )
275 - {
234 + if ( different( zOriginalContents, zWorkingContents ) ) {
276 235 checkWorkingChangedButNoUpdate( pRelativePath, zWorkingFile, zOriginalFile );
277 236 // ************************************* If Working is Empty, then complete merge!
278 - if ( zWorkingFile.length() != 0 )
279 - {
237 + if ( zWorkingFile.length() != 0 ) {
280 238 // Ignore!
281 239 mOriginal.removeEntry( pRelativePath );
282 240 mWorking.removeEntry( pRelativePath );
  @@ -294,15 +252,12 @@
294 252 // b) No 'Working' file
295 253 // - copy 'Update' to 'Working'.
296 254 // Copy 'Update' to 'Original'.
297 - private void processUpdateButNoOriginal( String pRelativePath, File pUpdateFile, byte[] pUpdateContents )
298 - {
255 + private void processUpdateButNoOriginal( String pRelativePath, File pUpdateFile, byte[] pUpdateContents ) {
299 256 File zWorkingFile = mWorking.getFile( pRelativePath );
300 - if ( zWorkingFile != null )
301 - {
257 + if ( zWorkingFile != null ) {
302 258 checkNewUpdateCollidesWithExistingWorking( pRelativePath, zWorkingFile, pUpdateFile );
303 259 // ************************************* If Working is Empty, then complete merge!
304 - if ( zWorkingFile.length() != 0 )
305 - {
260 + if ( zWorkingFile.length() != 0 ) {
306 261 // Ignore!
307 262 mWorking.removeEntry( pRelativePath );
308 263 return;
  @@ -320,26 +275,18 @@
320 275 // 'Update', 'Original', and 'Working'.
321 276 // Copy 'Update' to 'Original'.
322 277 private void processUpdateDifferentThanOriginal( String pRelativePath, File pUpdateFile, byte[] pUpdateContents, File pOriginalFile,
323 - byte[] pOriginalContents )
324 - {
278 + byte[] pOriginalContents ) {
325 279 File zWorkingFile = mWorking.getFile( pRelativePath );
326 - if ( zWorkingFile == null )
327 - {
280 + if ( zWorkingFile == null ) {
328 281 mWorking.save( pRelativePath, zWorkingFile, pUpdateContents );
329 - }
330 - else
331 - {
282 + } else {
332 283 byte[] zWorkingContents = load( zWorkingFile );
333 - if ( !different( pOriginalContents, zWorkingContents ) )
334 - {
284 + if ( !different( pOriginalContents, zWorkingContents ) ) {
335 285 mWorking.save( pRelativePath, zWorkingFile, pUpdateContents );
336 - }
337 - else
338 - {
286 + } else {
339 287 checkUpdateAndWorkingDifferentThanOriginal_threeWayMerge( pRelativePath, zWorkingFile, pUpdateFile, pOriginalFile );
340 288 // ************************************* If Working changed, then complete merge!
341 - if ( !different( zWorkingContents, load( zWorkingFile ) ) )
342 - {
289 + if ( !different( zWorkingContents, load( zWorkingFile ) ) ) {
343 290 // Ignore!
344 291 mOriginal.removeEntry( pRelativePath );
345 292 mWorking.removeEntry( pRelativePath );
  @@ -350,22 +297,19 @@
350 297 mOriginal.save( pRelativePath, pOriginalFile, pUpdateContents );
351 298 }
352 299
353 - private void checkWorkingChangedButNoUpdate( String pRelativePath, File pWorkingFile, File pOriginalFile )
354 - {
300 + private void checkWorkingChangedButNoUpdate( String pRelativePath, File pWorkingFile, File pOriginalFile ) {
355 301 System.out.println( "Working Changed But No Update: " + pRelativePath + "\n" +
356 302 " So Working shouldn't exist - Empty Working to complete merge..." );
357 303 ShellUtils.shell( mEditor, pWorkingFile.getAbsolutePath(), pOriginalFile.getAbsolutePath() );
358 304 }
359 305
360 - private void checkNewUpdateCollidesWithExistingWorking( String pRelativePath, File pWorkingFile, File pUpdateFile )
361 - {
306 + private void checkNewUpdateCollidesWithExistingWorking( String pRelativePath, File pWorkingFile, File pUpdateFile ) {
362 307 System.out.println( "New Update Collides With Existing Working: " + pRelativePath + "\n" +
363 308 " Move contents of Working to new file (leaving Working empty) to complete merge..." );
364 309 ShellUtils.shell( mEditor, pWorkingFile.getAbsolutePath(), pUpdateFile.getAbsolutePath() );
365 310 }
366 311
367 - private void checkUpdateAndWorkingDifferentThanOriginal_threeWayMerge( String pRelativePath, File pWorkingFile, File pUpdateFile, File pOriginalFile )
368 - {
312 + private void checkUpdateAndWorkingDifferentThanOriginal_threeWayMerge( String pRelativePath, File pWorkingFile, File pUpdateFile, File pOriginalFile ) {
369 313 System.out.println( "Change Collition, both Update AND Working differ from Original: " + pRelativePath + "\n" +
370 314 " Change Working to complete merge..." );
371 315 ShellUtils.shell( mEditor, pWorkingFile.getAbsolutePath(), pUpdateFile.getAbsolutePath(), pOriginalFile.getAbsolutePath() );