/* * Copyright (C) 2012 Jason Gedge <http://www.gedge.ca> * * This file is part of the OpGraph project. * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ /** * */ package ca.gedge.opgraph.app.xml; import java.awt.Color; import java.awt.Dimension; import java.io.IOException; import javax.swing.JComponent; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import ca.gedge.opgraph.OpGraph; import ca.gedge.opgraph.app.extensions.Note; import ca.gedge.opgraph.app.extensions.Notes; import ca.gedge.opgraph.extensions.Extendable; import ca.gedge.opgraph.io.xml.XMLSerializer; import ca.gedge.opgraph.io.xml.XMLSerializerFactory; /** */ public class NotesXMLSerializer implements XMLSerializer { static final String NAMESPACE = "http://gedge.ca/ns/opgraph-app"; static final String PREFIX = "oga"; static final QName NOTES_QNAME = new QName(NAMESPACE, "notes", PREFIX); static final QName NOTE_QNAME = new QName(NAMESPACE, "note", PREFIX); @Override public void write(XMLSerializerFactory serializerFactory, Document doc, Element parentElem, Object obj) throws IOException { if(obj == null) throw new IOException("Null object given to serializer"); // setup namespace for document final Element rootEle = doc.getDocumentElement(); rootEle.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE + ":" + PREFIX, NAMESPACE); if(obj instanceof Notes) { // Create notes element, if any exist final Notes notes = (Notes)obj; if(notes.size() > 0) { final Element notesElem = doc.createElementNS(NAMESPACE, PREFIX + ":notes"); // Create elements for each note for(Note note : notes) write(serializerFactory, doc, notesElem, note); parentElem.appendChild(notesElem); } } else if(obj instanceof Note) { final Note note = (Note)obj; final Element noteElem = doc.createElementNS(NAMESPACE, PREFIX + ":note"); noteElem.setAttribute("title", note.getTitle()); noteElem.setTextContent(note.getBody()); final JComponent noteComp = note.getExtension(JComponent.class); if(noteComp != null) { final String colorString = Integer.toHexString(noteComp.getBackground().getRGB() & 0xFFFFFF); noteElem.setAttribute("x", "" + noteComp.getX()); noteElem.setAttribute("y", "" + noteComp.getY()); noteElem.setAttribute("width", "" + noteComp.getWidth()); noteElem.setAttribute("height", "" + noteComp.getHeight()); noteElem.setAttribute("color", "0x" + colorString); } parentElem.appendChild(noteElem); } else { throw new IOException(NotesXMLSerializer.class.getName() + " cannot write objects of type " + obj.getClass().getName()); } } @Override public Object read(XMLSerializerFactory serializerFactory, OpGraph graph, Object parent, Document doc, Element elem) throws IOException { Object ret = null; if(NOTES_QNAME.equals(XMLSerializerFactory.getQName(elem))) { // Try to get the parent object if(parent == null || !(parent instanceof Extendable)) throw new IOException("Notes extension requires parent to be extendable"); final Extendable extendable = (Extendable)parent; final Notes notes = new Notes(); // Read in each note final NodeList children = elem.getChildNodes(); for(int childIndex = 0; childIndex < children.getLength(); ++childIndex) { final Node noteNode = children.item(childIndex); if(noteNode instanceof Element) { final Element noteElem = (Element) noteNode; read(serializerFactory, graph, notes, doc, noteElem); } } extendable.putExtension(Notes.class, notes); ret = notes; } else if(NOTE_QNAME.equals(XMLSerializerFactory.getQName(elem))) { if(parent == null || !(parent instanceof Notes)) throw new IOException("Notes extension requires parent to be extendable"); final Notes notes = (Notes)parent; final String title = elem.getAttribute("title"); final String body = (elem.getTextContent() == null ? "" : elem.getTextContent().trim()); final Note note = new Note(title, body); final JComponent noteComp = note.getExtension(JComponent.class); if(noteComp != null) { if(elem.hasAttribute("x") && elem.hasAttribute("y")) { final int x = Integer.parseInt(elem.getAttribute("x")); final int y = Integer.parseInt(elem.getAttribute("y")); noteComp.setLocation(x, y); } if(elem.hasAttribute("width") && elem.hasAttribute("height")) { final int w = Integer.parseInt(elem.getAttribute("width")); final int h = Integer.parseInt(elem.getAttribute("height")); noteComp.setPreferredSize(new Dimension(w, h)); } if(elem.hasAttribute("color")) { noteComp.setBackground(Color.decode(elem.getAttribute("color"))); } } notes.add(note); ret = note; } return ret; } @Override public boolean handles(Class<?> cls) { return (cls == Notes.class || cls == Note.class); } @Override public boolean handles(QName name) { return (NOTES_QNAME.equals(name) || NOTE_QNAME.equals(name)); } }