KickJava   Java API By Example, From Geeks To Geeks.

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


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.HashMap JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29 import org.netbeans.modules.xml.xam.Component;
30 import org.netbeans.modules.xml.xam.Model;
31 import org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent;
32 import org.netbeans.modules.xml.xam.dom.AbstractDocumentModel;
33 import org.netbeans.modules.xml.xam.dom.ChangeInfo;
34 import org.netbeans.modules.xml.xam.dom.DocumentComponent;
35 import org.netbeans.modules.xml.xam.dom.SyncUnit;
36 import org.netbeans.modules.xml.xdm.XDMModel;
37 import org.netbeans.modules.xml.xdm.diff.NodeInfo;
38 import org.netbeans.modules.xml.xdm.nodes.Node;
39 import org.netbeans.modules.xml.xdm.nodes.Element;
40 import org.netbeans.modules.xml.xdm.nodes.Document;
41
42 /**
43  * @author Nam Nguyen
44  * @author ajit
45  */

46 public class XDMListener implements PropertyChangeListener JavaDoc {
47     
48     private AbstractDocumentModel model;
49     private boolean inSync;
50     private Document oldDocument;
51     
52     /** Creates a new instance of XDMListener */
53     public XDMListener(AbstractDocumentModel model) {
54         this.model = model;
55     }
56     
57     private XDMModel getXDMModel() {
58         return ((XDMAccess) model.getAccess()).getXDMModel();
59     }
60     
61     void startSync() {
62         inSync = true;
63         syncUnits.clear();
64         oldDocument = getXDMModel().getCurrentDocument();
65         getXDMModel().addPropertyChangeListener(this);
66     }
67     
68     Document getOldDocument() {
69         return oldDocument;
70     }
71     
72     void endSync() {
73         endSync(true);
74     }
75     
76     void endSync(boolean processing) {
77         getXDMModel().removePropertyChangeListener(this);
78         try {
79             if (processing) {
80                 for (SyncUnit unit : syncUnits.values()) {
81                     model.processSyncUnit(unit);
82                 }
83             }
84         } finally {
85             syncUnits.clear();
86             inSync = false;
87         }
88     }
89     
90     private Map JavaDoc<Integer JavaDoc, SyncUnit> syncUnits = new HashMap JavaDoc<Integer JavaDoc, SyncUnit>();
91     private static Integer JavaDoc getID(ChangeInfo change) {
92         if (change.getParent() == null) {
93             return Integer.valueOf(0);
94         } else {
95             Element parent = (Element) change.getParent();
96             return Integer.valueOf(parent.getId());
97         }
98     }
99     private static Integer JavaDoc getID(DocumentComponent c) {
100         if (c == null) {
101             return Integer.valueOf(0);
102         }
103         Element xdmElement = (Element) ((AbstractDocumentComponent)c).getPeer();
104         return Integer.valueOf(xdmElement.getId());
105     }
106     
107     protected void processChange(ChangeInfo change) {
108         Integer JavaDoc unitID = getID(change);
109         SyncUnit existing = syncUnits.get(unitID);
110         SyncUnit su = model.prepareSyncUnit(change, existing);
111         if (su == null) {
112             return;
113         }
114         Integer JavaDoc reviewedID = getID(su.getTarget());
115         existing = syncUnits.get(reviewedID);
116         if (existing == null) {
117             if (unitID.equals(reviewedID)) {
118                 // normal new sync order
119
syncUnits.put(reviewedID, su);
120             } else {
121                 existing = syncUnits.get(reviewedID);
122                 if (existing != null) {
123                     existing.merge(su);
124                 } else {
125                     syncUnits.put(reviewedID, su);
126                 }
127             }
128         } else {
129             if (existing != su) {
130                 if (unitID.equals(reviewedID)) {
131                     existing.merge(su);
132                 } else {
133                     // existing sync unit replaced by reviewed one on ancestor of original target
134
syncUnits.remove(unitID);
135                     existing = syncUnits.get(reviewedID);
136                     if (existing != null) {
137                         existing.merge(su);
138                     } else {
139                         syncUnits.put(reviewedID, su);
140                     }
141                 }
142             }
143         }
144     }
145
146     protected void processEvent(Node eventNode, List JavaDoc<Node> pathToRoot, boolean isAdded) {
147         if (pathToRoot.size() == 1) {
148             assert pathToRoot.get(0) instanceof Document;
149             if (! (eventNode instanceof Element)) {
150                 return;
151             }
152             //assert eventNode.getId() == 1;
153
if (! isAdded) {
154                 return;
155             }
156             Component rootComponent = null;
157             String JavaDoc errorMessage = null;
158             try {
159                 rootComponent = model.createRootComponent((Element) eventNode);
160             } catch(IllegalArgumentException JavaDoc e) {
161                 errorMessage = e.getMessage();
162             }
163             if (rootComponent == null) {
164                 errorMessage = errorMessage != null ? errorMessage :
165                     "Unexpected root element "+AbstractDocumentComponent.getQName(eventNode);
166                 throw new IllegalArgumentException JavaDoc(new IOException JavaDoc(errorMessage));
167             }
168             model.firePropertyChangeEvent(new PropertyChangeEvent JavaDoc(model,
169                 Model.STATE_PROPERTY, Model.State.NOT_SYNCED, Model.State.VALID));
170         } else {
171             if (eventNode.getId() == pathToRoot.get(0).getId()) {
172                 throw new IllegalArgumentException JavaDoc("Event node has same id as parent");
173             }
174             pathToRoot = new ArrayList JavaDoc(pathToRoot);
175             pathToRoot.add(0, eventNode);
176             ChangeInfo change = model.prepareChangeInfo(toDomNodes(pathToRoot));
177             change.setAdded(isAdded);
178             processChange(change);
179         }
180     }
181     
182     public void propertyChange(PropertyChangeEvent JavaDoc event) {
183         if (!inSync) return;
184         
185         NodeInfo oldInfo = (NodeInfo) event.getOldValue();
186         NodeInfo newInfo = (NodeInfo) event.getNewValue();
187         
188         Node old = oldInfo!=null?(Node) oldInfo.getNode():null;
189         Node now = newInfo!=null?(Node) newInfo.getNode():null;
190         
191         if (old != null) {
192             processEvent(old, oldInfo.getNewAncestors(), false);
193         }
194         
195         if (now != null) {
196             processEvent(now, newInfo.getNewAncestors(), true);
197         }
198     }
199
200     static List JavaDoc<org.w3c.dom.Node JavaDoc> toDomNodes(List JavaDoc<Node> nodes) {
201         List JavaDoc<org.w3c.dom.Node JavaDoc> domNodes = new ArrayList JavaDoc<org.w3c.dom.Node JavaDoc>();
202         for (Node n : nodes) {
203             domNodes.add((org.w3c.dom.Node JavaDoc) n);
204         }
205         return domNodes;
206     }
207 }
208
209
Popular Tags