custom XStream converters for more compact files

This commit is contained in:
Branislav Stojkovic
2019-03-09 21:45:34 +01:00
parent f63b422a8c
commit a83cda9ecd
7 changed files with 222 additions and 5 deletions
@@ -0,0 +1,56 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.presenter;
import java.awt.Color;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
/**
* Serializes {@link Color} objects as hex values instead of r/g/b. Backwards compatible when unmarshalling.
*
* @author Branislav Stojkovic
*/
public class ColorConverter extends com.thoughtworks.xstream.converters.extended.ColorConverter {
@Override
public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) {
Color c = (Color) object;
writer.addAttribute("hex", String.format("%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue()));
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
if (reader.getAttribute("hex") != null)
return Color.decode("#" + reader.getAttribute("hex"));
return super.unmarshal(reader, context);
}
@SuppressWarnings("rawtypes")
@Override
public boolean canConvert(Class clazz) {
return Color.class.isAssignableFrom(clazz);
}
}
@@ -0,0 +1,59 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.presenter;
import java.awt.Font;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
/**
* Serializes {@link Font} objects in a more compact fashion. Backwards compatible when unmarshalling.
*
* @author Branislav Stojkovic
*/
public class FontConverter extends com.thoughtworks.xstream.converters.extended.FontConverter {
@Override
public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) {
Font f = (Font) object;
writer.addAttribute("name", f.getFontName());
writer.addAttribute("size", Integer.toString(f.getSize()));
writer.addAttribute("style", Integer.toString(f.getStyle()));
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
if (reader.getAttribute("name") != null) {
return new Font(reader.getAttribute("name"), Integer.parseInt(reader.getAttribute("style")), Integer.parseInt(reader.getAttribute("size")));
}
return super.unmarshal(reader, context);
}
@SuppressWarnings("rawtypes")
@Override
public boolean canConvert(Class clazz) {
return Font.class.isAssignableFrom(clazz);
}
}
@@ -0,0 +1,95 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.presenter;
import org.diylc.core.measures.AbstractMeasure;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
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;
/**
* Serializes objects of types derived from {@link AbstractMeasure} objects in a compact format. Backwards compatible when unmarshalling.
*
* @author Branislav Stojkovic
*/
public class MeasureConverter implements Converter {
@SuppressWarnings("rawtypes")
@Override
public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) {
AbstractMeasure m = (AbstractMeasure) object;
if (m.getValue() != null)
writer.addAttribute("value", Double.toString(m.getValue()));
if (m.getUnit() != null)
writer.addAttribute("unit", m.getUnit().name());
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Double value = null;
String unitStr = null;
if (reader.getAttribute("value") != null) {
value = Double.parseDouble(reader.getAttribute("value"));
unitStr = reader.getAttribute("unit");
} else {
if (reader.hasMoreChildren()) {
reader.moveDown();
if (reader.getNodeName().equals("value"))
value = Double.parseDouble(reader.getValue());
else if (reader.getNodeName().equals("unit"))
unitStr = reader.getValue();
reader.moveUp();
}
if (reader.hasMoreChildren()) {
reader.moveDown();
if (reader.getNodeName().equals("value"))
value = Double.parseDouble(reader.getValue());
else if (reader.getNodeName().equals("unit"))
unitStr = reader.getValue();
reader.moveUp();
}
}
try {
Class requiredType = context.getRequiredType();
ParameterizedTypeImpl generic = (ParameterizedTypeImpl)requiredType.getGenericSuperclass();
Class unitType = (Class)generic.getActualTypeArguments()[0];
Object unit = unitStr == null ? null : Enum.valueOf(unitType, unitStr);
return requiredType.getConstructor(Double.class, unitType).newInstance(value, unit);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@SuppressWarnings("rawtypes")
@Override
public boolean canConvert(Class clazz) {
return AbstractMeasure.class.isAssignableFrom(clazz);
}
}
@@ -92,8 +92,15 @@ public class ProjectFileManager {
};
}
};
xStream.autodetectAnnotations(true);
xStream.registerConverter(new PointConverter());
xStream.autodetectAnnotations(true);
xStream.alias("point", java.awt.Point.class);
xStream.alias("font", java.awt.Font.class);
xStream.alias("project", Project.class);
xStream.aliasPackage("diylc", "org.diylc.components");
xStream.registerConverter(new PointConverter());
xStream.registerConverter(new ColorConverter());
xStream.registerConverter(new FontConverter());
xStream.registerConverter(new MeasureConverter());
xStream.addImmutableType(Color.class);
xStream.addImmutableType(java.awt.Point.class);
xStream.addImmutableType(org.diylc.core.measures.Voltage.class);
@@ -160,7 +167,7 @@ public class ProjectFileManager {
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new InputStreamReader(new FileInputStream(file))));
doc.getDocumentElement().normalize();
if (doc.getDocumentElement().getNodeName().equalsIgnoreCase(Project.class.getName())) {
if (doc.getDocumentElement().getNodeName().equals(Project.class.getName()) || doc.getDocumentElement().getNodeName().equals("project")) {
project = parseV3File(fileName, warnings);
} else {
if (!doc.getDocumentElement().getNodeName().equalsIgnoreCase("layout")) {
@@ -209,7 +216,7 @@ public class ProjectFileManager {
Reader reader = new InputStreamReader(fis, "UTF-8");
project = (Project) xStream.fromXML(reader);
} catch (Exception e) {
LOG.warn("Could not open with the new xStream, trying the old one");
LOG.warn("Could not open with the new xStream, trying the old one", e);
fis.close();
fis = new FileInputStream(fileName);
project = (Project) xStreamOld.fromXML(fis);