1   
28  package demo.io.graphml;
29  
30  import org.w3c.dom.Document;
31  import org.w3c.dom.DocumentFragment;
32  import org.w3c.dom.Element;
33  import org.w3c.dom.NamedNodeMap;
34  import org.w3c.dom.Node;
35  import org.w3c.dom.NodeList;
36  import y.base.DataMap;
37  import y.io.GraphMLIOHandler;
38  import y.io.graphml.GraphMLHandler;
39  import y.io.graphml.KeyScope;
40  import y.io.graphml.input.AbstractDataAcceptorInputHandler;
41  import y.io.graphml.input.GraphMLParseException;
42  import y.io.graphml.input.GraphMLParseContext;
43  import y.io.graphml.input.ParseEvent;
44  import y.io.graphml.input.ParseEventListenerAdapter;
45  import y.io.graphml.input.InputHandlerProvider;
46  import y.io.graphml.input.QueryInputHandlersEvent;
47  import y.io.graphml.output.AbstractDataProviderOutputHandler;
48  import y.io.graphml.output.GraphMLWriteException;
49  import y.io.graphml.output.GraphMLXmlAttribute;
50  import y.io.graphml.output.OutputHandlerProvider;
51  import y.io.graphml.output.QueryOutputHandlersEvent;
52  import y.io.graphml.output.GraphMLWriteContext;
53  import y.util.Maps;
54  
55  import javax.xml.parsers.DocumentBuilder;
56  import javax.xml.parsers.DocumentBuilderFactory;
57  import javax.xml.parsers.ParserConfigurationException;
58  import java.util.Collection;
59  import java.util.HashMap;
60  import java.util.HashSet;
61  import java.util.Iterator;
62  import java.util.LinkedList;
63  import java.util.Locale;
64  import java.util.Set;
65  import java.awt.EventQueue;
66  
67  
81  public class DynamicAttributesDemo extends GraphMLDemo {
82  
83    protected void loadInitialGraph() {
84      dynamicAttributes = new LinkedList();
85          loadGraph("resources/custom/simple-attributes.graphml");
87    }
88  
89    
92    protected GraphMLIOHandler createGraphMLIOHandler() {
93      GraphMLIOHandler ioHandler = new GraphMLIOHandler();
94      ioHandler.getGraphMLHandler().addParseEventListener(
95          new ParseEventListenerAdapter() {
96            public void onGraphMLParsing(ParseEvent event) {
97                          dynamicAttributes.clear();
99            }
100         });
101         ioHandler.getGraphMLHandler().addInputHandlerProvider(new DynamicAttributesInputHandlerProvider());
103     ioHandler.getGraphMLHandler().addOutputHandlerProvider(new DynamicAttributesOutputHandlerProvider());
104 
105     return ioHandler;
106   }
107 
108   
111   private static class AttributeDescriptor {
112     private Set attributeMetadata = new HashSet();
113     private DataMap dataMap;
114     private final KeyScope scope;
115 
116 
117     AttributeDescriptor(DataMap dataMap, KeyScope scope) {
118       this.dataMap = dataMap;
119       this.scope = scope;
120     }
121 
122     public void addAttribute(GraphMLXmlAttribute attr) {
123       attributeMetadata.add(attr);
124     }
125 
126     public Collection getAttributeMetadata() {
127       return attributeMetadata;
128     }
129 
130     public DataMap getDataMap() {
131       return dataMap;
132     }
133 
134     public KeyScope getScope() {
135       return scope;
136     }
137 
138     public Object getDefaultValue() {
139       return defaultValue;
140     }
141 
142     public void setDefaultValue(Object defaultValue) {
143       this.defaultValue = defaultValue;
144     }
145 
146     private Object defaultValue;
147 
148     public boolean isDefaultSet() {
149       return isDefaultSet;
150     }
151 
152     public void setDefaultSet(boolean defaultSet) {
153       isDefaultSet = defaultSet;
154     }
155 
156     private boolean isDefaultSet;
157   }
158 
159   private Collection dynamicAttributes;
160 
161   private class DynamicAttributesInputHandlerProvider implements InputHandlerProvider {
162     public void onQueryInputHandler(QueryInputHandlersEvent event) throws GraphMLParseException {
163       if (!event.isHandled()) {
164                         DataMap map = Maps.createDataMap(new HashMap());
167         KeyScope scope = GraphMLHandler.getKeyScope(event.getKeyDefinition());
168 
169                                 AttributeDescriptor descriptor = new AttributeDescriptor(map, scope);
173         dynamicAttributes.add(descriptor);
174 
175         XmlInputHandler handler = null;
176         try {
177           handler = new XmlInputHandler(descriptor);
178         } catch (ParserConfigurationException e) {
179           throw new GraphMLParseException("Error configuring internal DocumentBuilder", e);
180         }
181         handler.initializeFromKeyDefinition(event.getContext(), event.getKeyDefinition());
182         event.addInputHandler(handler);
183       }
184     }
185   }
186 
187   private class DynamicAttributesOutputHandlerProvider implements OutputHandlerProvider {
188     public void onQueryOutputHandler(QueryOutputHandlersEvent event) throws GraphMLWriteException {
189       for (Iterator iterator = dynamicAttributes.iterator(); iterator.hasNext();) {
190                         AttributeDescriptor descriptor = (AttributeDescriptor) iterator.next();
193         KeyScope scope = descriptor.getScope();
194         XmlOutputHandler outputHandler = new XmlOutputHandler(descriptor);
195         event.addOutputHandler(outputHandler, scope);
196       }
197     }
198   }
199 
200   
203   private static class XmlInputHandler extends AbstractDataAcceptorInputHandler {
204 
205     private final DocumentBuilder documentBuilder;
206 
207     XmlInputHandler(AttributeDescriptor descriptor) throws ParserConfigurationException {
208       this.descriptor = descriptor;
209       setDataAcceptor(descriptor.getDataMap());
210       DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
211       builderFactory.setNamespaceAware(true);
212       documentBuilder = builderFactory.newDocumentBuilder();
213     }
214 
215     private AttributeDescriptor descriptor;
216 
217     protected Object parseDataCore(GraphMLParseContext context, Node node) throws GraphMLParseException {
218       NodeList children = node.getChildNodes();
219                   Document targetDoc = documentBuilder.newDocument();
222       DocumentFragment fragment = node.getOwnerDocument().createDocumentFragment();
223       if (children != null) {
224         for (int i = 0; i < children.getLength(); i++) {
225           Node n = children.item(i);
226           fragment.appendChild(n.cloneNode(true));
227         }
228       }
229       Element rootElement = targetDoc.createElement("DocumentRoot");
230       targetDoc.appendChild(rootElement);
231       Node node1 = targetDoc.importNode(fragment, true);
232       rootElement.appendChild(node1);
233       return targetDoc;
234     }
235 
236     public void initializeFromKeyDefinition(GraphMLParseContext context, Element definition) throws
237         GraphMLParseException {
238       super.initializeFromKeyDefinition(context, definition);
239 
240             NamedNodeMap attributes = definition.getAttributes();
242       for (int i = 0; i < attributes.getLength(); ++i) {
243         Node attr = attributes.item(i);
244         descriptor.addAttribute(new GraphMLXmlAttribute(attr.getNodeName(), attr.getNamespaceURI(),
245             attr.getNodeValue()));
246       }
247       descriptor.setDefaultSet(isDefaultExists());
248       descriptor.setDefaultValue(getDefaultValue());
249     }
250   }
251 
252   
255   private static class XmlOutputHandler extends AbstractDataProviderOutputHandler {
256 
257     XmlOutputHandler(AttributeDescriptor descriptor) {
258       this.descriptor = descriptor;
259       setDefaultValue(descriptor.getDefaultValue());
260       setDataProvider(descriptor.getDataMap());
261       setDefaultValueAssigned(descriptor.isDefaultSet());
262     }
263 
264     private AttributeDescriptor descriptor;
265 
266     public Collection getKeyDefinitionAttributes() {
267       return descriptor.getAttributeMetadata();
268     }
269 
270     protected void writeValueCore(GraphMLWriteContext context, Object data) throws GraphMLWriteException {
271       if (data != null) {
272                 Document savedDoc = (Document) data;
274 
275         DocumentFragment fragment = savedDoc.createDocumentFragment();
276         NodeList children = savedDoc.getDocumentElement().getChildNodes();
277         if (children != null) {
278           for (int i = 0; i < children.getLength(); i++) {
279             Node n = children.item(i);
280             fragment.appendChild(n.cloneNode(true));
281           }
282         }
283         context.getWriter().writeDocumentFragment(fragment);
284       }
285     }
286   }
287 
288   
291   protected String[] getExampleResources() {
292     return new String[]{
293         "resources/custom/simple-attributes.graphml",
294         "resources/custom/complexdemo.graphml",
295     };
296   }
297 
298   
301   public static void main(String[] args) {
302     EventQueue.invokeLater(new Runnable() {
303       public void run() {
304         Locale.setDefault(Locale.ENGLISH);
305         initLnF();
306         (new DynamicAttributesDemo()).start();
307       }
308     });
309   }
310 }
311