KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > xdm > xam > XDMAccess


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.xdm.xam;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import javax.swing.event.UndoableEditListener JavaDoc;
33 import javax.xml.namespace.QName JavaDoc;
34 import org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent;
35 import org.netbeans.modules.xml.xam.dom.DocumentModel;
36 import org.netbeans.modules.xml.xam.dom.DocumentModelAccess;
37 import org.netbeans.modules.xml.xam.dom.AbstractDocumentModel;
38 import org.netbeans.modules.xml.xam.dom.ElementIdentity;
39 import org.netbeans.modules.xml.xdm.XDMModel;
40 import org.netbeans.modules.xml.xdm.diff.NodeInfo;
41 import org.netbeans.modules.xml.xdm.nodes.Attribute;
42 import org.netbeans.modules.xml.xdm.nodes.Document;
43 import org.netbeans.modules.xml.xdm.nodes.Element;
44 import org.netbeans.modules.xml.xdm.nodes.Node;
45 import org.netbeans.modules.xml.xdm.nodes.NodeImpl;
46 import org.netbeans.modules.xml.xdm.nodes.Token;
47 import org.netbeans.modules.xml.xdm.visitor.NodeByPositionVisitor;
48 import org.netbeans.modules.xml.xdm.visitor.PathFromRootVisitor;
49 import org.netbeans.modules.xml.xdm.visitor.PositionFinderVisitor;
50 import org.netbeans.modules.xml.xdm.visitor.XPathFinder;
51 import org.w3c.dom.NamedNodeMap JavaDoc;
52
53 /**
54  *
55  * @author nn136682
56  */

57 public class XDMAccess extends DocumentModelAccess {
58     private XDMModel xdmModel;
59     private AbstractDocumentModel model;
60     private XDMListener xdmListener;
61     
62     public XDMAccess(AbstractDocumentModel model) {
63         xdmModel = new XDMModel(model.getModelSource());
64         xdmModel.setPretty(true);
65         this.model = model;
66         xdmListener = new XDMListener(this.model);
67         xdmModel.setQNameValuedAttributes(model.getQNameValuedAttributes());
68     }
69     
70     public org.w3c.dom.Document JavaDoc getDocumentRoot() {
71         return getReferenceModel().getCurrentDocument();
72     }
73     
74     public void removeUndoableEditListener(UndoableEditListener JavaDoc listener) {
75         xdmModel.removeUndoableEditListener(listener);
76     }
77     
78     public void addUndoableEditListener(UndoableEditListener JavaDoc listener) {
79         xdmModel.addUndoableEditListener(listener);
80     }
81     
82     public AbstractDocumentModel getModel() { return model; }
83     public XDMModel getReferenceModel() {
84         return xdmModel;
85     }
86     
87     public void flush() {
88         xdmModel.flush();
89     }
90     
91     public void prepareForUndoRedo() {
92         xdmListener.startSync();
93     }
94     public void finishUndoRedo() {
95         xdmListener.endSync();
96     }
97     
98     public void prepareSync() {
99         xdmModel.prepareSync();
100     }
101     
102     public DocumentModel.State sync() throws IOException JavaDoc {
103         if (model.getRootComponent() == null) {
104             xdmModel.sync();
105             if(xdmModel.getStatus() == XDMModel.Status.STABLE){
106                 Element root = Element.class.cast(xdmModel.getDocument().getDocumentElement());
107                 if (root == null) {
108                     throw new IOException JavaDoc("Cannot create model from non-XML document");
109                 }
110                 if (model.createRootComponent(root) == null) {
111                     throw new IOException JavaDoc("Cannot create model with "+
112                             new QName JavaDoc(root.getNamespaceURI(), root.getLocalName()));
113                 }
114             }
115         } else {
116             boolean error = true;
117             try {
118                 xdmListener.startSync();
119                 xdmModel.sync();
120                 error = false;
121                 xdmListener.endSync();
122             } catch(IllegalArgumentException JavaDoc ex) {
123                 IOException JavaDoc ioe = new IOException JavaDoc();
124                 ioe.initCause(ex);
125                 throw ioe;
126             } finally {
127                 if (error) {
128                     xdmListener.endSync(false);
129                 }
130             }
131         }
132         
133         return xdmModel.getStatus() == XDMModel.Status.STABLE ? DocumentModel.State.VALID : DocumentModel.State.NOT_WELL_FORMED;
134     }
135     
136     public boolean areSameNodes(org.w3c.dom.Node JavaDoc node1, org.w3c.dom.Node JavaDoc node2) {
137         if (! (node1 instanceof NodeImpl && node2 instanceof NodeImpl)) {
138             return false;
139         }
140         NodeImpl n1 = (NodeImpl) node1;
141         NodeImpl n2 = (NodeImpl) node2;
142         boolean areSameNodes = n1.isEquivalentNode(n2);
143         
144         /*
145         // keep the original fail-fast version and make additional
146         // comparisons version only for sync usage
147         if (! areSameNodes) {
148             areSameNodes = compareTokens(n1, n2);
149         }*/

150         return areSameNodes;
151     }
152     
153     /**
154      * @Returns true if both nodes have same list of tokens and attributes.
155      * Since children list are not used, only use this comparison in specific
156      * context.
157      */

158     private boolean compareTokens(NodeImpl n1, NodeImpl n2) {
159         List JavaDoc<Token> n1Tokens = n1.getTokens();
160         List JavaDoc<Token> n2Tokens = n2.getTokens();
161         if (n1Tokens.size() != n2Tokens.size()) {
162             return false;
163         }
164          
165         for( int i=0;i<n1Tokens.size();i++) {
166             if (! n1Tokens.get(i).getValue().equals(n2Tokens.get(i).getValue())) {
167                 return false;
168             }
169         }
170             
171         NamedNodeMap JavaDoc n1Attrs = n1.getAttributes();
172         NamedNodeMap JavaDoc n2Attrs = n2.getAttributes();
173         if (n1Attrs.getLength() != n2Attrs.getLength()) {
174             return false;
175         }
176
177         for(int i=0;i<n1Attrs.getLength();i++) {
178             List JavaDoc<Token> n1AttrTokens = ((NodeImpl)n1Attrs.item(i)).getTokens();
179             List JavaDoc<Token> n2AttrTokens = ((NodeImpl)n2Attrs.item(i)).getTokens();
180             if (n1AttrTokens.size() != n2AttrTokens.size()) {
181                 return false;
182             }
183              
184             for (int j=0;j<n1AttrTokens.size();j++) {
185                 if (! n1AttrTokens.get(j).getValue().equals(n2AttrTokens.get(j).getValue())) {
186                     return false;
187                 }
188             }
189         }
190         
191         return true;
192     }
193     
194     public int getElementIndexOf(org.w3c.dom.Node JavaDoc parent, org.w3c.dom.Element JavaDoc child) {
195         if (child == null) return -1;
196         int elementIndex = -1;
197         for (int i = 0; i < parent.getChildNodes().getLength(); i++) {
198             org.w3c.dom.Node JavaDoc n = parent.getChildNodes().item(i);
199             if (! (n instanceof Element)) continue;
200             elementIndex++;
201             if (areSameNodes(n, child)) {
202                 return elementIndex;
203             }
204         }
205         return -1;
206     }
207     
208     private boolean noMutations() {
209         return model.inSync() && ! model.startedFiringEvents() || model.inUndoRedo();
210     }
211     
212     public void setAttribute(org.w3c.dom.Element JavaDoc element, String JavaDoc name, String JavaDoc value, NodeUpdater updater) {
213         if (noMutations()) return;
214         if(element instanceof Node) {
215             Element xdmElem = (Element)element;
216             if(xdmElem.isInTree()) {
217                 updater.updateReference(xdmModel.setAttribute(xdmElem,name,value));
218             } else {
219                 xdmElem.setAttribute(name,value);
220             }
221         } else {
222             throw new IllegalArgumentException JavaDoc();
223         }
224     }
225     
226     public void removeAttribute(org.w3c.dom.Element JavaDoc element, String JavaDoc name, NodeUpdater updater) {
227         if (noMutations()) return;
228         if(element instanceof Node) {
229             Element xdmElem = (Element)element;
230             if(xdmElem.isInTree()) {
231                 updater.updateReference(xdmModel.removeAttribute(xdmElem,name));
232             } else {
233                 xdmElem.removeAttribute(name);
234             }
235         } else {
236             throw new IllegalArgumentException JavaDoc();
237         }
238     }
239     
240     public void appendChild(org.w3c.dom.Node JavaDoc node, org.w3c.dom.Node JavaDoc newChild, NodeUpdater updater) {
241         if (noMutations()) return;
242         if(node instanceof Node && newChild instanceof Node) {
243             Node xdmNode = (Node)node;
244             if (xdmNode.isInTree()) {
245                 updater.updateReference(xdmModel.append(xdmNode,(Node)newChild));
246             } else {
247                 xdmNode.appendChild(newChild);
248             }
249         } else {
250             throw new IllegalArgumentException JavaDoc();
251         }
252     }
253     
254     public void insertBefore(org.w3c.dom.Node JavaDoc node, org.w3c.dom.Node JavaDoc newChild, org.w3c.dom.Node JavaDoc refChild, NodeUpdater updater) {
255         if (noMutations()) return;
256         if (node instanceof Node && newChild instanceof Node && refChild instanceof Node) {
257             Node xdmNode = (Node)node;
258             if(xdmNode.isInTree()) {
259                 updater.updateReference(xdmModel.insertBefore(xdmNode,(Node)newChild,(Node)refChild));
260             } else {
261                 xdmNode.insertBefore(newChild,refChild);
262             }
263         } else {
264             throw new IllegalArgumentException JavaDoc();
265         }
266     }
267     
268     public void removeChild(org.w3c.dom.Node JavaDoc node, org.w3c.dom.Node JavaDoc child, NodeUpdater updater) {
269         if (noMutations()) return;
270         if(node instanceof Node && child instanceof Node) {
271             Node xdmNode = (Node)node;
272             if(xdmNode.isInTree()) {
273                 updater.updateReference(xdmModel.remove(xdmNode,(Node)child));
274             } else {
275                 xdmNode.removeChild(child);
276             }
277         } else {
278             throw new IllegalArgumentException JavaDoc();
279         }
280     }
281     
282     public void removeChildren(org.w3c.dom.Node JavaDoc node, Collection JavaDoc<org.w3c.dom.Node JavaDoc> children, NodeUpdater updater) {
283         if (noMutations()) return;
284         if(node instanceof Node) {
285             ArrayList JavaDoc<Node> nodes = new ArrayList JavaDoc<Node>();
286             for (org.w3c.dom.Node JavaDoc n : children) {
287                 if (n instanceof Node) {
288                     nodes.add((Node)n);
289                 } else {
290                     throw new IllegalArgumentException JavaDoc();
291                 }
292             }
293             Node xdmNode = (Node)node;
294             if(xdmNode.isInTree()) {
295                 updater.updateReference(xdmModel.removeChildNodes(xdmNode, nodes));
296             } else {
297                 for (Node child : nodes) {
298                     xdmNode.removeChild(child);
299                 }
300             }
301         } else {
302             throw new IllegalArgumentException JavaDoc();
303         }
304     }
305     
306     public void replaceChild(org.w3c.dom.Node JavaDoc node, org.w3c.dom.Node JavaDoc child, org.w3c.dom.Node JavaDoc newChild, NodeUpdater updater) {
307         if (noMutations()) return;
308         Node xdmNode = (Node)node;
309         if(xdmNode.isInTree()) {
310             updater.updateReference(xdmModel.replaceChild(xdmNode, (Node)child, (Node)newChild));
311         } else {
312             xdmNode.replaceChild(newChild, child);
313         }
314     }
315     
316     /**
317      * Replace children content with single text node having string value.
318      */

319     public void setText(org.w3c.dom.Element JavaDoc element, String JavaDoc val, NodeUpdater updater) {
320         if (noMutations()) return;
321         Element xdmElem = (Element)element;
322         if(xdmElem.isInTree()) {
323             updater.updateReference(xdmModel.setTextValue(xdmElem,val));
324         } else {
325             while(xdmElem.hasChildNodes()) {
326                 xdmElem.removeChild(xdmElem.getLastChild());
327             }
328             xdmElem.appendChild(xdmModel.getCurrentDocument().createTextNode(val));
329         }
330     }
331     
332     public String JavaDoc getXmlFragment(org.w3c.dom.Element JavaDoc element) {
333         if (element instanceof Element) {
334             Element xdmElem = (Element)element;
335             return xdmElem.getXmlFragmentText();
336         } else {
337             throw new IllegalArgumentException JavaDoc();
338         }
339     }
340     
341     /**
342      * Replace element children with result from parsing of given xml fragment text.
343      */

344     public void setXmlFragment(org.w3c.dom.Element JavaDoc element, String JavaDoc val, NodeUpdater updater) throws IOException JavaDoc {
345         if (noMutations()) return;
346         Element xdmElem = (Element)element;
347         if(xdmElem.isInTree()) {
348             updater.updateReference(xdmModel.setXmlFragmentText(xdmElem, val));
349         } else {
350             xdmElem.setXmlFragmentText(val);
351         }
352     }
353     
354     public void setPrefix(org.w3c.dom.Element JavaDoc element, String JavaDoc prefix) {
355         if (noMutations()) return;
356         Element xdmElement = (Element)element;
357         if (! xdmElement.isInTree()) {
358             xdmElement.setPrefix(prefix);
359         }
360     }
361     
362     public int findPosition(org.w3c.dom.Node JavaDoc node){
363         return (new PositionFinderVisitor()).findPosition(xdmModel.getDocument(), (Node)node);
364     }
365     
366     public Element getContainingElement(int position){
367         return (new NodeByPositionVisitor(xdmModel.getDocument())).getContainingElement(position);
368     }
369     
370     public org.w3c.dom.Element JavaDoc duplicate(org.w3c.dom.Element JavaDoc element){
371         return (org.w3c.dom.Element JavaDoc) ((Element)element).copy();
372     }
373     
374     public Map JavaDoc<QName JavaDoc,String JavaDoc> getAttributeMap(org.w3c.dom.Element JavaDoc element) {
375         Map JavaDoc<QName JavaDoc,String JavaDoc> qValues = new AttributeMap<QName JavaDoc,String JavaDoc>();
376         NamedNodeMap JavaDoc attributes = element.getAttributes();
377         for (int i=0; i<attributes.getLength(); i++) {
378             Attribute attr = (Attribute) attributes.item(i);
379             if (attr.isXmlnsAttribute()) {
380                 continue;
381             }
382             QName JavaDoc q = AbstractDocumentComponent.getQName(attr);
383             ((AttributeMap)qValues).addKey(q);
384             qValues.put(q, attr.getValue());
385         }
386         return qValues;
387     }
388     
389     public List JavaDoc<org.w3c.dom.Element JavaDoc> getPathFromRoot(org.w3c.dom.Document JavaDoc root, org.w3c.dom.Element JavaDoc node) {
390         List JavaDoc<Node> pathToRoot = new PathFromRootVisitor().findPath(root, node);
391         List JavaDoc<org.w3c.dom.Element JavaDoc> pathFromRoot = new ArrayList JavaDoc<org.w3c.dom.Element JavaDoc>();
392         for (Node n : pathToRoot) {
393             if (! (n instanceof Element)) {
394                 break;
395             }
396             pathFromRoot.add(0, (Element) n);
397         }
398         return pathFromRoot;
399     }
400     
401     public String JavaDoc getXPath(org.w3c.dom.Document JavaDoc root, org.w3c.dom.Element JavaDoc node) {
402         return XPathFinder.getXpath((Document)root, (Node)node);
403     }
404     
405     public org.w3c.dom.Node JavaDoc findNode(org.w3c.dom.Document JavaDoc root, String JavaDoc xpath) {
406         return new XPathFinder().findNode((Document)root, xpath);
407     }
408     
409     public List JavaDoc<org.w3c.dom.Node JavaDoc> findNodes(org.w3c.dom.Document JavaDoc root, String JavaDoc xpath) {
410         return XDMListener.toDomNodes(new XPathFinder().findNodes((Document)root, xpath));
411     }
412     
413     public XDMModel getXDMModel() {
414         return xdmModel;
415     }
416     
417     public ElementIdentity getElementIdentity() {
418         return getXDMModel().getElementIdentity();
419     }
420
421     public void addMergeEventHandler(PropertyChangeListener JavaDoc l) {
422         xdmModel.addPropertyChangeListener(l);
423     }
424
425     public void removeMergeEventHandler(PropertyChangeListener JavaDoc l) {
426         xdmModel.removePropertyChangeListener(l);
427     }
428
429     public org.w3c.dom.Node JavaDoc getOldEventParentNode(PropertyChangeEvent JavaDoc event) {
430         NodeInfo oldInfo = (NodeInfo) event.getOldValue();
431         return oldInfo!=null?(Node) oldInfo.getParent():null;
432     }
433
434     public org.w3c.dom.Node JavaDoc getOldEventNode(PropertyChangeEvent JavaDoc event) {
435         NodeInfo oldInfo = (NodeInfo) event.getOldValue();
436         return oldInfo!=null?(Node) oldInfo.getNode():null;
437     }
438
439     public org.w3c.dom.Node JavaDoc getNewEventParentNode(PropertyChangeEvent JavaDoc event) {
440         NodeInfo newInfo = (NodeInfo) event.getNewValue();
441         return newInfo!=null?(Node) newInfo.getParent():null;
442     }
443
444     public org.w3c.dom.Node JavaDoc getNewEventNode(PropertyChangeEvent JavaDoc event) {
445         NodeInfo newInfo = (NodeInfo) event.getNewValue();
446         return newInfo!=null?(Node) newInfo.getNode():null;
447     }
448
449     public String JavaDoc getIndentation(){
450         return xdmModel.getIndentation();
451     }
452     
453     public void setIndentation(String JavaDoc indentation){
454         xdmModel.setIndentation(indentation);
455     }
456
457     // To fix the attribute order issue when using getAttributeMap().keySet().iterator()
458
public class AttributeMap<K,V> extends HashMap JavaDoc<K,V> {
459         List JavaDoc<K> keys = new ArrayList JavaDoc<K>();
460         public AttributeKeySet<K> keySet() {
461             return new AttributeKeySet(keys);
462         }
463
464         private void addKey(K q) {
465             keys.add(q);
466         }
467     }
468     
469     public class AttributeKeySet<E> extends HashSet JavaDoc<E> {
470         List JavaDoc<E> keys = new ArrayList JavaDoc<E>();
471         
472         public AttributeKeySet(List JavaDoc<E> keys) {
473             this.keys = keys;
474         }
475
476         public boolean isEmpty() {
477             return keys.isEmpty();
478         }
479         
480         public boolean contains(Object JavaDoc key) {
481             return keys.contains(key);
482         }
483     
484         public Iterator JavaDoc iterator() {
485             return keys.iterator();
486         }
487         
488         public int size() {
489             return keys.size();
490         }
491     }
492 }
493
Popular Tags