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.layout.hierarchic;
29  
30  import demo.layout.hierarchic.CellSpanLayoutDemo.CellColorManager;
31  
32  import y.base.Graph;
33  import y.base.Node;
34  import y.io.GraphMLIOHandler;
35  import y.io.graphml.graph2d.GraphicsSerializationToolkit;
36  import y.io.graphml.input.DeserializationEvent;
37  import y.io.graphml.input.DeserializationHandler;
38  import y.io.graphml.input.GraphMLParseContext;
39  import y.io.graphml.input.GraphMLParseException;
40  import y.io.graphml.output.GraphMLWriteContext;
41  import y.io.graphml.output.GraphMLWriteException;
42  import y.io.graphml.output.SerializationEvent;
43  import y.io.graphml.output.SerializationHandler;
44  import y.io.graphml.output.XmlWriter;
45  import y.view.Graph2D;
46  import y.view.NodeRealizer;
47  import y.view.tabular.TableGroupNodeRealizer;
48  import y.view.tabular.TableGroupNodeRealizer.Column;
49  import y.view.tabular.TableGroupNodeRealizer.Table;
50  
51  import java.awt.Color;
52  import java.util.Collection;
53  
54  import org.w3c.dom.NamedNodeMap;
55  
56  /**
57   * Provides serialization support for
58   * {@link CellSpanLayoutDemo.CellColorManager} instances.
59   *
60   */
61  class CellSpanIoSupport {
62    /**
63     * Prevents instantiation of support class.
64     */
65    private CellSpanIoSupport() {
66    }
67  
68    /**
69     * Configures the given GraphML handler for reading and writing
70     * {@link CellSpanLayoutDemo.CellColorManager} instances.
71     * @param handler the GraphML handler to be configured.
72     * @return the new configured given GraphML handler. 
73     */
74    static GraphMLIOHandler configure( final GraphMLIOHandler handler ) {
75      final CellColorsIoHandler ccmHandler = new CellColorsIoHandler();
76      handler.getGraphMLHandler().addSerializationHandler(ccmHandler);
77      handler.getGraphMLHandler().addDeserializationHandler(ccmHandler);
78      return handler;
79    }
80  
81  
82  
83    /**
84     * Provides serialization support for
85     * {@link CellSpanLayoutDemo.CellColorManager} instances.
86     */
87    private static final class CellColorsIoHandler
88            implements DeserializationHandler, SerializationHandler {
89      private static final String ELEMENT_CELL_COLORS = "CellColors";
90      private static final String ELEMENT_CELL_COLOR = "CellColor";
91      private static final String ATTR_COLOR = "color";
92      private static final String ATTR_COLUMN = "column";
93      private static final String ATTR_ROW = "row";
94      private static final String NAMESPACE = "demo";
95  
96      /**
97       * Writes {@link CellSpanLayoutDemo.CellColorManager} instances.
98       */
99      public void onHandleSerialization(
100             final SerializationEvent e
101     ) throws GraphMLWriteException {
102       final Object item = e.getItem();
103       if (item instanceof CellColorManager) {
104         final GraphMLWriteContext context = e.getContext();
105         final Graph graph = context.getGraph();
106         if (graph instanceof Graph2D) {
107           final Collection stack = context.getObjectStack();
108           if (!stack.isEmpty()) {
109             final Object first = stack.iterator().next();
110             if (first instanceof Node) {
111               final NodeRealizer nr = ((Graph2D) graph).getRealizer((Node) first);
112               if (nr instanceof TableGroupNodeRealizer) {
113                 final XmlWriter writer = context.getWriter();
114                 writer.writeStartElement(NAMESPACE, ELEMENT_CELL_COLORS, NAMESPACE);
115 
116                 final CellColorManager manager = (CellColorManager) item;
117                 final Table table = ((TableGroupNodeRealizer) nr).getTable();
118                 for (int i = 0, n = table.columnCount(); i < n; ++i) {
119                   final Column col = table.getColumn(i);
120                   for (int j = 0, m = table.rowCount(); j < m; ++j) {
121                     final Color color = manager.getCellColor(col, table.getRow(j));
122                     if (color != null) {
123                       writer.writeStartElement(NAMESPACE, ELEMENT_CELL_COLOR, NAMESPACE);
124                       writer.writeAttribute(ATTR_COLOR, GraphicsSerializationToolkit.valueOf(color));
125                       writer.writeAttribute(ATTR_COLUMN, i);
126                       writer.writeAttribute(ATTR_ROW, j);
127                       writer.writeEndElement();
128                     }
129                   }
130                 }
131 
132                 writer.writeEndElement();
133               }
134             }
135           }
136         }
137         e.setHandled(true);
138       }
139     }
140 
141     /**
142      * Reads {@link CellSpanLayoutDemo.CellColorManager} instances.
143      */
144     public void onHandleDeserialization(
145             final DeserializationEvent e
146     ) throws GraphMLParseException {
147       final org.w3c.dom.Node node = e.getXmlNode();
148       if (isDemoElement(node) &&
149           ELEMENT_CELL_COLORS.equals(node.getLocalName())) {
150         final CellColorManager manager = new CellColorManager();
151         e.setResult(manager);
152 
153         final GraphMLParseContext context = e.getContext();
154         final Graph graph = context.getGraph();
155         if (graph instanceof Graph2D) {
156           final Collection stack = context.getObjectStack();
157           if (!stack.isEmpty()) {
158             final Object first = stack.iterator().next();
159             if (first instanceof Node) {
160               final NodeRealizer nr = ((Graph2D) graph).getRealizer((Node) first);
161               if (nr instanceof TableGroupNodeRealizer) {
162                 final Table table = ((TableGroupNodeRealizer) nr).getTable();
163                 for (org.w3c.dom.Node child = node.getFirstChild();
164                      child != null;
165                      child = child.getNextSibling()) {
166                   if (isDemoElement(child) &&
167                       ELEMENT_CELL_COLOR.equals(child.getLocalName())) {
168                     final NamedNodeMap attrs = child.getAttributes();
169                     final org.w3c.dom.Node cn = attrs.getNamedItem(ATTR_COLOR);
170                     if (cn == null) {
171                       throw new GraphMLParseException("Missing color attribute.");
172                     }
173                     final org.w3c.dom.Node colNode = attrs.getNamedItem(ATTR_COLUMN);
174                     if (colNode == null) {
175                       throw new GraphMLParseException("Missing column attribute.");
176                     }
177                     final org.w3c.dom.Node rowNode = attrs.getNamedItem(ATTR_ROW);
178                     if (rowNode == null) {
179                       throw new GraphMLParseException("Missing row attribute.");
180                     }
181 
182                     final Color color = GraphicsSerializationToolkit.parseColor(cn.getNodeValue());
183                     final int col = Integer.parseInt(colNode.getNodeValue());
184                     final int row = Integer.parseInt(rowNode.getNodeValue());
185                     manager.setCellColor(table.getColumn(col), table.getRow(row), color);
186                   }
187                 }
188               }
189             }
190           }
191         }
192       }
193     }
194 
195     /**
196      * Determines whether or not the given XML node is an element node
197      * in the <code>demo</code> namespace.
198      * @param node the XML node to check.
199      * @return <code>true</code> if the given XML node is an element node
200      * in the <code>demo</code> namespace; <code>false</code> otherwise.
201      */
202     private static boolean isDemoElement( final org.w3c.dom.Node node ) {
203       return node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE &&
204              NAMESPACE.equals(node.getNamespaceURI());
205     }
206   }
207 }
208