KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > axi > impl > AXIModelImpl


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.xml.axi.impl;
20
21 import java.io.IOException JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.WeakHashMap JavaDoc;
29 import org.netbeans.modules.xml.axi.AXIComponent;
30 import org.netbeans.modules.xml.axi.AXIDocument;
31 import org.netbeans.modules.xml.axi.AXIModel;
32 import org.netbeans.modules.xml.axi.AXIModelFactory;
33 import org.netbeans.modules.xml.axi.SchemaGenerator;
34 import org.netbeans.modules.xml.schema.model.Schema;
35 import org.netbeans.modules.xml.schema.model.SchemaComponent;
36 import org.netbeans.modules.xml.schema.model.SchemaModel;
37 import org.netbeans.modules.xml.schema.model.SchemaModelReference;
38 import org.netbeans.modules.xml.xam.ComponentListener;
39 import org.netbeans.modules.xml.xam.Model;
40 import org.netbeans.modules.xml.xam.ModelSource;
41 import org.netbeans.modules.xml.xam.NamedReferenceable;
42 import org.netbeans.modules.xml.xam.dom.NamedComponentReference;
43 import org.netbeans.modules.xml.xam.locator.CatalogModelException;
44 import org.netbeans.modules.xml.xam.spi.Validation;
45 import org.netbeans.modules.xml.xam.spi.Validator.ResultItem;
46 import org.netbeans.modules.xml.xam.spi.Validator.ResultType;
47 import org.openide.util.WeakListeners;
48
49
50 /**
51  * Represents an AXI model for a schema.
52  * It keeps a map of AXI elements against schema global elements.
53  *
54  * @author Samaresh (Samaresh.Panda@Sun.Com)
55  */

56 public class AXIModelImpl extends AXIModel {
57             
58     /**
59      * Creates a new instance AXIModelImpl.
60      */

61     public AXIModelImpl(ModelSource modelSource) {
62         super(modelSource);
63         
64         //create and add listener to listen to this model changes
65
this.propertyListener = new AXIModelListener();
66         addPropertyChangeListener(propertyListener);
67         
68         //create and add listener to listen to schema model changes
69
this.schemaModelListener = new SchemaModelListener(this);
70         this.getSchemaModel().addPropertyChangeListener(schemaModelListener);
71     }
72     
73     /**
74      * Returns true if the AXIDocument has been initialized, false otherwise.
75      */

76     boolean isAXIDocumentInitialized() {
77         return isAXIDocumentInitialized;
78     }
79     
80     /**
81      * Initializes AXIDocument.
82      */

83     void initializeAXIDocument() {
84         AXIDocument doc = getRoot();
85         Schema schema = (Schema)doc.getPeer();
86         if(schema == null) {
87             doc.setPeer(getSchemaModel().getSchema());
88         }
89         Util.updateAXIDocument(doc);
90         isAXIDocumentInitialized = true;
91                 
92         //initialize schema design pattern
93
SchemaGenerator.Pattern dp = null;
94         if(dp != null)
95             setSchemaDesignPattern(dp);
96         else
97             setSchemaDesignPattern(SchemaGenerator.DEFAULT_DESIGN_PATTERN);
98     }
99
100     /**
101      * Retunrs true if the specified schema component and this AXI model
102      * belong to the same schema model. False otherwise.
103      */

104     public boolean fromSameSchemaModel(SchemaComponent schemaComponent) {
105         return (getSchemaModel() == schemaComponent.getModel());
106     }
107         
108     /**
109      * Returns the global AXI component from other AXI model.
110      */

111     public AXIComponent lookupFromOtherModel(SchemaComponent schemaComponent) {
112         if(!schemaComponent.isInDocumentModel())
113             return null;
114         AXIModelFactory factory = AXIModelFactory.getDefault();
115         AXIModelImpl model = (AXIModelImpl)factory.getModel(schemaComponent.getModel());
116         return model!=null?model.lookup(schemaComponent):null;
117     }
118     
119     /**
120      * Returns the global AXI component against the specified global schema component.
121      */

122     public AXIComponent lookup(SchemaComponent schemaComponent) {
123         return ((AXIDocumentImpl)getRoot()).findChild(schemaComponent);
124     }
125         
126     /**
127      * Check if sync is really required or not. True for the very first time.
128      * Returns false, if user started a design pattern transformation or if the
129      * model was mutated inside a transaction. Else, true if the listeners have
130      * accumulated events.
131      */

132     protected boolean needsSync() {
133         if(isForceSync)
134             return true;
135         if(!isAXIDocumentInitialized())
136             return true;
137         
138         if(designPatternMode || isIntransaction()) {
139             return false;
140         }
141         
142         if(axiModelListener != null)
143            return axiModelListener.needsSync() || schemaModelListener.needsSync();
144         
145         return schemaModelListener.needsSync();
146     }
147         
148     void disableAutoSync() {
149         designPatternMode = true;
150         super.getAccess().setAutoSync(false);
151     }
152     
153     void enableAutoSync() {
154         designPatternMode = false;
155         super.getAccess().setAutoSync(true);
156     }
157     
158     /**
159      * Sync started.
160      */

161     protected void syncStarted() {
162         try {
163             getSchemaModel().sync();
164         } catch(IOException JavaDoc ex) {
165             setState(Model.State.NOT_SYNCED);
166         }
167     }
168     
169     /**
170      * Finished sync. Clear the event lists.
171      */

172     protected void syncCompleted() {
173         schemaModelListener.syncCompleted();
174         if(axiModelListener != null)
175             axiModelListener.syncCompleted();
176         propertyListener.clearEvents();
177     }
178     
179     /**
180      * Overwrite sync.
181      */

182     public void sync() {
183         try {
184             synchronized(getSchemaModel()) {
185                 super.sync();
186             }
187         } catch(IOException JavaDoc ex) {
188             setState(Model.State.NOT_SYNCED);
189         } finally {
190             setForceSync(false);
191         }
192     }
193
194     /**
195      * This is where the actual sync starts.
196      * Returns true if success, false if failed.
197      */

198     public synchronized boolean doSync() {
199         //finally sync itself.
200
AXIModelUpdater updater = new AXIModelUpdater(this);
201         return updater.doSync();
202     }
203     
204     public SchemaGenerator.Pattern getSchemaDesignPattern() {
205         return schemaDesignPattern;
206     }
207     
208     public void setSchemaDesignPattern(SchemaGenerator.Pattern schemaDesignPattern) {
209         this.schemaDesignPattern = schemaDesignPattern;
210     }
211     
212     /**
213      * Returns the PCL who listens to this model changes.
214      */

215     public AXIModelListener getPropertyChangeListener() {
216         return propertyListener;
217     }
218     
219     /**
220      * Runs the validator to see if the schema is valid or not.
221      * Returns true for a valid schema, false otherwise.
222      */

223     public boolean validate() {
224         Model.State state = getSchemaModel().getState();
225         if(state != SchemaModel.State.VALID) {
226             return false;
227         }
228         
229         return true;
230     }
231     
232     public List JavaDoc<AXIModel> getReferencedModels() {
233         List JavaDoc<AXIModel> models = Collections.emptyList();
234         Schema schema = getSchemaModel().getSchema();
235         if(schema == null)
236             return models;
237         Collection JavaDoc<SchemaModelReference> refs = schema.getSchemaReferences();
238         if(refs == null || refs.size() == 0) {
239             return models;
240         }
241         models = new ArrayList JavaDoc<AXIModel>();
242         Iterator JavaDoc<SchemaModelReference> iter = refs.iterator();
243         while(iter.hasNext()) {
244             try {
245                 SchemaModelReference ref = iter.next();
246                 Schema s = ref.resolveReferencedModel().getSchema();
247                 AXIModel m = AXIModelFactory.getDefault().
248                         getModel(ref.resolveReferencedModel());
249                 models.add(m);
250             } catch (CatalogModelException ex) {
251                 //will not be added to the list
252
}
253         }
254
255         return Collections.unmodifiableList(models);
256     }
257             
258     /**
259      * Builds referenceable cache and listens to appropriate
260      * referenced models. This gets updated in each sync.
261      */

262     void buildReferenceableCache() {
263         listenerMap.clear();
264         Schema schema = getSchemaModel().getSchema();
265         if(schema == null)
266             return;
267         buildCache(schema);
268         Collection JavaDoc<SchemaModelReference> refs = schema.getSchemaReferences();
269         if(refs == null || refs.size() == 0)
270             return;
271         Iterator JavaDoc<SchemaModelReference> iter = refs.iterator();
272         while(iter.hasNext()) {
273             try {
274                 SchemaModelReference ref = iter.next();
275                 Schema s = ref.resolveReferencedModel().getSchema();
276                 buildCache(s);
277                 if(getRoot().canVisitChildren()) {
278                     AXIModel m = AXIModelFactory.getDefault().
279                             getModel(ref.resolveReferencedModel());
280                     //listen to other model, only if
281
//the doc was expanded earlier.
282
listenToReferencedModel(m);
283                 }
284             } catch (Exception JavaDoc ex) {
285                 continue;
286             }
287         }
288     }
289
290     public void listenToReferencedModel(AXIModel model) {
291         if(listenerMap.get(model) == null) {
292             ComponentListener listener = (ComponentListener)WeakListeners.
293                     create(ComponentListener.class, axiModelListener, model);
294             model.addComponentListener(listener);
295             listenerMap.put(model, listener);
296         }
297     }
298        
299     /**
300      * Updates the cache of all referenceable for a given schema file.
301      * Note: the key in the map is namespace:name.
302      */

303     private void buildCache(Schema schema) {
304         for(SchemaComponent child : schema.getChildren()) {
305             if(child instanceof NamedReferenceable) {
306                 NamedReferenceable ref = (NamedReferenceable)child;
307                 mapReferenceable.put(schema.getTargetNamespace() + ":" + ref.getName(), ref);
308             }
309         }
310     }
311     
312     /**
313      * Fetches an item from the cache of all referenceable.
314      * Note: the key in the map is namespace:name.
315      */

316     public SchemaComponent getReferenceableSchemaComponent(NamedComponentReference ncr) {
317         String JavaDoc name = ncr.getQName().getNamespaceURI() + ":" + ncr.getQName().getLocalPart();
318         Class JavaDoc<? extends NamedReferenceable> elementType = ncr.getType();
319         NamedReferenceable ref = mapReferenceable.get(name);
320         if(ref != null && elementType.isAssignableFrom(ref.getClass())) {
321             return (SchemaComponent)ref;
322         }
323         
324         return (SchemaComponent)ncr.get();
325     }
326         
327     public String JavaDoc toString() {
328         if(getRoot() == null)
329             return null;
330         
331         return getRoot().getTargetNamespace();
332     }
333
334     public void setForceSync(boolean b) {
335         isForceSync = b;
336     }
337
338     /**
339      * PCL to be used by code generator.
340      */

341     private AXIModelListener propertyListener;
342     
343     /*
344      * Schema model listener.
345      */

346     private SchemaModelListener schemaModelListener;
347
348     /*
349      * AXI Model listener to listen to other AXI models.
350      */

351     private OtherAXIModelListener axiModelListener = new OtherAXIModelListener(this);
352     private WeakHashMap JavaDoc<AXIModel, ComponentListener> listenerMap =
353             new WeakHashMap JavaDoc<AXIModel, ComponentListener>();
354         
355     /*
356      * True, when design patten transformation is being carried out.
357      */

358     private boolean designPatternMode = false;
359         
360     /*
361      * Flag to indicate if the AXIDocument was initialized or no.
362      */

363     private boolean isAXIDocumentInitialized = false;
364
365     private SchemaGenerator.Pattern schemaDesignPattern;
366     private HashMap JavaDoc<String JavaDoc, NamedReferenceable> mapReferenceable =
367             new HashMap JavaDoc<String JavaDoc, NamedReferenceable>();
368
369     private boolean isForceSync = false;
370 }
371
Popular Tags