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];
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) {
fw.close();
}
- private String tabs() {
+ protected String tabs() {
return TABS.substring(0, Math.min(indent, TABS.length()));
}
}
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) {
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();
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'");
}
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());
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);
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) {
}
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();
}
}
}
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];
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));
}
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();
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 {
}
}
+ 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();
return Stream.empty();
}
- private static boolean isComplex(Object obj) {
+ protected static boolean isComplex(Object obj) {
return !(
obj instanceof Number ||
obj instanceof Boolean ||
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();
len = 16;
}
+ openName(name);
fw.print(" flag=\"0x");
fw.print(trimHex(n.longValue(), len));
fw.print('"');
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];
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) {
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()) {
}
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);
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;
/**
* 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);
/**
public String getFileName() {
return null;
}
+
+ @Override
+ public Map<String, Supplier<?>> getGenericProperties() {
+ return null;
+ }
+
+ @Override
+ public List<? extends GenericRecord> getGenericChildren() {
+ return Collections.singletonList(getExOleObjStg());
+ }
}
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.
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);
+ }
}
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;
@Override
public Map<String, Supplier<?>> getGenericProperties() {
- return null;
+ return GenericRecordUtil.getGenericProperties(
+ "pictures", this::getPictureData,
+ "embeddedObjects", this::getEmbeddedObjects
+ );
}
@Override
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();
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());
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() );
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() );
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() );
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());
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" +
"}";
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" +
"}";
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() );
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() );
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());
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() );
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() );
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() );
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() );
"<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]","");
"<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]","");