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