diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2019-10-25 20:00:06 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2019-10-25 20:00:06 +0000 |
commit | 6e32d853bea059a5ec795d779a0a3c29fc079b0d (patch) | |
tree | 4412ba59be3cec56042a410e0b70604a7a6f5799 | |
parent | 468346fca8ce777ecfdefd8d5125b71638315ea9 (diff) | |
download | poi-6e32d853bea059a5ec795d779a0a3c29fc079b0d.tar.gz poi-6e32d853bea059a5ec795d779a0a3c29fc079b0d.zip |
#63745 - Make GenericRecordJsonWriter Json-conformant
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1868952 13f79535-47bb-0310-9956-ffa450edef68
19 files changed, 606 insertions, 418 deletions
diff --git a/src/java/org/apache/poi/util/GenericRecordJsonWriter.java b/src/java/org/apache/poi/util/GenericRecordJsonWriter.java index b70fe362a7..10e6beb314 100644 --- a/src/java/org/apache/poi/util/GenericRecordJsonWriter.java +++ b/src/java/org/apache/poi/util/GenericRecordJsonWriter.java @@ -40,25 +40,39 @@ import java.nio.charset.StandardCharsets; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.List; import java.util.Map; -import java.util.function.BiConsumer; import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.xml.bind.DatatypeConverter; - import org.apache.poi.common.usermodel.GenericRecord; import org.apache.poi.util.GenericRecordUtil.AnnotatedFlag; +@SuppressWarnings({"UnusedReturnValue", "WeakerAccess"}) @Beta public class GenericRecordJsonWriter implements Closeable { private static final String TABS; private static final String ZEROS = "0000000000000000"; private static final Pattern ESC_CHARS = Pattern.compile("[\"\\p{Cntrl}\\\\]"); - private static final List<Map.Entry<Class,BiConsumer<GenericRecordJsonWriter,Object>>> handler = new ArrayList<>(); + @FunctionalInterface + protected interface GenericRecordHandler { + /** + * Handler method + * + * @param record the parent record, applied via instance method reference + * @param name the name of the property + * @param object the value of the property + * @return {@code true}, if the element was handled and output produced, + * The provided methods can be overridden and a implementation can return {@code false}, + * if the element hasn't been written to the stream + */ + boolean print(GenericRecordJsonWriter record, String name, Object object); + } + + private static final List<Map.Entry<Class,GenericRecordHandler>> handler = new ArrayList<>(); static { char[] t = new char[255]; @@ -81,22 +95,25 @@ public class GenericRecordJsonWriter implements Closeable { handler(Object.class, GenericRecordJsonWriter::printObject); } - private static void handler(Class c, BiConsumer<GenericRecordJsonWriter,Object> printer) { + private static void handler(Class c, GenericRecordHandler printer) { handler.add(new AbstractMap.SimpleEntry<>(c,printer)); } - private final PrintWriter fw; - private int indent = 0; - private boolean withComments = true; - private int childIndex = 0; + protected final AppendableWriter aw; + protected final PrintWriter fw; + protected int indent = 0; + protected boolean withComments = true; + protected int childIndex = 0; public GenericRecordJsonWriter(File fileName) throws IOException { OutputStream os = ("null".equals(fileName.getName())) ? new NullOutputStream() : new FileOutputStream(fileName); - fw = new PrintWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8)); + aw = new AppendableWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8)); + fw = new PrintWriter(aw); } public GenericRecordJsonWriter(Appendable buffer) { - fw = new PrintWriter(new AppendableWriter(buffer)); + aw = new AppendableWriter(buffer); + fw = new PrintWriter(aw); } public static String marshal(GenericRecord record) { @@ -123,7 +140,7 @@ public class GenericRecordJsonWriter implements Closeable { fw.close(); } - private String tabs() { + protected String tabs() { return TABS.substring(0, Math.min(indent, TABS.length())); } @@ -144,81 +161,103 @@ public class GenericRecordJsonWriter implements Closeable { } fw.println(); + boolean hasProperties = writeProperties(record); + fw.println(); + + writeChildren(record, hasProperties); + + fw.append(tabs); + fw.append("}"); + } + + protected boolean writeProperties(GenericRecord record) { Map<String, Supplier<?>> prop = record.getGenericProperties(); - if (prop != null) { - final int oldChildIndex = childIndex; - childIndex = 0; - prop.forEach(this::writeProp); - childIndex = oldChildIndex; + if (prop == null || prop.isEmpty()) { + return false; } - fw.println(); + final int oldChildIndex = childIndex; + childIndex = 0; + long cnt = prop.entrySet().stream().filter(e -> writeProp(e.getKey(),e.getValue())).count(); + childIndex = oldChildIndex; + + return cnt > 0; + } + + + protected boolean writeChildren(GenericRecord record, boolean hasProperties) { List<? extends GenericRecord> list = record.getGenericChildren(); - if (list != null && !list.isEmpty()) { - indent++; - fw.append(tabs()); - if (prop != null && !prop.isEmpty()) { - fw.append(", "); - } - fw.append("children: ["); - final int oldChildIndex = childIndex; - childIndex = 0; - list.forEach(l -> { writeValue(l); childIndex++; }); - childIndex = oldChildIndex; - fw.println(); - fw.append(tabs()); - fw.append("]"); + if (list == null || list.isEmpty()) { + return false; + } + + indent++; + aw.setHoldBack(tabs() + (hasProperties ? ", " : "") + "\"children\": [\n"); + final int oldChildIndex = childIndex; + childIndex = 0; + long cnt = list.stream().filter(l -> writeValue(null, l) && ++childIndex > 0).count(); + childIndex = oldChildIndex; + aw.setHoldBack(null); + + if (cnt > 0) { fw.println(); - indent--; + fw.println(tabs() + "]"); } + indent--; - fw.append(tabs); - fw.append("}"); + return cnt > 0; } public void writeError(String errorMsg) { fw.append("{ error: "); - printObject(errorMsg); + printObject("error", errorMsg); fw.append(" }"); } - private void writeProp(String k, Supplier<?> v) { - final boolean isNext = (childIndex++>0); - if (isNext) { - fw.println(); - } - fw.write(tabs()); - fw.write('\t'); - fw.write(isNext ? ", " : " "); - fw.write(k); - fw.write(": "); + protected boolean writeProp(String name, Supplier<?> value) { + final boolean isNext = (childIndex>0); + aw.setHoldBack(isNext ? "\n" + tabs() + "\t, " : tabs() + "\t "); final int oldChildIndex = childIndex; childIndex = 0; - writeValue(v.get()); - childIndex = oldChildIndex; + boolean written = writeValue(name, value.get()); + childIndex = oldChildIndex + (written ? 1 : 0); + aw.setHoldBack(null); + return written; } - private void writeValue(Object o) { + protected boolean writeValue(String name, Object o) { if (childIndex > 0) { - fw.println(','); - } - if (o == null) { - fw.write("null"); - } else { - handler.stream(). - filter(h -> matchInstanceOrArray(h.getKey(), o)). - findFirst(). - ifPresent(h -> h.getValue().accept(this, o)); + aw.setHoldBack(","); } + + GenericRecordHandler grh = (o == null) + ? GenericRecordJsonWriter::printNull + : handler.stream().filter(h -> matchInstanceOrArray(h.getKey(), o)). + findFirst().map(Map.Entry::getValue).orElse(null); + + boolean result = grh != null && grh.print(this, name, o); + aw.setHoldBack(null); + return result; } - private static boolean matchInstanceOrArray(Class key, Object instance) { + protected static boolean matchInstanceOrArray(Class key, Object instance) { return key.isInstance(instance) || (Array.class.equals(key) && instance.getClass().isArray()); } - private void printNumber(Object o) { + protected void printName(String name) { + fw.print(name != null ? "\""+name+"\": " : ""); + } + + protected boolean printNull(String name, Object o) { + printName(name); + fw.write("null"); + return true; + } + + protected boolean printNumber(String name, Object o) { Number n = (Number)o; - fw.print(n.toString()); + printName(name); + fw.print(n.longValue()); final int size; if (n instanceof Byte) { @@ -239,65 +278,81 @@ public class GenericRecordJsonWriter implements Closeable { fw.write(trimHex(l, size)); fw.write(" */"); } + return true; } - private void printBoolean(Object o) { + protected boolean printBoolean(String name, Object o) { + printName(name); fw.write(((Boolean)o).toString()); + return true; } - private void printList(Object o) { - fw.println('['); + protected boolean printList(String name, Object o) { + printName(name); + fw.println("["); int oldChildIndex = childIndex; childIndex = 0; //noinspection unchecked - ((List)o).forEach(e -> { writeValue(e); childIndex++; }); + ((List)o).forEach(e -> { writeValue(null, e); childIndex++; }); childIndex = oldChildIndex; - fw.write(']'); + fw.write(tabs() + "\t]"); + return true; } - private void printGenericRecord(Object o) { - fw.println(); + protected boolean printGenericRecord(String name, Object o) { + printName(name); this.indent++; write((GenericRecord) o); this.indent--; + return true; } - private void printAnnotatedFlag(Object o) { + protected boolean printAnnotatedFlag(String name, Object o) { + printName(name); AnnotatedFlag af = (AnnotatedFlag) o; - fw.write("0x"); - fw.write(Long.toHexString(af.getValue().get().longValue())); + fw.print(af.getValue().get().longValue()); if (withComments) { fw.write(" /* "); fw.write(af.getDescription()); fw.write(" */ "); } + return true; } - private void printBytes(Object o) { + protected boolean printBytes(String name, Object o) { + printName(name); fw.write('"'); - fw.write(DatatypeConverter.printBase64Binary((byte[]) o)); + fw.write(Base64.getEncoder().encodeToString((byte[]) o)); fw.write('"'); + return true; } - private void printPoint(Object o) { + protected boolean printPoint(String name, Object o) { + printName(name); Point2D p = (Point2D)o; - fw.write("{ x: "+p.getX()+", y: "+p.getY()+" }"); + fw.write("{ \"x\": "+p.getX()+", \"y\": "+p.getY()+" }"); + return true; } - private void printDimension(Object o) { + protected boolean printDimension(String name, Object o) { + printName(name); Dimension2D p = (Dimension2D)o; - fw.write("{ width: "+p.getWidth()+", height: "+p.getHeight()+" }"); + fw.write("{ \"width\": "+p.getWidth()+", \"height\": "+p.getHeight()+" }"); + return true; } - private void printRectangle(Object o) { + protected boolean printRectangle(String name, Object o) { + printName(name); Rectangle2D p = (Rectangle2D)o; - fw.write("{ x: "+p.getX()+", y: "+p.getY()+", width: "+p.getWidth()+", height: "+p.getHeight()+" }"); + fw.write("{ \"x\": "+p.getX()+", \"y\": "+p.getY()+", \"width\": "+p.getWidth()+", \"height\": "+p.getHeight()+" }"); + return true; } - private void printPath(Object o) { + protected boolean printPath(String name, Object o) { + printName(name); final PathIterator iter = ((Path2D)o).getPathIterator(null); final double[] pnts = new double[6]; - fw.print("["); + fw.write("["); indent += 2; String t = tabs(); @@ -309,19 +364,19 @@ public class GenericRecordJsonWriter implements Closeable { fw.print(t); isNext = true; final int segType = iter.currentSegment(pnts); - fw.append("{ type: "); + fw.append("{ \"type\": "); switch (segType) { case PathIterator.SEG_MOVETO: - fw.write("'move', x: "+pnts[0]+", y: "+pnts[1]); + fw.write("'move', \"x\": "+pnts[0]+", \"y\": "+pnts[1]); break; case PathIterator.SEG_LINETO: - fw.write("'lineto', x: "+pnts[0]+", y: "+pnts[1]); + fw.write("'lineto', \"x\": "+pnts[0]+", \"y\": "+pnts[1]); break; case PathIterator.SEG_QUADTO: - fw.write("'quad', x1: "+pnts[0]+", y1: "+pnts[1]+", x2: "+pnts[2]+", y2: "+pnts[3]); + fw.write("'quad', \"x1\": "+pnts[0]+", \"y1\": "+pnts[1]+", \"x2\": "+pnts[2]+", \"y2\": "+pnts[3]); break; case PathIterator.SEG_CUBICTO: - fw.write("'cubic', x1: "+pnts[0]+", y1: "+pnts[1]+", x2: "+pnts[2]+", y2: "+pnts[3]+", x3: "+pnts[4]+", y3: "+pnts[5]); + fw.write("'cubic', \"x1\": "+pnts[0]+", \"y1\": "+pnts[1]+", \"x2\": "+pnts[2]+", \"y2\": "+pnts[3]+", \"x3\": "+pnts[4]+", \"y3\": "+pnts[5]); break; case PathIterator.SEG_CLOSE: fw.write("'close'"); @@ -332,9 +387,11 @@ public class GenericRecordJsonWriter implements Closeable { } fw.write("]"); + return true; } - private void printObject(Object o) { + protected boolean printObject(String name, Object o) { + printName(name); fw.write('"'); final Matcher m = ESC_CHARS.matcher(o.toString()); @@ -374,20 +431,25 @@ public class GenericRecordJsonWriter implements Closeable { fw.write(sb.toString()); fw.write('"'); + return true; } - private void printAffineTransform(Object o) { + protected boolean printAffineTransform(String name, Object o) { + printName(name); AffineTransform xForm = (AffineTransform)o; fw.write( - "{ scaleX: "+xForm.getScaleX()+ - ", shearX: "+xForm.getShearX()+ - ", transX: "+xForm.getTranslateX()+ - ", scaleY: "+xForm.getScaleY()+ - ", shearY: "+xForm.getShearY()+ - ", transY: "+xForm.getTranslateY()+" }"); + "{ \"scaleX\": "+xForm.getScaleX()+ + ", \"shearX\": "+xForm.getShearX()+ + ", \"transX\": "+xForm.getTranslateX()+ + ", \"scaleY\": "+xForm.getScaleY()+ + ", \"shearY\": "+xForm.getShearY()+ + ", \"transY\": "+xForm.getTranslateY()+" }"); + return true; } - private void printColor(Object o) { + protected boolean printColor(String name, Object o) { + printName(name); + final int rgb = ((Color)o).getRGB(); fw.print(rgb); @@ -396,17 +458,20 @@ public class GenericRecordJsonWriter implements Closeable { fw.write(trimHex(rgb, 8)); fw.write(" */"); } + return true; } - private void printArray(Object o) { - fw.println('['); + protected boolean printArray(String name, Object o) { + printName(name); + fw.write("["); int length = Array.getLength(o); final int oldChildIndex = childIndex; for (childIndex=0; childIndex<length; childIndex++) { - writeValue(Array.get(o, childIndex)); + writeValue(null, Array.get(o, childIndex)); } childIndex = oldChildIndex; - fw.write(']'); + fw.write(tabs() + "\t]"); + return true; } static String trimHex(final long l, final int size) { @@ -433,30 +498,58 @@ public class GenericRecordJsonWriter implements Closeable { } static class AppendableWriter extends Writer { - private Appendable buffer; + private final Appendable appender; + private final Writer writer; + private String holdBack; AppendableWriter(Appendable buffer) { super(buffer); - this.buffer = buffer; + this.appender = buffer; + this.writer = null; + } + + AppendableWriter(Writer writer) { + super(writer); + this.appender = null; + this.writer = writer; + } + + void setHoldBack(String holdBack) { + this.holdBack = holdBack; } @Override public void write(char[] cbuf, int off, int len) throws IOException { - buffer.append(String.valueOf(cbuf), off, len); + if (holdBack != null) { + if (appender != null) { + appender.append(holdBack); + } else { + writer.write(holdBack); + } + holdBack = null; + } + + if (appender != null) { + appender.append(String.valueOf(cbuf), off, len); + } else { + writer.write(cbuf, off, len); + } } @Override public void flush() throws IOException { - if (buffer instanceof Flushable) { - ((Flushable)buffer).flush(); + Object o = (appender != null) ? appender : writer; + if (o instanceof Flushable) { + ((Flushable)o).flush(); } } @Override public void close() throws IOException { flush(); - if (buffer instanceof Closeable) { - ((Closeable)buffer).close(); + Object o = (appender != null) ? appender : writer; + if (o instanceof Closeable) { + ((Closeable)o).close(); } } } diff --git a/src/java/org/apache/poi/util/GenericRecordXmlWriter.java b/src/java/org/apache/poi/util/GenericRecordXmlWriter.java index 44ca83f14c..c5c7877f04 100644 --- a/src/java/org/apache/poi/util/GenericRecordXmlWriter.java +++ b/src/java/org/apache/poi/util/GenericRecordXmlWriter.java @@ -39,27 +39,41 @@ import java.nio.charset.StandardCharsets; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; +import java.util.Base64; import java.util.List; import java.util.Map; -import java.util.function.BiConsumer; import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.xml.bind.DatatypeConverter; - import org.apache.poi.common.usermodel.GenericRecord; import org.apache.poi.util.GenericRecordJsonWriter.AppendableWriter; import org.apache.poi.util.GenericRecordJsonWriter.NullOutputStream; +@SuppressWarnings("WeakerAccess") public class GenericRecordXmlWriter implements Closeable { private static final String TABS; private static final String ZEROS = "0000000000000000"; private static final Pattern ESC_CHARS = Pattern.compile("[<>&'\"\\p{Cntrl}]"); - private static final List<Map.Entry<Class, BiConsumer<GenericRecordXmlWriter,Object>>> handler = new ArrayList<>(); + @FunctionalInterface + protected interface GenericRecordHandler { + /** + * Handler method + * + * @param record the parent record, applied via instance method reference + * @param name the name of the property + * @param object the value of the property + * @return {@code true}, if the element was handled and output produced, + * The provided methods can be overridden and a implementation can return {@code false}, + * if the element hasn't been written to the stream + */ + boolean print(GenericRecordXmlWriter record, String name, Object object); + } + + private static final List<Map.Entry<Class, GenericRecordHandler>> handler = new ArrayList<>(); static { char[] t = new char[255]; @@ -83,7 +97,7 @@ public class GenericRecordXmlWriter implements Closeable { handler(Object.class, GenericRecordXmlWriter::printObject); } - private static void handler(Class c, BiConsumer<GenericRecordXmlWriter,Object> printer) { + private static void handler(Class c, GenericRecordHandler printer) { handler.add(new AbstractMap.SimpleEntry<>(c, printer)); } @@ -126,15 +140,15 @@ public class GenericRecordXmlWriter implements Closeable { fw.close(); } - private String tabs() { + protected String tabs() { return TABS.substring(0, Math.min(indent, TABS.length())); } public void write(GenericRecord record) { - write(record, "record"); + write("record", record); } - private void write(GenericRecord record, final String name) { + protected void write(final String name, GenericRecord record) { final String tabs = tabs(); Enum type = record.getGenericRecordType(); String recordName = (type != null) ? type.name() : record.getClass().getSimpleName(); @@ -148,49 +162,16 @@ public class GenericRecordXmlWriter implements Closeable { fw.append("\""); } - boolean hasChildren = false; - Map<String, Supplier<?>> prop = record.getGenericProperties(); - if (prop != null) { - final int oldChildIndex = childIndex; - childIndex = 0; - attributePhase = true; - List<Map.Entry<String,Supplier<?>>> complex = prop.entrySet().stream().flatMap(this::writeProp).collect(Collectors.toList()); - attributePhase = false; - if (!complex.isEmpty()) { - hasChildren = true; - fw.println(">"); - indent++; - complex.forEach(this::writeProp); - indent--; - } - childIndex = oldChildIndex; - } else { - fw.print(">"); - } + attributePhase = true; + + boolean hasComplex = writeProperties(record); attributePhase = false; - List<? extends GenericRecord> list = record.getGenericChildren(); - if (list != null && !list.isEmpty()) { - hasChildren = true; - indent++; - fw.println(); - fw.append(tabs()); - fw.println("<children>"); - indent++; - final int oldChildIndex = childIndex; - childIndex = 0; - list.forEach(l -> { writeValue("record", l); childIndex++; }); - childIndex = oldChildIndex; - fw.println(); - indent--; - fw.append(tabs()); - fw.println("</children>"); - indent--; - } + hasComplex |= writeChildren(record, hasComplex); - if (hasChildren) { + if (hasComplex) { fw.append(tabs); fw.println("</" + name + ">"); } else { @@ -198,13 +179,61 @@ public class GenericRecordXmlWriter implements Closeable { } } + protected boolean writeProperties(GenericRecord record) { + Map<String, Supplier<?>> prop = record.getGenericProperties(); + if (prop == null || prop.isEmpty()) { + return false; + } + + final int oldChildIndex = childIndex; + childIndex = 0; + List<Map.Entry<String,Supplier<?>>> complex = prop.entrySet().stream().flatMap(this::writeProp).collect(Collectors.toList()); + + attributePhase = false; + if (!complex.isEmpty()) { + fw.println(">"); + indent++; + complex.forEach(this::writeProp); + indent--; + } + childIndex = oldChildIndex; + + return !complex.isEmpty(); + } + + protected boolean writeChildren(GenericRecord record, boolean hasComplexProperties) { + List<? extends GenericRecord> list = record.getGenericChildren(); + if (list == null || list.isEmpty()) { + return false; + } + if (!hasComplexProperties) { + fw.print(">"); + } + + indent++; + fw.println(); + fw.println(tabs()+"<children>"); + indent++; + final int oldChildIndex = childIndex; + childIndex = 0; + list.forEach(l -> { + writeValue("record", l); + childIndex++; + }); + childIndex = oldChildIndex; + fw.println(); + indent--; + fw.println(tabs()+"</children>"); + indent--; + + return true; + } + public void writeError(String errorMsg) { - fw.append("<error>"); - printObject(errorMsg); - fw.append("</error>"); + printObject("error", errorMsg); } - private Stream<Map.Entry<String,Supplier<?>>> writeProp(Map.Entry<String,Supplier<?>> me) { + protected Stream<Map.Entry<String,Supplier<?>>> writeProp(Map.Entry<String,Supplier<?>> me) { Object obj = me.getValue().get(); if (obj == null) { return Stream.empty(); @@ -223,7 +252,7 @@ public class GenericRecordXmlWriter implements Closeable { return Stream.empty(); } - private static boolean isComplex(Object obj) { + protected static boolean isComplex(Object obj) { return !( obj instanceof Number || obj instanceof Boolean || @@ -233,100 +262,101 @@ public class GenericRecordXmlWriter implements Closeable { obj instanceof Enum); } - private void writeValue(String key, Object o) { - assert(key != null); - if (o instanceof GenericRecord) { - printGenericRecord((GenericRecord)o, key); - } else if (o != null) { - if (key.endsWith(">")) { + protected void writeValue(String name, Object value) { + assert(name != null); + if (value instanceof GenericRecord) { + printGenericRecord(name, value); + } else if (value != null) { + if (name.endsWith(">")) { fw.print("\t"); } - fw.print(attributePhase ? " " + key + "=\"" : tabs()+"<" + key); - if (key.endsWith(">")) { - fw.println(); - } - handler.stream(). - filter(h -> matchInstanceOrArray(h.getKey(), o)). + filter(h -> matchInstanceOrArray(h.getKey(), value)). findFirst(). - ifPresent(h -> h.getValue().accept(this, o)); + ifPresent(h -> h.getValue().print(this, name, value)); - if (attributePhase) { - fw.append("\""); - } - - if (key.endsWith(">")) { - fw.println(tabs()+"\t</"+key); - } else if (o instanceof List || o.getClass().isArray()) { - fw.println(tabs()+"</"+key+">"); - } } } - private static boolean matchInstanceOrArray(Class key, Object instance) { + protected static boolean matchInstanceOrArray(Class key, Object instance) { return key.isInstance(instance) || (Array.class.equals(key) && instance.getClass().isArray()); } - private void printNumber(Object o) { - assert(attributePhase); - Number n = (Number)o; - fw.print(n.toString()); + protected void openName(String name) { + name = name.replace(">>", ">"); if (attributePhase) { - return; + fw.print(" " + name.replace('>',' ').trim() + "=\""); + } else { + fw.print(tabs() + "<" + name); + if (name.endsWith(">")) { + fw.println(); + } } + } - final int size; - if (n instanceof Byte) { - size = 2; - } else if (n instanceof Short) { - size = 4; - } else if (n instanceof Integer) { - size = 8; - } else if (n instanceof Long) { - size = 16; + protected void closeName(String name) { + name = name.replace(">>", ">"); + if (attributePhase) { + fw.append("\""); } else { - size = -1; + if (name.endsWith(">")) { + fw.println(tabs() + "\t</" + name); + } else { + fw.println("/>"); + } } + } - long l = n.longValue(); - if (withComments && size > 0 && (l < 0 || l > 9)) { - fw.write(" /* 0x"); - fw.write(trimHex(l, size)); - fw.write(" */"); - } + protected boolean printNumber(String name, Object o) { + assert(attributePhase); + + openName(name); + Number n = (Number)o; + fw.print(n.toString()); + closeName(name); + + return true; } - private void printBoolean(Object o) { + protected boolean printBoolean(String name, Object o) { + assert (attributePhase); + openName(name); fw.write(((Boolean)o).toString()); + closeName(name); + return true; } - private void printList(Object o) { + protected boolean printList(String name, Object o) { assert (!attributePhase); - fw.println(">"); + openName(name+">"); int oldChildIndex = childIndex; childIndex = 0; //noinspection unchecked ((List)o).forEach(e -> { writeValue("item>", e); childIndex++; }); childIndex = oldChildIndex; + closeName(name+">"); + return true; } - private void printArray(Object o) { + protected boolean printArray(String name, Object o) { assert (!attributePhase); - fw.println(">"); + openName(name+">"); int length = Array.getLength(o); final int oldChildIndex = childIndex; for (childIndex=0; childIndex<length; childIndex++) { writeValue("item>", Array.get(o, childIndex)); } childIndex = oldChildIndex; + closeName(name+">"); + return true; } - private void printGenericRecord(Object o, String name) { - write((GenericRecord) o, name); + protected void printGenericRecord(String name, Object value) { + write(name, (GenericRecord) value); } - private void printAnnotatedFlag(Object o) { + protected boolean printAnnotatedFlag(String name, Object o) { assert (!attributePhase); GenericRecordUtil.AnnotatedFlag af = (GenericRecordUtil.AnnotatedFlag) o; Number n = af.getValue().get(); @@ -341,6 +371,7 @@ public class GenericRecordXmlWriter implements Closeable { len = 16; } + openName(name); fw.print(" flag=\"0x"); fw.print(trimHex(n.longValue(), len)); fw.print('"'); @@ -349,35 +380,50 @@ public class GenericRecordXmlWriter implements Closeable { fw.print(af.getDescription()); fw.print("\""); } - fw.println("/>"); + closeName(name); + return true; } - private void printBytes(Object o) { + protected boolean printBytes(String name, Object o) { assert (!attributePhase); - fw.write(">"); - fw.write(DatatypeConverter.printBase64Binary((byte[]) o)); + openName(name+">"); + fw.write(Base64.getEncoder().encodeToString((byte[]) o)); + closeName(name+">"); + return true; } - private void printPoint(Object o) { + protected boolean printPoint(String name, Object o) { assert (!attributePhase); + openName(name); Point2D p = (Point2D)o; fw.println(" x=\""+p.getX()+"\" y=\""+p.getY()+"\"/>"); + closeName(name); + return true; } - private void printDimension(Object o) { + protected boolean printDimension(String name, Object o) { assert (!attributePhase); + openName(name); Dimension2D p = (Dimension2D)o; fw.println(" width=\""+p.getWidth()+"\" height=\""+p.getHeight()+"\"/>"); + closeName(name); + return true; } - private void printRectangle(Object o) { + protected boolean printRectangle(String name, Object o) { assert (!attributePhase); + openName(name); Rectangle2D p = (Rectangle2D)o; fw.println(" x=\""+p.getX()+"\" y=\""+p.getY()+"\" width=\""+p.getWidth()+"\" height=\""+p.getHeight()+"\"/>"); + closeName(name); + return true; } - private void printPath(Object o) { + protected boolean printPath(String name, Object o) { assert (!attributePhase); + + openName(name+">"); + final PathIterator iter = ((Path2D)o).getPathIterator(null); final double[] pnts = new double[6]; @@ -385,10 +431,8 @@ public class GenericRecordXmlWriter implements Closeable { String t = tabs(); indent -= 2; - boolean isNext = false; while (!iter.isDone()) { fw.print(t); - isNext = true; final int segType = iter.currentSegment(pnts); fw.print("<pathelement "); switch (segType) { @@ -412,9 +456,12 @@ public class GenericRecordXmlWriter implements Closeable { iter.next(); } + closeName(name+">"); + return true; } - private void printObject(Object o) { + protected boolean printObject(String name, Object o) { + openName(name+">"); final Matcher m = ESC_CHARS.matcher(o.toString()); final StringBuffer sb = new StringBuffer(); while (m.find()) { @@ -444,34 +491,44 @@ public class GenericRecordXmlWriter implements Closeable { } m.appendTail(sb); fw.write(sb.toString()); + closeName(name+">"); + return true; } - private void printAffineTransform(Object o) { + protected boolean printAffineTransform(String name, Object o) { assert (!attributePhase); + openName(name); AffineTransform xForm = (AffineTransform)o; - fw.write( + fw.write("<"+name+ " scaleX=\""+xForm.getScaleX()+"\" "+ "shearX=\""+xForm.getShearX()+"\" "+ "transX=\""+xForm.getTranslateX()+"\" "+ "scaleY=\""+xForm.getScaleY()+"\" "+ "shearY=\""+xForm.getShearY()+"\" "+ "transY=\""+xForm.getTranslateY()+"\"/>"); + closeName(name); + return true; } - private void printColor(Object o) { + protected boolean printColor(String name, Object o) { assert (attributePhase); + openName(name); final int rgb = ((Color)o).getRGB(); - fw.print("0x"); - fw.print(trimHex(rgb, 8)); + fw.print("0x"+trimHex(rgb, 8)); + closeName(name); + return true; } - private void printBufferedImage(Object o) { + protected boolean printBufferedImage(String name, Object o) { assert (!attributePhase); + openName(name); BufferedImage bi = (BufferedImage)o; - fw.println(" width=\""+bi.getWidth()+"\" height=\""+bi.getHeight()+"\" bands=\""+bi.getColorModel().getNumComponents()+"\"/>"); + fw.println(" width=\""+bi.getWidth()+"\" height=\""+bi.getHeight()+"\" bands=\""+bi.getColorModel().getNumComponents()+"\""); + closeName(name); + return true; } - private String trimHex(final long l, final int size) { + protected String trimHex(final long l, final int size) { final String b = Long.toHexString(l); int len = b.length(); return ZEROS.substring(0, Math.max(0,size-len)) + b.substring(Math.max(0,len-size), len); diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectData.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectData.java index b1cb5a4324..c07323dad6 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectData.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectData.java @@ -20,11 +20,13 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; +import org.apache.poi.common.usermodel.GenericRecord; import org.apache.poi.hslf.record.ExOleObjStg; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.FileMagic; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.sl.usermodel.ObjectData; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -32,7 +34,7 @@ import org.apache.poi.util.POILogger; /** * A class that represents object data embedded in a slide show. */ -public class HSLFObjectData implements ObjectData { +public class HSLFObjectData implements ObjectData, GenericRecord { private static final POILogger LOG = POILogFactory.getLogger(HSLFObjectData.class); /** @@ -91,4 +93,14 @@ public class HSLFObjectData implements ObjectData { public String getFileName() { return null; } + + @Override + public Map<String, Supplier<?>> getGenericProperties() { + return null; + } + + @Override + public List<? extends GenericRecord> getGenericChildren() { + return Collections.singletonList(getExOleObjStg()); + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java index 1a8061d3c9..df3de7229a 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureData.java @@ -21,17 +21,28 @@ import java.awt.Dimension; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; - -import org.apache.poi.hslf.blip.*; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.Supplier; + +import org.apache.poi.common.usermodel.GenericRecord; +import org.apache.poi.hslf.blip.DIB; +import org.apache.poi.hslf.blip.EMF; +import org.apache.poi.hslf.blip.JPEG; +import org.apache.poi.hslf.blip.PICT; +import org.apache.poi.hslf.blip.PNG; +import org.apache.poi.hslf.blip.WMF; import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.sl.usermodel.PictureData; -import org.apache.poi.util.*; +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.Units; /** * A class that represents image data contained in a slide show. */ -public abstract class HSLFPictureData implements PictureData { +public abstract class HSLFPictureData implements PictureData, GenericRecord { /** * Size of the image checksum calculated using MD5 algorithm. @@ -226,4 +237,19 @@ public abstract class HSLFPictureData implements PictureData { Units.pointsToPixel(dim.getHeight()) ); } + + @Override + public Map<String, Supplier<?>> getGenericProperties() { + final Map<String,Supplier<?>> m = new LinkedHashMap<>(); + m.put("type", this::getType); + m.put("imageDimension", this::getImageDimension); + m.put("signature", this::getSignature); + m.put("uidInstanceCount", this::getUIDInstanceCount); + m.put("offset", this::getOffset); + m.put("uid", this::getUID); + m.put("checksum", this::getChecksum); + m.put("index", this::getIndex); + m.put("rawData", this::getRawData); + return Collections.unmodifiableMap(m); + } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java index 490a590d30..5f182d5886 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java @@ -53,6 +53,7 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.sl.usermodel.MasterSheet; import org.apache.poi.sl.usermodel.PictureData.PictureType; import org.apache.poi.sl.usermodel.SlideShow; +import org.apache.poi.util.GenericRecordUtil; import org.apache.poi.util.IOUtils; import org.apache.poi.util.Internal; import org.apache.poi.util.POILogFactory; @@ -1168,7 +1169,10 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap @Override public Map<String, Supplier<?>> getGenericProperties() { - return null; + return GenericRecordUtil.getGenericProperties( + "pictures", this::getPictureData, + "embeddedObjects", this::getEmbeddedObjects + ); } @Override diff --git a/src/testcases/org/apache/poi/ddf/TestEscherBSERecord.java b/src/testcases/org/apache/poi/ddf/TestEscherBSERecord.java index 8b47a299f4..0a86ef149f 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherBSERecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherBSERecord.java @@ -86,26 +86,26 @@ public final class TestEscherBSERecord { EscherBSERecord record = createRecord(); String expected = "{ /* BSE */\n" + - "\t recordId: -4089 /* 0xf007 */\n" + - "\t, version: 1\n" + - "\t, instance: 0\n" + - "\t, options: 1\n" + - "\t, recordSize: 44 /* 0x0000002c */\n" + - "\t, blipTypeWin32: 5\n" + - "\t, pictureTypeWin32: \"JPEG\"\n" + - "\t, blipTypeMacOS: 5\n" + - "\t, pictureTypeMacOS: \"JPEG\"\n" + - "\t, suid: \"AQIDBAUGBwgJCgsMDQ4PAA==\"\n" + - "\t, tag: 1\n" + - "\t, size: 0\n" + - "\t, ref: 2\n" + - "\t, offset: 3\n" + - "\t, usage: 4\n" + - "\t, name: 5\n" + - "\t, unused2: 6\n" + - "\t, unused3: 7\n" + - "\t, blipRecord: null\n" + - "\t, remainingData: \"\"\n" + + "\t \"recordId\": -4089 /* 0xf007 */\n" + + "\t, \"version\": 1\n" + + "\t, \"instance\": 0\n" + + "\t, \"options\": 1\n" + + "\t, \"recordSize\": 44 /* 0x0000002c */\n" + + "\t, \"blipTypeWin32\": 5\n" + + "\t, \"pictureTypeWin32\": \"JPEG\"\n" + + "\t, \"blipTypeMacOS\": 5\n" + + "\t, \"pictureTypeMacOS\": \"JPEG\"\n" + + "\t, \"suid\": \"AQIDBAUGBwgJCgsMDQ4PAA==\"\n" + + "\t, \"tag\": 1\n" + + "\t, \"size\": 0\n" + + "\t, \"ref\": 2\n" + + "\t, \"offset\": 3\n" + + "\t, \"usage\": 4\n" + + "\t, \"name\": 5\n" + + "\t, \"unused2\": 6\n" + + "\t, \"unused3\": 7\n" + + "\t, \"blipRecord\": null\n" + + "\t, \"remainingData\": \"\"\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); String actual = record.toString(); diff --git a/src/testcases/org/apache/poi/ddf/TestEscherBoolProperty.java b/src/testcases/org/apache/poi/ddf/TestEscherBoolProperty.java index 5aa14bf391..3b05780575 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherBoolProperty.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherBoolProperty.java @@ -27,12 +27,12 @@ public final class TestEscherBoolProperty { EscherBoolProperty p = new EscherBoolProperty(EscherPropertyTypes.GEOMETRY__FILLOK, 1); String expected = "{ /* GEOMETRY__FILLOK */\n" + - "\t id: 383 /* 0x017f */\n" + - "\t, name: \"geometry.fillok\"\n" + - "\t, propertyNumber: 383 /* 0x017f */\n" + - "\t, propertySize: 6\n" + - "\t, flags: 0x17f /* */ \n" + - "\t, value: 1\n" + + "\t \"id\": 383 /* 0x017f */\n" + + "\t, \"name\": \"geometry.fillok\"\n" + + "\t, \"propertyNumber\": 383 /* 0x017f */\n" + + "\t, \"propertySize\": 6\n" + + "\t, \"flags\": 383 /* */ \n" + + "\t, \"value\": 1\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals(expected, p.toString()); diff --git a/src/testcases/org/apache/poi/ddf/TestEscherChildAnchorRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherChildAnchorRecord.java index 5278ce990c..457accfa4d 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherChildAnchorRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherChildAnchorRecord.java @@ -66,15 +66,15 @@ public final class TestEscherChildAnchorRecord { public void testToString(){ String expected = "{ /* CHILD_ANCHOR */\n" + - "\t recordId: -4081 /* 0xf00f */\n" + - "\t, version: 1\n" + - "\t, instance: 0\n" + - "\t, options: 1\n" + - "\t, recordSize: 24 /* 0x00000018 */\n" + - "\t, x1: 1\n" + - "\t, y1: 2\n" + - "\t, x2: 3\n" + - "\t, y2: 4\n" + + "\t \"recordId\": -4081 /* 0xf00f */\n" + + "\t, \"version\": 1\n" + + "\t, \"instance\": 0\n" + + "\t, \"options\": 1\n" + + "\t, \"recordSize\": 24 /* 0x00000018 */\n" + + "\t, \"x1\": 1\n" + + "\t, \"y1\": 2\n" + + "\t, \"x2\": 3\n" + + "\t, \"y2\": 4\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals( expected, createRecord().toString() ); diff --git a/src/testcases/org/apache/poi/ddf/TestEscherClientAnchorRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherClientAnchorRecord.java index 64d0a6fd8f..5077118286 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherClientAnchorRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherClientAnchorRecord.java @@ -72,21 +72,21 @@ public class TestEscherClientAnchorRecord { public void testToString() { String expected = "{ /* CLIENT_ANCHOR */\n" + - "\t recordId: -4080 /* 0xf010 */\n" + - "\t, version: 1\n" + - "\t, instance: 0\n" + - "\t, options: 1\n" + - "\t, recordSize: 28 /* 0x0000001c */\n" + - "\t, flag: 77 /* 0x004d */\n" + - "\t, col1: 55 /* 0x0037 */\n" + - "\t, dx1: 33 /* 0x0021 */\n" + - "\t, row1: 88 /* 0x0058 */\n" + - "\t, dy1: 11 /* 0x000b */\n" + - "\t, col2: 44 /* 0x002c */\n" + - "\t, dx2: 22 /* 0x0016 */\n" + - "\t, row2: 99 /* 0x0063 */\n" + - "\t, dy2: 66 /* 0x0042 */\n" + - "\t, remainingData: \"/90=\"\n" + + "\t \"recordId\": -4080 /* 0xf010 */\n" + + "\t, \"version\": 1\n" + + "\t, \"instance\": 0\n" + + "\t, \"options\": 1\n" + + "\t, \"recordSize\": 28 /* 0x0000001c */\n" + + "\t, \"flag\": 77 /* 0x004d */\n" + + "\t, \"col1\": 55 /* 0x0037 */\n" + + "\t, \"dx1\": 33 /* 0x0021 */\n" + + "\t, \"row1\": 88 /* 0x0058 */\n" + + "\t, \"dy1\": 11 /* 0x000b */\n" + + "\t, \"col2\": 44 /* 0x002c */\n" + + "\t, \"dx2\": 22 /* 0x0016 */\n" + + "\t, \"row2\": 99 /* 0x0063 */\n" + + "\t, \"dy2\": 66 /* 0x0042 */\n" + + "\t, \"remainingData\": \"/90=\"\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals( expected, createRecord().toString() ); diff --git a/src/testcases/org/apache/poi/ddf/TestEscherClientDataRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherClientDataRecord.java index 63b21b89f4..3c0285931e 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherClientDataRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherClientDataRecord.java @@ -55,12 +55,12 @@ public class TestEscherClientDataRecord { public void testToString() { String expected = "{ /* CLIENT_DATA */\n" + - "\t recordId: -4079 /* 0xf011 */\n" + - "\t, version: 2\n" + - "\t, instance: 0\n" + - "\t, options: 2\n" + - "\t, recordSize: 8\n" + - "\t, remainingData: \"\"\n" + + "\t \"recordId\": -4079 /* 0xf011 */\n" + + "\t, \"version\": 2\n" + + "\t, \"instance\": 0\n" + + "\t, \"options\": 2\n" + + "\t, \"recordSize\": 8\n" + + "\t, \"remainingData\": \"\"\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals( expected, createRecord().toString() ); diff --git a/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java index 83244e8273..8c263b8bd2 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java @@ -83,12 +83,12 @@ public final class TestEscherContainerRecord { r.setOptions((short) 0x000F); String expected = "{ /* SP_CONTAINER */\n" + - "\t recordId: -4092 /* 0xf004 */\n" + - "\t, version: 15 /* 0x000f */\n" + - "\t, instance: 0\n" + - "\t, options: 15 /* 0x000f */\n" + - "\t, recordSize: 8\n" + - "\t, isContainer: true\n" + + "\t \"recordId\": -4092 /* 0xf004 */\n" + + "\t, \"version\": 15 /* 0x000f */\n" + + "\t, \"instance\": 0\n" + + "\t, \"options\": 15 /* 0x000f */\n" + + "\t, \"recordSize\": 8\n" + + "\t, \"isContainer\": true\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals(expected, r.toString()); @@ -101,22 +101,22 @@ public final class TestEscherContainerRecord { r.addChildRecord(r2); expected = "{ /* SP_CONTAINER */\n" + - "\t recordId: -4092 /* 0xf004 */\n" + - "\t, version: 15 /* 0x000f */\n" + - "\t, instance: 0\n" + - "\t, options: 15 /* 0x000f */\n" + - "\t, recordSize: 16 /* 0x00000010 */\n" + - "\t, isContainer: true\n" + - "\t, children: [\n" + + "\t \"recordId\": -4092 /* 0xf004 */\n" + + "\t, \"version\": 15 /* 0x000f */\n" + + "\t, \"instance\": 0\n" + + "\t, \"options\": 15 /* 0x000f */\n" + + "\t, \"recordSize\": 16 /* 0x00000010 */\n" + + "\t, \"isContainer\": true\n" + + "\t, \"children\": [\n" + "\t\t{ /* OPT */\n" + - "\t\t\t recordId: -4085 /* 0xf00b */\n" + - "\t\t\t, version: 3\n" + - "\t\t\t, instance: 0\n" + - "\t\t\t, options: 3\n" + - "\t\t\t, recordSize: 8\n" + - "\t\t\t, isContainer: false\n" + - "\t\t\t, properties: [\n" + - "]\n" + + "\t\t\t \"recordId\": -4085 /* 0xf00b */\n" + + "\t\t\t, \"version\": 3\n" + + "\t\t\t, \"instance\": 0\n" + + "\t\t\t, \"options\": 3\n" + + "\t\t\t, \"recordSize\": 8\n" + + "\t\t\t, \"isContainer\": false\n" + + "\t\t\t, \"properties\": [\n" + + "\t\t\t]\n" + "\t\t}\n" + "\t]\n" + "}"; @@ -126,33 +126,31 @@ public final class TestEscherContainerRecord { r.addChildRecord(r2); expected = "{ /* SP_CONTAINER */\n" + - "\t recordId: -4092 /* 0xf004 */\n" + - "\t, version: 15 /* 0x000f */\n" + - "\t, instance: 0\n" + - "\t, options: 15 /* 0x000f */\n" + - "\t, recordSize: 24 /* 0x00000018 */\n" + - "\t, isContainer: true\n" + - "\t, children: [\n" + + "\t \"recordId\": -4092 /* 0xf004 */\n" + + "\t, \"version\": 15 /* 0x000f */\n" + + "\t, \"instance\": 0\n" + + "\t, \"options\": 15 /* 0x000f */\n" + + "\t, \"recordSize\": 24 /* 0x00000018 */\n" + + "\t, \"isContainer\": true\n" + + "\t, \"children\": [\n" + "\t\t{ /* OPT */\n" + - "\t\t\t recordId: -4085 /* 0xf00b */\n" + - "\t\t\t, version: 3\n" + - "\t\t\t, instance: 0\n" + - "\t\t\t, options: 3\n" + - "\t\t\t, recordSize: 8\n" + - "\t\t\t, isContainer: false\n" + - "\t\t\t, properties: [\n" + - "]\n" + - "\t\t},\n" + - "\n" + - "\t\t{ /* OPT - index: 1 */\n" + - "\t\t\t recordId: -4085 /* 0xf00b */\n" + - "\t\t\t, version: 3\n" + - "\t\t\t, instance: 0\n" + - "\t\t\t, options: 3\n" + - "\t\t\t, recordSize: 8\n" + - "\t\t\t, isContainer: false\n" + - "\t\t\t, properties: [\n" + - "]\n" + + "\t\t\t \"recordId\": -4085 /* 0xf00b */\n" + + "\t\t\t, \"version\": 3\n" + + "\t\t\t, \"instance\": 0\n" + + "\t\t\t, \"options\": 3\n" + + "\t\t\t, \"recordSize\": 8\n" + + "\t\t\t, \"isContainer\": false\n" + + "\t\t\t, \"properties\": [\n" + + "\t\t\t]\n" + + "\t\t},\t\t{ /* OPT - index: 1 */\n" + + "\t\t\t \"recordId\": -4085 /* 0xf00b */\n" + + "\t\t\t, \"version\": 3\n" + + "\t\t\t, \"instance\": 0\n" + + "\t\t\t, \"options\": 3\n" + + "\t\t\t, \"recordSize\": 8\n" + + "\t\t\t, \"isContainer\": false\n" + + "\t\t\t, \"properties\": [\n" + + "\t\t\t]\n" + "\t\t}\n" + "\t]\n" + "}"; diff --git a/src/testcases/org/apache/poi/ddf/TestEscherDgRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherDgRecord.java index ac7f4bf0f2..a8735a068e 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherDgRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherDgRecord.java @@ -59,14 +59,14 @@ public final class TestEscherDgRecord { public void testToString() { String expected = "{ /* DG */\n" + - "\t recordId: -4088 /* 0xf008 */\n" + - "\t, version: 0\n" + - "\t, instance: 1\n" + - "\t, options: 16 /* 0x0010 */\n" + - "\t, recordSize: 16 /* 0x00000010 */\n" + - "\t, numShapes: 2\n" + - "\t, lastMSOSPID: 1025 /* 0x00000401 */\n" + - "\t, drawingGroupId: 1\n" + + "\t \"recordId\": -4088 /* 0xf008 */\n" + + "\t, \"version\": 0\n" + + "\t, \"instance\": 1\n" + + "\t, \"options\": 16 /* 0x0010 */\n" + + "\t, \"recordSize\": 16 /* 0x00000010 */\n" + + "\t, \"numShapes\": 2\n" + + "\t, \"lastMSOSPID\": 1025 /* 0x00000401 */\n" + + "\t, \"drawingGroupId\": 1\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals( expected, createRecord().toString() ); diff --git a/src/testcases/org/apache/poi/ddf/TestEscherDggRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherDggRecord.java index bcd5025c84..d06979dab9 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherDggRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherDggRecord.java @@ -70,21 +70,20 @@ public final class TestEscherDggRecord { public void testToString() { String expected = "{ /* DGG */\n" + - "\t recordId: -4090 /* 0xf006 */\n" + - "\t, version: 0\n" + - "\t, instance: 0\n" + - "\t, options: 0\n" + - "\t, recordSize: 32 /* 0x00000020 */\n" + - "\t, fileIdClusters: [\n" + - "\n" + + "\t \"recordId\": -4090 /* 0xf006 */\n" + + "\t, \"version\": 0\n" + + "\t, \"instance\": 0\n" + + "\t, \"options\": 0\n" + + "\t, \"recordSize\": 32 /* 0x00000020 */\n" + + "\t, \"fileIdClusters\": [\n" + "\t{ /* FileIdCluster */\n" + - "\t\t drawingGroupId: 1\n" + - "\t\t, numShapeIdUsed: 2\n" + - "\t}]\n" + - "\t, shapeIdMax: 1026 /* 0x00000402 */\n" + - "\t, numIdClusters: 2\n" + - "\t, numShapesSaved: 2\n" + - "\t, drawingsSaved: 1\n" + + "\t\t \"drawingGroupId\": 1\n" + + "\t\t, \"numShapeIdUsed\": 2\n" + + "\t}\t]\n" + + "\t, \"shapeIdMax\": 1026 /* 0x00000402 */\n" + + "\t, \"numIdClusters\": 2\n" + + "\t, \"numShapesSaved\": 2\n" + + "\t, \"drawingsSaved\": 1\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals( expected, createRecord().toString() ); diff --git a/src/testcases/org/apache/poi/ddf/TestEscherOptRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherOptRecord.java index 96c57e6ec6..33af04b3ba 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherOptRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherOptRecord.java @@ -148,22 +148,21 @@ public final class TestEscherOptRecord { r.addEscherProperty(prop1); String expected = "{ /* OPT */\n" + - "\t recordId: -4085 /* 0xf00b */\n" + - "\t, version: 3\n" + - "\t, instance: 1\n" + - "\t, options: 19 /* 0x0013 */\n" + - "\t, recordSize: 14 /* 0x0000000e */\n" + - "\t, isContainer: false\n" + - "\t, properties: [\n" + - "\n" + + "\t \"recordId\": -4085 /* 0xf00b */\n" + + "\t, \"version\": 3\n" + + "\t, \"instance\": 1\n" + + "\t, \"options\": 19 /* 0x0013 */\n" + + "\t, \"recordSize\": 14 /* 0x0000000e */\n" + + "\t, \"isContainer\": false\n" + + "\t, \"properties\": [\n" + "\t{ /* GEOMETRY__FILLOK */\n" + - "\t\t id: 383 /* 0x017f */\n" + - "\t\t, name: \"geometry.fillok\"\n" + - "\t\t, propertyNumber: 383 /* 0x017f */\n" + - "\t\t, propertySize: 6\n" + - "\t\t, flags: 0x17f /* */ \n" + - "\t\t, value: 1\n" + - "\t}]\n" + + "\t\t \"id\": 383 /* 0x017f */\n" + + "\t\t, \"name\": \"geometry.fillok\"\n" + + "\t\t, \"propertyNumber\": 383 /* 0x017f */\n" + + "\t\t, \"propertySize\": 6\n" + + "\t\t, \"flags\": 383 /* */ \n" + + "\t\t, \"value\": 1\n" + + "\t}\t]\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals( expected, r.toString()); diff --git a/src/testcases/org/apache/poi/ddf/TestEscherSpRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherSpRecord.java index 099022877f..786cf0917b 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherSpRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherSpRecord.java @@ -59,14 +59,14 @@ public class TestEscherSpRecord { public void testToString() { String expected = "{ /* SP */\n" + - "\t recordId: -4086 /* 0xf00a */\n" + - "\t, version: 2\n" + - "\t, instance: 0\n" + - "\t, options: 2\n" + - "\t, recordSize: 16 /* 0x00000010 */\n" + - "\t, shapeType: 0\n" + - "\t, shapeId: 1024 /* 0x00000400 */\n" + - "\t, flags: 0x5 /* GROUP | PATRIARCH */ \n" + + "\t \"recordId\": -4086 /* 0xf00a */\n" + + "\t, \"version\": 2\n" + + "\t, \"instance\": 0\n" + + "\t, \"options\": 2\n" + + "\t, \"recordSize\": 16 /* 0x00000010 */\n" + + "\t, \"shapeType\": 0\n" + + "\t, \"shapeId\": 1024 /* 0x00000400 */\n" + + "\t, \"flags\": 5 /* GROUP | PATRIARCH */ \n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals( expected, createRecord().toString() ); diff --git a/src/testcases/org/apache/poi/ddf/TestEscherSpgrRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherSpgrRecord.java index 6c04df66ec..0e8e356ff2 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherSpgrRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherSpgrRecord.java @@ -65,15 +65,15 @@ public final class TestEscherSpgrRecord { public void testToString() { String expected = "{ /* SPGR */\n" + - "\t recordId: -4087 /* 0xf009 */\n" + - "\t, version: 0\n" + - "\t, instance: 1\n" + - "\t, options: 16 /* 0x0010 */\n" + - "\t, recordSize: 24 /* 0x00000018 */\n" + - "\t, rectX1: 1\n" + - "\t, rectY1: 2\n" + - "\t, rectX2: 3\n" + - "\t, rectY2: 4\n" + + "\t \"recordId\": -4087 /* 0xf009 */\n" + + "\t, \"version\": 0\n" + + "\t, \"instance\": 1\n" + + "\t, \"options\": 16 /* 0x0010 */\n" + + "\t, \"recordSize\": 24 /* 0x00000018 */\n" + + "\t, \"rectX1\": 1\n" + + "\t, \"rectY1\": 2\n" + + "\t, \"rectX2\": 3\n" + + "\t, \"rectY2\": 4\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals( expected, createRecord().toString() ); diff --git a/src/testcases/org/apache/poi/ddf/TestEscherSplitMenuColorsRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherSplitMenuColorsRecord.java index 7571dcd6fe..6df9fd6122 100644 --- a/src/testcases/org/apache/poi/ddf/TestEscherSplitMenuColorsRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestEscherSplitMenuColorsRecord.java @@ -65,15 +65,15 @@ public final class TestEscherSplitMenuColorsRecord { public void testToString() { String expected = "{ /* SPLIT_MENU_COLORS */\n" + - "\t recordId: -3810 /* 0xf11e */\n" + - "\t, version: 0\n" + - "\t, instance: 4\n" + - "\t, options: 64 /* 0x0040 */\n" + - "\t, recordSize: 24 /* 0x00000018 */\n" + - "\t, color1: 1026 /* 0x00000402 */\n" + - "\t, color2: 2\n" + - "\t, color3: 2\n" + - "\t, color4: 1\n" + + "\t \"recordId\": -3810 /* 0xf11e */\n" + + "\t, \"version\": 0\n" + + "\t, \"instance\": 4\n" + + "\t, \"options\": 64 /* 0x0040 */\n" + + "\t, \"recordSize\": 24 /* 0x00000018 */\n" + + "\t, \"color1\": 1026 /* 0x00000402 */\n" + + "\t, \"color2\": 2\n" + + "\t, \"color3\": 2\n" + + "\t, \"color4\": 1\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals( expected, createRecord().toString() ); diff --git a/src/testcases/org/apache/poi/ddf/TestUnknownEscherRecord.java b/src/testcases/org/apache/poi/ddf/TestUnknownEscherRecord.java index 5a9c1aa459..d354c5d887 100644 --- a/src/testcases/org/apache/poi/ddf/TestUnknownEscherRecord.java +++ b/src/testcases/org/apache/poi/ddf/TestUnknownEscherRecord.java @@ -152,12 +152,12 @@ public final class TestUnknownEscherRecord { r.serialize( 0, data, new NullEscherSerializationListener() ); String expected = "{ /* UNKNOWN */\n" + - "\t recordId: -3822 /* 0xf112 */\n" + - "\t, version: 4\n" + - "\t, instance: 291 /* 0x0123 */\n" + - "\t, options: 4660 /* 0x1234 */\n" + - "\t, recordSize: 8\n" + - "\t, data: \"\"\n" + + "\t \"recordId\": -3822 /* 0xf112 */\n" + + "\t, \"version\": 4\n" + + "\t, \"instance\": 291 /* 0x0123 */\n" + + "\t, \"options\": 4660 /* 0x1234 */\n" + + "\t, \"recordSize\": 8\n" + + "\t, \"data\": \"\"\n" + "}"; expected = expected.replace("\n", System.getProperty("line.separator")); assertEquals(expected, r.toString() ); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestPolygon.java b/src/testcases/org/apache/poi/hssf/usermodel/TestPolygon.java index 252273076c..b47443b1b8 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestPolygon.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestPolygon.java @@ -92,11 +92,11 @@ public class TestPolygon { "<flags flag=\"0x8145\" description=\"IS_COMPLEX\"/>" + "<data>BQAFAPD/AAAFAFoABQAyACwAWgBYAAAABQA=</data>" + "<elements>" + - "<item>>AAAFAA==</item>" + - "<item>>WgAFAA==</item>" + - "<item>>MgAsAA==</item>" + - "<item>>WgBYAA==</item>" + - "<item>>AAAFAA==</item>" + + "<item>AAAFAA==</item>" + + "<item>WgAFAA==</item>" + + "<item>MgAsAA==</item>" + + "<item>WgBYAA==</item>" + + "<item>AAAFAA==</item>" + "</elements>" + "</record>"; String actual = verticesProp1.toXml("").replaceAll("[\r\n\t]",""); @@ -115,10 +115,10 @@ public class TestPolygon { "<flags flag=\"0x8145\" description=\"IS_COMPLEX\"/>" + "<data>BAAEAPD/AQAEAAIABQADAAYAAQAEAA==</data>" + "<elements>" + - "<item>>AQAEAA==</item>" + - "<item>>AgAFAA==</item>" + - "<item>>AwAGAA==</item>" + - "<item>>AQAEAA==</item>" + + "<item>AQAEAA==</item>" + + "<item>AgAFAA==</item>" + + "<item>AwAGAA==</item>" + + "<item>AQAEAA==</item>" + "</elements></record>"; actual = verticesProp1.toXml("").replaceAll("[\r\n\t]",""); |