Modified: poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java?rev=1876704&r1=1876703&r2=1876704&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java (original) +++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocumentPath.java Sat Apr 18 21:31:18 2020 @@ -15,175 +15,98 @@ See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - + package org.apache.poi.poifs.filesystem; import java.io.File; +import java.util.Arrays; +import java.util.Objects; +import java.util.function.Predicate; +import java.util.stream.Stream; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; /** * Class POIFSDocumentPath - * - * @author Marc Johnson (mjohnson at apache dot org) - * @version %I%, %G% */ -public class POIFSDocumentPath -{ +public class POIFSDocumentPath { + private static final POILogger log = POILogFactory.getLogger(POIFSDocumentPath.class); - + private final String[] components; private int hashcode; //lazy-compute hashCode /** - * constructor for the path of a document that is not in the root - * of the POIFSFileSystem - * - * @param components the Strings making up the path to a document. - * The Strings must be ordered as they appear in - * the directory hierarchy of the the document - * -- the first string must be the name of a - * directory in the root of the POIFSFileSystem, - * and every Nth (for N > 1) string thereafter - * must be the name of a directory in the - * directory identified by the (N-1)th string. - * <p> - * If the components parameter is null or has - * zero length, the POIFSDocumentPath is - * appropriate for a document that is in the - * root of a POIFSFileSystem - * - * @exception IllegalArgumentException if any of the elements in - * the components parameter - * are null or have zero - * length + * simple constructor for the path of a document that is in the root of the POIFSFileSystem. + * The constructor that takes an array of Strings can also be used to create such a + * POIFSDocumentPath by passing it a null or empty String array */ - - public POIFSDocumentPath(final String [] components) - throws IllegalArgumentException - { - if (components == null) - { - this.components = new String[ 0 ]; - } - else - { - this.components = new String[ components.length ]; - for (int j = 0; j < components.length; j++) - { - if ((components[ j ] == null) - || (components[ j ].length() == 0)) - { - throw new IllegalArgumentException( - "components cannot contain null or empty strings"); - } - this.components[ j ] = components[ j ]; - } - } + public POIFSDocumentPath() { + components = new String[0]; } /** - * simple constructor for the path of a document that is in the - * root of the POIFSFileSystem. The constructor that takes an - * array of Strings can also be used to create such a - * POIFSDocumentPath by passing it a null or empty String array + * constructor for the path of a document that is not in the root of the POIFSFileSystem + * + * @param components the Strings making up the path to a document. + * The Strings must be ordered as they appear in the directory hierarchy of the the document. + * The first string must be the name of a directory in the root of the POIFSFileSystem, and + * every Nth (for N > 1) string thereafter must be the name of a directory in the directory + * identified by the (N-1)th string. <p> If the components parameter is null or has zero length, + * the POIFSDocumentPath is appropriate for a document that is in the root of a POIFSFileSystem + * + * @exception IllegalArgumentException + * if any of the elements in the components parameter are null or have zero length */ - - public POIFSDocumentPath() - { - this.components = new String[ 0 ]; + public POIFSDocumentPath(final String [] components) throws IllegalArgumentException { + this(null, components); } /** - * constructor that adds additional subdirectories to an existing - * path + * constructor that adds additional subdirectories to an existing path * * @param path the existing path * @param components the additional subdirectory names to be added * - * @exception IllegalArgumentException if any of the Strings in - * components is null or zero - * length + * @exception IllegalArgumentException + * if any of the Strings in components is null or zero length */ + public POIFSDocumentPath(final POIFSDocumentPath path, final String[] components) throws IllegalArgumentException { + String[] s1 = (path == null) ? new String[0] : path.components; + String[] s2 = (components == null) ? new String[0] : components; - public POIFSDocumentPath(final POIFSDocumentPath path, - final String [] components) - throws IllegalArgumentException - { - if (components == null) - { - this.components = new String[ path.components.length ]; - } - else - { - this.components = - new String[ path.components.length + components.length ]; - } - System.arraycopy(path.components, 0, this.components, 0, path.components.length); - if (components != null) - { - for (int j = 0; j < components.length; j++) - { - if (components[ j ] == null) - { - throw new IllegalArgumentException( - "components cannot contain null"); - } - if (components[ j ].length() == 0) - { - log.log(POILogger.WARN, "Directory under " + path + " has an empty name, " + - "not all OLE2 readers will handle this file correctly!"); - } - - this.components[ j + path.components.length ] = - components[ j ]; - } + // TODO: Although the Javadoc says empty strings are forbidden, the adapted legacy + // implementation allowed it in case a path was specified... + Predicate<String> p = (path != null) ? Objects::isNull : (s) -> (s == null || s.isEmpty()); + if (Stream.of(s2).anyMatch(p)) { + throw new IllegalArgumentException("components cannot contain null or empty strings"); } + + this.components = Stream.concat(Stream.of(s1),Stream.of(s2)).toArray(String[]::new); } /** - * equality. Two POIFSDocumentPath instances are equal if they - * have the same number of component Strings, and if each - * component String is equal to its coresponding component String + * Two POIFSDocumentPath instances are equal if they have the same number of component Strings, + * and if each component String is equal to its corresponding component String * * @param o the object we're checking equality for * * @return true if the object is equal to this object */ - public boolean equals(final Object o) - { - boolean rval = false; - - if ((o != null) && (o.getClass() == this.getClass())) - { - if (this == o) - { - rval = true; - } - else - { - POIFSDocumentPath path = ( POIFSDocumentPath ) o; - - if (path.components.length == this.components.length) - { - rval = true; - for (int j = 0; j < this.components.length; j++) - { - if (!path.components[ j ] - .equals(this.components[ j ])) - { - rval = false; - break; - } - } - } - } + public boolean equals(final Object o) { + if (this == o) { + return true; + } + + if ((o != null) && (o.getClass() == this.getClass())) { + POIFSDocumentPath path = ( POIFSDocumentPath ) o; + return Arrays.equals(this.components, path.components); } - return rval; + return false; } /** @@ -192,30 +115,14 @@ public class POIFSDocumentPath * @return hashcode */ - public int hashCode() - { - if (hashcode == 0) - { - hashcode = computeHashCode(); - } - return hashcode; - } - - private int computeHashCode() { - int code = 0; - for (int j = 0; j < components.length; j++) - { - code += components[ j ].hashCode(); - } - return code; + public int hashCode() { + return (hashcode == 0) ? (hashcode = Arrays.hashCode(components)) : hashcode; } /** * @return the number of components */ - - public int length() - { + public int length() { return components.length; } @@ -228,10 +135,7 @@ public class POIFSDocumentPath * * @exception ArrayIndexOutOfBoundsException if n < 0 or n >= length() */ - - public String getComponent(int n) - throws ArrayIndexOutOfBoundsException - { + public String getComponent(int n) throws ArrayIndexOutOfBoundsException { return components[ n ]; } @@ -242,21 +146,10 @@ public class POIFSDocumentPath * @since 2002-01-24 * @return path of parent, or null if this path is the root path */ - - public POIFSDocumentPath getParent() - { - final int length = components.length - 1; - - if (length < 0) - { - return null; - } - String[] parentComponents = new String[ length ]; - System.arraycopy(components, 0, parentComponents, 0, length); - - return new POIFSDocumentPath(parentComponents); + public POIFSDocumentPath getParent() { + return (components.length == 0) ? null : new POIFSDocumentPath(Arrays.copyOf(components, components.length - 1)); } - + /** * <p>Returns the last name in the document path's name sequence. * If the document path's name sequence is empty, then the empty string is returned.</p> @@ -264,13 +157,8 @@ public class POIFSDocumentPath * @since 2016-04-09 * @return The last name in the document path's name sequence, or empty string if this is the root path */ - - public String getName() - { - if (components.length == 0) { - return ""; - } - return components[components.length - 1]; + public String getName() { + return components.length == 0 ? "" : components[components.length - 1]; } /** @@ -281,22 +169,8 @@ public class POIFSDocumentPath * * @since 2002-01-24 */ - - public String toString() - { - final StringBuilder b = new StringBuilder(); - final int l = length(); - - b.append(File.separatorChar); - for (int i = 0; i < l; i++) - { - b.append(getComponent(i)); - if (i < l - 1) - { - b.append(File.separatorChar); - } - } - return b.toString(); + public String toString() { + return File.separatorChar + String.join(String.valueOf(File.separatorChar), components); } -} // end public class POIFSDocumentPath +}
Modified: poi/trunk/src/java/org/apache/poi/util/HexDump.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/util/HexDump.java?rev=1876704&r1=1876703&r2=1876704&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/util/HexDump.java (original) +++ poi/trunk/src/java/org/apache/poi/util/HexDump.java Sat Apr 18 21:31:18 2020 @@ -17,13 +17,9 @@ package org.apache.poi.util; -import java.io.ByteArrayOutputStream; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; -import java.io.PrintStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -31,7 +27,7 @@ import java.nio.charset.StandardCharsets * dump data in hexadecimal format */ @Internal -public class HexDump { +public final class HexDump { public static final String EOL = System.getProperty("line.separator"); public static final Charset UTF8 = StandardCharsets.UTF_8; @@ -105,8 +101,8 @@ public class HexDump { public static String dump(final byte [] data, final long offset, final int index) { return dump(data, offset, index, Integer.MAX_VALUE); - } - + } + /** * dump an array of bytes to a String * @@ -128,23 +124,23 @@ public class HexDump { int data_length = (length == Integer.MAX_VALUE || length < 0 || index+length < 0) ? data.length : Math.min(data.length,index+length); - - + + if ((index < 0) || (index >= data.length)) { String err = "illegal index: "+index+" into array of length "+data.length; throw new ArrayIndexOutOfBoundsException(err); } - + long display_offset = offset + index; StringBuilder buffer = new StringBuilder(74); - + for (int j = index; j < data_length; j += 16) { int chars_read = data_length - j; if (chars_read > 16) { chars_read = 16; } - + writeHex(buffer, display_offset, 8, ""); for (int k = 0; k < 16; k++) { if (k < chars_read) { @@ -168,7 +164,7 @@ public class HexDump { if (Character.isISOControl(charB)) { return '.'; } - + switch (charB) { // printable, but not compilable with current compiler encoding case 0xFF: @@ -180,7 +176,7 @@ public class HexDump { } return charB; } - + /** * Converts the parameter to a hex value. * @@ -209,58 +205,6 @@ public class HexDump { * Converts the parameter to a hex value. * * @param value The value to convert - * @return A String representing the array of shorts - */ - public static String toHex(final short[] value) - { - StringBuilder retVal = new StringBuilder(); - retVal.append('['); - for(int x = 0; x < value.length; x++) - { - if (x>0) { - retVal.append(", "); - } - retVal.append(toHex(value[x])); - } - retVal.append(']'); - return retVal.toString(); - } - - /** - * <p>Converts the parameter to a hex value breaking the results into - * lines.</p> - * - * @param value The value to convert - * @param bytesPerLine The maximum number of bytes per line. The next byte - * will be written to a new line - * @return A String representing the array of bytes - */ - public static String toHex(final byte[] value, final int bytesPerLine) { - if (value.length == 0) { - return ": 0"; - } - final int digits = (int) Math.round(Math.log(value.length) / Math.log(10) + 0.5); - StringBuilder retVal = new StringBuilder(); - writeHex(retVal, 0, digits, ""); - retVal.append(": "); - for(int x=0, i=-1; x < value.length; x++) { - if (++i == bytesPerLine) { - retVal.append('\n'); - writeHex(retVal, x, digits, ""); - retVal.append(": "); - i = 0; - } else if (x>0) { - retVal.append(", "); - } - retVal.append(toHex(value[x])); - } - return retVal.toString(); - } - - /** - * Converts the parameter to a hex value. - * - * @param value The value to convert * @return The result right padded with 0 */ public static String toHex(short value) { @@ -306,57 +250,6 @@ public class HexDump { } /** - * Converts the string to a string of hex values by - * using String.getBytes(LocaleUtil.CHARSET_1252) to - * convert the string to a byte-array. - * - * @param value The value to convert - * @return The resulted hex string - */ - public static String toHex(String value) { - return (value == null || value.length() == 0) - ? "[]" - : toHex(value.getBytes(LocaleUtil.CHARSET_1252)); - } - - /** - * Dumps <code>bytesToDump</code> bytes to an output stream. - * - * @param in The stream to read from - * @param out The output stream - * @param start The index to use as the starting position for the left hand side label - * @param bytesToDump The number of bytes to output. Use -1 to read until the end of file. - */ - public static void dump( InputStream in, PrintStream out, int start, int bytesToDump ) throws IOException - { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - if (bytesToDump == -1) - { - int c = in.read(); - while (c != -1) - { - buf.write(c); - c = in.read(); - } - } - else - { - int bytesRemaining = bytesToDump; - while (bytesRemaining-- > 0) - { - int c = in.read(); - if (c == -1) { - break; - } - buf.write(c); - } - } - - byte[] data = buf.toByteArray(); - dump(data, 0, out, start, data.length); - } - - /** * @return string of 16 (zero padded) uppercase hex chars and prefixed with '0x' */ public static String longToHex(long value) { @@ -364,7 +257,7 @@ public class HexDump { writeHex(sb, value, 16, "0x"); return sb.toString(); } - + /** * @return string of 8 (zero padded) uppercase hex chars and prefixed with '0x' */ @@ -373,7 +266,7 @@ public class HexDump { writeHex(sb, value & 0xFFFFFFFFL, 8, "0x"); return sb.toString(); } - + /** * @return string of 4 (zero padded) uppercase hex chars and prefixed with '0x' */ @@ -382,7 +275,7 @@ public class HexDump { writeHex(sb, value & 0xFFFFL, 4, "0x"); return sb.toString(); } - + /** * @return string of 2 (zero padded) uppercase hex chars and prefixed with '0x' */ @@ -391,7 +284,7 @@ public class HexDump { writeHex(sb, value & 0xFFL, 2, "0x"); return sb.toString(); } - + /** * @see Integer#toHexString(int) * @see Long#toHexString(long) @@ -406,13 +299,5 @@ public class HexDump { acc >>>= 4; } sb.append(buf); - } - - - public static void main(String[] args) throws IOException { - InputStream in = new FileInputStream(args[0]); - byte[] b = IOUtils.toByteArray(in); - in.close(); - System.out.println(HexDump.dump(b, 0, 0)); } } Modified: poi/trunk/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java?rev=1876704&r1=1876703&r2=1876704&view=diff ============================================================================== --- poi/trunk/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java (original) +++ poi/trunk/src/testcases/org/apache/poi/hssf/model/TestDrawingAggregate.java Sat Apr 18 21:31:18 2020 @@ -55,7 +55,6 @@ import org.apache.poi.hssf.usermodel.HSS import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFTestHelper; import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.util.HexDump; import org.junit.Test; public class TestDrawingAggregate { @@ -231,7 +230,7 @@ public class TestDrawingAggregate { for(EscherRecord r : records) { out.write(r.serialize()); } - assertEquals(HexDump.toHex(dgBytes, 10), HexDump.toHex(out.toByteArray(), 10)); + assertArrayEquals(dgBytes, out.toByteArray()); } /** Modified: poi/trunk/src/testcases/org/apache/poi/util/TestHexDump.java URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/util/TestHexDump.java?rev=1876704&r1=1876703&r2=1876704&view=diff ============================================================================== --- poi/trunk/src/testcases/org/apache/poi/util/TestHexDump.java (original) +++ poi/trunk/src/testcases/org/apache/poi/util/TestHexDump.java Sat Apr 18 21:31:18 2020 @@ -22,7 +22,11 @@ import static org.junit.Assert.assertEqu import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -35,12 +39,7 @@ public class TestHexDump { @BeforeClass public static void setUp() throws UnsupportedEncodingException { SYSTEM_OUT = System.out; - System.setOut(new PrintStream(new OutputStream() { - @Override - public void write(int b) throws IOException { - - } - }, false, "UTF-8")); + System.setOut(new PrintStream(new OutputStream() {public void write(int b) {}}, false, "UTF-8")); } @AfterClass @@ -153,10 +152,6 @@ public class TestHexDump { public void testToHex() { assertEquals("000A", HexDump.toHex((short)0xA)); - assertEquals("[]", HexDump.toHex(new short[] { })); - assertEquals("[000A]", HexDump.toHex(new short[] { 0xA })); - assertEquals("[000A, 000B]", HexDump.toHex(new short[] { 0xA, 0xB })); - assertEquals("0A", HexDump.toHex((byte)0xA)); assertEquals("0000000A", HexDump.toHex(0xA)); @@ -164,12 +159,6 @@ public class TestHexDump { assertEquals("[0A]", HexDump.toHex(new byte[] { 0xA })); assertEquals("[0A, 0B]", HexDump.toHex(new byte[] { 0xA, 0xB })); - assertEquals(": 0", HexDump.toHex(new byte[] { }, 10)); - assertEquals("0: 0A", HexDump.toHex(new byte[] { 0xA }, 10)); - assertEquals("0: 0A, 0B", HexDump.toHex(new byte[] { 0xA, 0xB }, 10)); - assertEquals("0: 0A, 0B\n2: 0C, 0D", HexDump.toHex(new byte[] { 0xA, 0xB, 0xC, 0xD }, 2)); - assertEquals("0: 0A, 0B\n2: 0C, 0D\n4: 0E, 0F", HexDump.toHex(new byte[] { 0xA, 0xB, 0xC, 0xD, 0xE, 0xF }, 2)); - assertEquals("FFFF", HexDump.toHex((short)0xFFFF)); assertEquals("00000000000004D2", HexDump.toHex(1234L)); @@ -185,7 +174,7 @@ public class TestHexDump { } @Test - public void testDumpToString() throws Exception { + public void testDumpToString() { byte[] testArray = testArray(); String dump = HexDump.dump(testArray, 0, 0); //System.out.println("Hex: \n" + dump); @@ -199,93 +188,37 @@ public class TestHexDump { } @Test(expected=ArrayIndexOutOfBoundsException.class) - public void testDumpToStringOutOfIndex1() throws Exception { + public void testDumpToStringOutOfIndex1() { HexDump.dump(new byte[1], 0, -1); } @Test(expected=ArrayIndexOutOfBoundsException.class) - public void testDumpToStringOutOfIndex2() throws Exception { + public void testDumpToStringOutOfIndex2() { HexDump.dump(new byte[1], 0, 2); } @Test(expected=ArrayIndexOutOfBoundsException.class) - public void testDumpToStringOutOfIndex3() throws Exception { + public void testDumpToStringOutOfIndex3() { HexDump.dump(new byte[1], 0, 1); } @Test - public void testDumpToStringNoDataEOL1() throws Exception { + public void testDumpToStringNoDataEOL1() { HexDump.dump(new byte[0], 0, 1); } @Test - public void testDumpToStringNoDataEOL2() throws Exception { + public void testDumpToStringNoDataEOL2() { HexDump.dump(new byte[0], 0, 0); } - @Test - public void testDumpToPrintStream() throws IOException { - byte[] testArray = testArray(); - ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); - PrintStream out = new PrintStream(byteOut,true,LocaleUtil.CHARSET_1252.name()); - ByteArrayInputStream byteIn = new ByteArrayInputStream(testArray); - byteIn.mark(256); - String str; - - byteIn.reset(); - byteOut.reset(); - HexDump.dump(byteIn, out, 0, 256); - str = new String(byteOut.toByteArray(), LocaleUtil.CHARSET_1252); - assertTrue("Had: \n" + str, str.contains("0123456789:;<=>?")); - - // test with more than we have - byteIn.reset(); - byteOut.reset(); - HexDump.dump(byteIn, out, 0, 1000); - str = new String(byteOut.toByteArray(), LocaleUtil.CHARSET_1252); - assertTrue("Had: \n" + str, str.contains("0123456789:;<=>?")); - - // test with -1 - byteIn.reset(); - byteOut.reset(); - HexDump.dump(byteIn, out, 0, -1); - str = new String(byteOut.toByteArray(), LocaleUtil.CHARSET_1252); - assertTrue("Had: \n" + str, str.contains("0123456789:;<=>?")); - - byteIn.reset(); - byteOut.reset(); - HexDump.dump(byteIn, out, 1, 235); - str = new String(byteOut.toByteArray(), LocaleUtil.CHARSET_1252); - assertTrue("Line contents should be moved by one now, but Had: \n" + str, - str.contains("123456789:;<=>?@")); - - byteIn.close(); - byteOut.close(); - } - - @Test - public void testMain() throws Exception { - File file = TempFile.createTempFile("HexDump", ".dat"); - try { - try (FileOutputStream out = new FileOutputStream(file)) { - IOUtils.copy(new ByteArrayInputStream("teststring".getBytes(LocaleUtil.CHARSET_1252)), out); - } - assertTrue(file.exists()); - assertTrue(file.length() > 0); - - HexDump.main(new String[] { file.getAbsolutePath() }); - } finally { - assertTrue(file.exists() && file.delete()); - } - } - private static byte[] testArray() { byte[] testArray = new byte[ 256 ]; for (int j = 0; j < 256; j++) { testArray[ j ] = ( byte ) j; } - + return testArray; } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
