1   /****************************************************************************
2    * This demo file is part of yFiles for Java 2.14.
3    * Copyright (c) 2000-2017 by yWorks GmbH, Vor dem Kreuzberg 28,
4    * 72070 Tuebingen, Germany. All rights reserved.
5    * 
6    * yFiles demo files exhibit yFiles for Java functionalities. Any redistribution
7    * of demo files in source code or binary form, with or without
8    * modification, is not permitted.
9    * 
10   * Owners of a valid software license for a yFiles for Java version that this
11   * demo is shipped with are allowed to use the demo source code as basis
12   * for their own yFiles for Java powered applications. Use of such programs is
13   * governed by the rights and conditions as set out in the yFiles for Java
14   * license agreement.
15   * 
16   * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED
17   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19   * NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21   * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   *
27   ***************************************************************************/
28  package demo.view.uml;
29  
30  import org.w3c.dom.Element;
31  import org.w3c.dom.Node;
32  import y.io.graphml.NamespaceConstants;
33  import y.io.graphml.input.DeserializationEvent;
34  import y.io.graphml.input.DeserializationHandler;
35  import y.io.graphml.input.GraphMLParseException;
36  import y.io.graphml.output.GraphMLWriteException;
37  import y.io.graphml.output.SerializationEvent;
38  import y.io.graphml.output.SerializationHandler;
39  import y.io.graphml.output.XmlWriter;
40  
41  import java.util.ArrayList;
42  import java.util.List;
43  
44  /**
45   * Handles serialization and deserialization of the {@link UmlClassModel user data}.
46   */
47  class UmlClassModelIOHandler implements SerializationHandler, DeserializationHandler {
48    private static final String ELEMENT_MODEL = "Model";
49    private static final String ATTRIBUTE_TYPE = "type";
50    private static final String VALUE_TYPE_CLASS = "Class";
51    private static final String ATTRIBUTE_NAME = "name";
52    private static final String ELEMENT_ATTRIBUTES = "Attributes";
53    private static final String ELEMENT_OPERATIONS = "Operations";
54    private static final String ELEMENT_ATTRIBUTE = "Attribute";
55    private static final String ELEMENT_OPERATION = "Operation";
56    private static final String ATTRIBUTE_VALUE = "value";
57  
58    /**
59     * Handles the serialization of the model.
60     *
61     * @param event Event that contains all data that is needed for serialization.
62     * @throws GraphMLWriteException
63     */
64    public void onHandleSerialization(final SerializationEvent event) throws GraphMLWriteException {
65      final Object item = event.getItem();
66      if (item instanceof UmlClassModel) {
67        final UmlClassModel model = (UmlClassModel) item;
68        final XmlWriter writer = event.getWriter();
69        writer.writeStartElement(ELEMENT_MODEL, NamespaceConstants.YFILES_JAVA_NS);
70        writeType(writer, model);
71        writeName(writer, model);
72        writeAttributes(writer, model);
73        writeOperations(writer, model);
74        writer.writeEndElement();
75        event.setHandled(true);
76      }
77    }
78  
79    /**
80     * Writes the type of the model.
81     */
82    private void writeType(final XmlWriter writer, final UmlClassModel model) {
83      writer.writeAttribute(ATTRIBUTE_TYPE, VALUE_TYPE_CLASS);
84    }
85  
86    /**
87     * Writes the name of the model element.
88     */
89    private void writeName(final XmlWriter writer, final UmlClassModel model) {
90      writer.writeAttribute(ATTRIBUTE_NAME, model.getClassName());
91    }
92  
93    /**
94     * Writes the attributes.
95     */
96    private void writeAttributes(final XmlWriter writer, final UmlClassModel model) {
97      writer.writeStartElement(ELEMENT_ATTRIBUTES, NamespaceConstants.YFILES_JAVA_NS);
98      for (java.util.Iterator it = model.getAttributes().iterator(); it.hasNext(); ) {
99        final String attribute = (String) it.next();
100       writer.writeStartElement(ELEMENT_ATTRIBUTE, NamespaceConstants.YFILES_JAVA_NS);
101       writer.writeAttribute(ATTRIBUTE_VALUE, attribute);
102       writer.writeEndElement();
103     }
104     writer.writeEndElement();
105   }
106 
107   /**
108    * Writes the operations.
109    */
110   private void writeOperations(final XmlWriter writer, final UmlClassModel model) {
111     writer.writeStartElement(ELEMENT_OPERATIONS, NamespaceConstants.YFILES_JAVA_NS);
112     for (java.util.Iterator it = model.getOperations().iterator(); it.hasNext(); ) {
113       final String operation = (String) it.next();
114       writer.writeStartElement(ELEMENT_OPERATION, NamespaceConstants.YFILES_JAVA_NS);
115       writer.writeAttribute(ATTRIBUTE_VALUE, operation);
116       writer.writeEndElement();
117     }
118     writer.writeEndElement();
119   }
120 
121   /**
122    * Handles the deserialization of the model.
123    *
124    * @param event Event that contains all data that is needed for deserialization.
125    * @throws GraphMLParseException
126    */
127   public void onHandleDeserialization(final DeserializationEvent event) throws GraphMLParseException {
128     final org.w3c.dom.Node xmlNode = event.getXmlNode();
129 
130     if (xmlNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE &&
131         NamespaceConstants.YFILES_JAVA_NS.equals(xmlNode.getNamespaceURI())) {
132       if (ELEMENT_MODEL.equals(xmlNode.getLocalName())) {
133         Element element = (Element) xmlNode;
134         final String name = element.getAttribute(ATTRIBUTE_NAME);
135 
136         final List attributes = new ArrayList();
137         final List operations = new ArrayList();
138         for (Node childNode = xmlNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) {
139           if (ELEMENT_ATTRIBUTES.equals(childNode.getLocalName())) {
140             readAttributes(childNode, attributes);
141           } else if (ELEMENT_OPERATIONS.equals(childNode.getLocalName())) {
142             readOperations(childNode, operations);
143           }
144         }
145         event.setResult(new UmlClassModel(name, attributes, operations));
146       }
147     }
148   }
149 
150   /**
151    * Reads the list of attributes.
152    */
153   private void readAttributes(final Node xmlNode, final List attributes) {
154     for (Node childNode = xmlNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) {
155       if (ELEMENT_ATTRIBUTE.equals(childNode.getLocalName())) {
156         final Element element = (Element) childNode;
157         final String attribute = element.getAttribute(ATTRIBUTE_VALUE);
158         if (attribute != null && attribute.length() > 0) {
159           attributes.add(attribute);
160         }
161       }
162     }
163   }
164 
165   /**
166    * Reads the list of operations.
167    */
168   private void readOperations(final Node xmlNode, final List operations) {
169     for (Node childNode = xmlNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) {
170       if (ELEMENT_OPERATION.equals(childNode.getLocalName())) {
171         final Element element = (Element) childNode;
172         final String operation = element.getAttribute(ATTRIBUTE_VALUE);
173         if (operation != null && operation.length() > 0) {
174           operations.add(operation);
175         }
176       }
177     }
178   }
179 }
180