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