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);
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -2596,7 +2596,7 @@
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Cleaner XML format for .DIY files with less cross-references</description>
<description>Cleaner and more compact XML format for .DIY files resulting in files about half the size of originals. Backward compatible with older files, but might introduce issues when opening files from the new version using an old version!</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>BUG_FIX</changeType>