001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.poifs.filesystem;
019:
020: import junit.framework.TestCase;
021: import junit.framework.ComparisonFailure;
022:
023: import java.io.*;
024: import java.util.*;
025:
026: import org.apache.poi.poifs.property.DirectoryProperty;
027: import org.apache.poi.poifs.property.Property;
028:
029: /**
030: * Verify the order of entries <code>DirectoryProperty</code> .
031: * <p>
032: * In particular it is important to serialize ROOT._VBA_PROJECT_CUR.VBA node.
033: * See bug 39234 in bugzilla. Thanks to Bill Seddon for providing the solution.
034: * </p>
035: *
036: * @author Yegor Kozlov
037: */
038: public class TestPropertySorter extends TestCase {
039:
040: //the correct order of entries in the test file
041: protected static final String[] _entries = { "dir", "JML", "UTIL",
042: "Loader", "Sheet1", "Sheet2", "Sheet3", "__SRP_0",
043: "__SRP_1", "__SRP_2", "__SRP_3", "__SRP_4", "__SRP_5",
044: "ThisWorkbook", "_VBA_PROJECT", };
045:
046: protected File testFile;
047:
048: public void setUp() {
049: String home = System.getProperty("HSSF.testdata.path");
050: testFile = new File(home + "/39234.xls");
051: }
052:
053: /**
054: * Test sorting of properties in <code>DirectoryProperty</code>
055: */
056: public void testSortProperties() throws IOException {
057: InputStream is = new FileInputStream(testFile);
058: POIFSFileSystem fs = new POIFSFileSystem(is);
059: is.close();
060: Property[] props = getVBAProperties(fs);
061:
062: assertEquals(_entries.length, props.length);
063:
064: // (1). See that there is a problem with the old case-sensitive property comparartor
065: Arrays.sort(props, new CaseSensitivePropertyComparator());
066: try {
067: for (int i = 0; i < props.length; i++) {
068: assertEquals(_entries[i], props[i].getName());
069: }
070: fail("case-sensitive property comparator returns properties in wrong order");
071: } catch (ComparisonFailure e) {
072: ; // as expected
073: }
074:
075: // (2) Verify that the fixed proeprty comparator works right
076: Arrays.sort(props, new DirectoryProperty.PropertyComparator());
077: for (int i = 0; i < props.length; i++) {
078: assertEquals(_entries[i], props[i].getName());
079: }
080: }
081:
082: /**
083: * Serialize file system and verify that the order of properties is the same as in the original file.
084: */
085: public void testSerialization() throws IOException {
086: InputStream is = new FileInputStream(testFile);
087: POIFSFileSystem fs = new POIFSFileSystem(is);
088: is.close();
089:
090: ByteArrayOutputStream out = new ByteArrayOutputStream();
091: fs.writeFilesystem(out);
092: out.close();
093: is = new ByteArrayInputStream(out.toByteArray());
094: fs = new POIFSFileSystem(is);
095: is.close();
096: Property[] props = getVBAProperties(fs);
097: Arrays.sort(props, new DirectoryProperty.PropertyComparator());
098:
099: assertEquals(_entries.length, props.length);
100: for (int i = 0; i < props.length; i++) {
101: assertEquals(_entries[i], props[i].getName());
102: }
103: }
104:
105: /**
106: * @return array of properties read from ROOT._VBA_PROJECT_CUR.VBA node
107: */
108: protected Property[] getVBAProperties(POIFSFileSystem fs)
109: throws IOException {
110: String _VBA_PROJECT_CUR = "_VBA_PROJECT_CUR";
111: String VBA = "VBA";
112:
113: DirectoryEntry root = fs.getRoot();
114: DirectoryEntry vba_project = (DirectoryEntry) root
115: .getEntry(_VBA_PROJECT_CUR);
116:
117: DirectoryNode vba = (DirectoryNode) vba_project.getEntry(VBA);
118: DirectoryProperty p = (DirectoryProperty) vba.getProperty();
119:
120: ArrayList lst = new ArrayList();
121: for (Iterator it = p.getChildren(); it.hasNext();) {
122: Property ch = (Property) it.next();
123: lst.add(ch);
124: }
125: return (Property[]) lst.toArray(new Property[0]);
126: }
127:
128: /**
129: * Old version of case-sensitive PropertyComparator to demonstrate the problem
130: */
131: private class CaseSensitivePropertyComparator implements Comparator {
132:
133: public boolean equals(Object o) {
134: return this == o;
135: }
136:
137: public int compare(Object o1, Object o2) {
138: String name1 = ((Property) o1).getName();
139: String name2 = ((Property) o2).getName();
140: int result = name1.length() - name2.length();
141:
142: if (result == 0) {
143: result = name1.compareTo(name2);
144: }
145: return result;
146: }
147: }
148:
149: }
|