]> source.dussan.org Git - poi.git/commitdiff
Start on a new method for POIFS EntryUtils for checking to see if the two Directories...
authorNick Burch <nick@apache.org>
Fri, 25 Nov 2011 21:56:19 +0000 (21:56 +0000)
committerNick Burch <nick@apache.org>
Fri, 25 Nov 2011 21:56:19 +0000 (21:56 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1206355 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/poifs/filesystem/EntryUtils.java
src/testcases/org/apache/poi/poifs/filesystem/TestEntryUtils.java [new file with mode: 0644]

index deb30dae344b609d78f71b7161dc0c10079bdc63..c3c5145d0cae5f0cc2fe9fdd761c964ea64bf110 100644 (file)
 ==================================================================== */
 package org.apache.poi.poifs.filesystem;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.poi.util.Internal;
 
@@ -96,4 +99,118 @@ public class EntryUtils
         // System.err.println("CopyNodes called");
         copyNodes( source.getRoot(), target.getRoot(), excepts );
     }
+    
+    /**
+     * Checks to see if the two Directories hold the same contents.
+     * For this to be true, they must have entries with the same names,
+     *  no entries in one but not the other, and the size+contents
+     *  of each entry must match.
+     * TODO Some sort of excepts support
+     */
+    public static boolean areDirectoriesIdentical(DirectoryNode dirA, DirectoryNode dirB) {
+       // First up, check they have the same number of children
+       if (dirA.getEntryCount() != dirB.getEntryCount()) {
+          return false;
+       }
+       
+       // Next, check entries and their types/sizes
+       Map<String,Integer> aSizes = new HashMap<String, Integer>();
+       final int isDirectory = -12345; 
+       for (Entry a : dirA) {
+          String aName = a.getName();
+          if (a.isDirectoryEntry()) {
+             aSizes.put(aName, isDirectory);
+          } else {
+             aSizes.put(aName, ((DocumentNode)a).getSize());
+          }
+       }
+       for (Entry b : dirB) {
+          String bName = b.getName();
+          if (! aSizes.containsKey(bName)) {
+             // In B but not A
+             return false;
+          }
+          
+          int size;
+          if (b.isDirectoryEntry()) {
+             size = isDirectory;
+          } else {
+             size = ((DocumentNode)b).getSize();
+          }
+          if (size != aSizes.get(bName)) {
+             // Either the wrong type, or they're different sizes
+             return false;
+          }
+          
+          // Track it as checked
+          aSizes.remove(bName);
+       }
+       if (!aSizes.isEmpty()) {
+          // Nodes were in A but not B
+          return false;
+       }
+       
+       // If that passed, check entry contents
+       for (Entry a : dirA) {
+          try {
+             Entry b = dirB.getEntry(a.getName());
+             boolean match;
+             if (a.isDirectoryEntry()) {
+                match = areDirectoriesIdentical(
+                      (DirectoryNode)a, (DirectoryNode)b);
+             } else {
+                match = areDocumentsIdentical(
+                      (DocumentNode)a, (DocumentNode)b);
+             }
+             if (!match) return false;
+          } catch(FileNotFoundException e) {
+             // Shouldn't really happen...
+             return false;
+          } catch(IOException e) {
+             // Something's messed up with one document, not a match
+             return false;
+          }
+       }
+       
+       // If we get here, they match!
+       return true;
+    }
+    
+    /**
+     * Checks to see if two Documents have the same name
+     *  and the same contents. (Their parent directories are
+     *  not checked)
+     */
+    public static boolean areDocumentsIdentical(DocumentNode docA, DocumentNode docB) throws IOException {
+       if (! docA.getName().equals(docB.getName())) {
+          // Names don't match, not the same
+          return false;
+       }
+       if (docA.getSize() != docB.getSize()) {
+          // Wrong sizes, can't have the same contents
+          return false;
+       }
+
+       boolean matches = true;
+       DocumentInputStream inpA = null, inpB = null;
+       try {
+          inpA = new DocumentInputStream(docA);
+          inpB = new DocumentInputStream(docB);
+          
+          int readA, readB;
+          do {
+             readA = inpA.read();
+             readB = inpB.read();
+             if (readA != readB) {
+                matches = false;
+                break;
+             }
+          } while(readA != -1 && readB != -1);
+       } finally {
+          if (inpA != null) inpA.close();
+          if (inpB != null) inpB.close();
+       }
+       
+       return matches;
+    }
 }
diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestEntryUtils.java b/src/testcases/org/apache/poi/poifs/filesystem/TestEntryUtils.java
new file mode 100644 (file)
index 0000000..17b16ba
--- /dev/null
@@ -0,0 +1,38 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.poifs.filesystem;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.POIDataSamples;
+
+public class TestEntryUtils extends TestCase {
+    private static final POIDataSamples dataSamples = POIDataSamples.getPOIFSInstance();
+
+    public void testCopyRecursively() throws Exception {
+       // TODO
+    }
+
+    public void testAreDocumentsIdentical() throws Exception {
+       // TODO
+    }
+
+    public void testAreDirectoriesIdentical() throws Exception {
+       // TODO
+    }
+}