VisioPagesConverter.java
package com.taxonomy.visio.converter;
import com.taxonomy.visio.VisioDocument;
import com.taxonomy.visio.VisioPage;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import java.math.BigDecimal;
/** Marshals the Visio page index part used inside a {@code .vsdx} package. */
public class VisioPagesConverter implements Converter {
private static final String VISIO_NS =
"http://schemas.microsoft.com/office/visio/2012/main";
private static final String REL_NS =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships";
private static final double MINIMUM_PAGE_WIDTH = 11.0;
private static final double MINIMUM_PAGE_HEIGHT = 8.5;
private static final double PAGE_MARGIN = 1.0;
@Override
public boolean canConvert(Class type) {
return VisioDocument.class.equals(type);
}
@Override
public void marshal(
Object source,
HierarchicalStreamWriter writer,
MarshallingContext context) {
VisioDocument document = (VisioDocument) source;
writer.addAttribute("xmlns", VISIO_NS);
writer.addAttribute("xmlns:r", REL_NS);
for (int index = 0; index < document.getPages().size(); index++) {
VisioPage page = document.getPages().get(index);
writer.startNode("Page");
writer.addAttribute("ID", page.getId());
writer.addAttribute("Name", page.getName());
writer.addAttribute("NameU", "TaxonomyPage." + page.getId());
writer.addAttribute("IsCustomName", "1");
writer.addAttribute("IsCustomNameU", "1");
writer.startNode("PageSheet");
writeCell(writer, "PageWidth", decimal(pageWidth(page)));
writeCell(writer, "PageHeight", decimal(pageHeight(page)));
writeCell(writer, "PageScale", "1");
writeCell(writer, "DrawingScale", "1");
writer.endNode();
writer.startNode("Rel");
writer.addAttribute("r:id", "rId" + (index + 1));
writer.endNode();
writer.endNode();
}
}
@Override
public Object unmarshal(
HierarchicalStreamReader reader,
UnmarshallingContext context) {
throw new UnsupportedOperationException(
"VisioPagesConverter does not support unmarshaling");
}
private static double pageWidth(VisioPage page) {
double right = page.getShapes().stream()
.mapToDouble(shape -> shape.getX() + shape.getWidth() / 2.0)
.max()
.orElse(0.0);
return Math.max(MINIMUM_PAGE_WIDTH, right + PAGE_MARGIN);
}
private static double pageHeight(VisioPage page) {
double top = page.getShapes().stream()
.mapToDouble(shape -> shape.getY() + shape.getHeight() / 2.0)
.max()
.orElse(0.0);
return Math.max(MINIMUM_PAGE_HEIGHT, top + PAGE_MARGIN);
}
private static void writeCell(
HierarchicalStreamWriter writer,
String name,
String value) {
writer.startNode("Cell");
writer.addAttribute("N", name);
writer.addAttribute("V", value);
writer.endNode();
}
private static String decimal(double value) {
return BigDecimal.valueOf(value).stripTrailingZeros().toPlainString();
}
}