KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > xam > AbstractModelFactory


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.xam;
21
22 import java.beans.PropertyChangeListener JavaDoc;
23 import java.beans.PropertyChangeSupport JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.lang.ref.WeakReference JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.WeakHashMap JavaDoc;
30 import java.util.logging.Level JavaDoc;
31 import java.util.logging.Logger JavaDoc;
32 import org.netbeans.modules.xml.xam.spi.ModelAccessProvider;
33 import org.openide.util.Lookup;
34 import org.openide.util.RequestProcessor;
35
36 /**
37  *
38  * @author Chris Webster
39  * @author Nam Nguyen
40  */

41 public abstract class AbstractModelFactory<M extends Model> {
42     public AbstractModelFactory() {
43         factories.add(new WeakReference JavaDoc<AbstractModelFactory>(this));
44         propSupport = new PropertyChangeSupport JavaDoc(this);
45     }
46     
47     public static final int DELAY_SYNCER = 2000; // milisecs.
48
public static final int DELAY_DIRTY = 1000; // milisecs.
49

50     public static final String JavaDoc MODEL_LOADED_PROPERTY = "modelLoaded";
51
52     private WeakHashMap JavaDoc<Object JavaDoc, WeakReference JavaDoc<M>> cachedModels =
53     new WeakHashMap JavaDoc<Object JavaDoc,WeakReference JavaDoc<M>>();
54     private PropertyChangeSupport JavaDoc propSupport;
55     
56     protected abstract M createModel(ModelSource source);
57     
58
59     /**
60      * Create new model from given model source; returns null if there are errors
61      * during creation.
62      *
63      * Note that, the returned model might not be valid, i.e., source is well-formed.
64      * Also, that the returned model is not cached and does not have background
65      * auto-sync support.
66      */

67     public M createFreshModel(ModelSource modelSource) {
68         M model = createModel(modelSource);
69         try {
70             if (model != null) {
71                 model.sync();
72                 propSupport.firePropertyChange(MODEL_LOADED_PROPERTY, null, model);
73             }
74         } catch (IOException JavaDoc ioe) {
75             Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Sync has errors", ioe);
76         }
77         return model;
78     }
79     
80     /**
81      * This method extracts the key from the model source. A subclass can
82      * change the ModelSource lookup requirements and thus this method may
83      * be overridden to allow a different key to be used.
84      */

85     protected Object JavaDoc getKey(ModelSource source) {
86         ModelAccessProvider p = getEffectiveAccessProvider(source);
87         if (p != null) {
88             return p.getModelSourceKey(source);
89         }
90     return (File JavaDoc) source.getLookup().lookup(File JavaDoc.class);
91     }
92     
93     private ModelAccessProvider getEffectiveAccessProvider(ModelSource ms) {
94     ModelAccessProvider p = (ModelAccessProvider)
95         ms.getLookup().lookup(ModelAccessProvider.class);
96     return p == null ? getAccessProvider() : p;
97     }
98     
99     public static ModelAccessProvider getAccessProvider() {
100         return (ModelAccessProvider) Lookup.getDefault().lookup(ModelAccessProvider.class);
101     }
102     
103     protected synchronized M getModel(ModelSource source) {
104         if (source == null) {
105             return null;
106         }
107     Object JavaDoc key = getKey(source);
108     assert key != null;
109         WeakReference JavaDoc<M> modelRef = cachedModels.get(key);
110         M model = (modelRef == null ? null : modelRef.get());
111         if (model == null) {
112             model = createModel(source);
113             if (model != null) {
114                 try {
115                     model.sync();
116                 } catch (IOException JavaDoc ioe) {
117                     Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Sync has errors", ioe);
118                 }
119                 cachedModels.put(key, new WeakReference JavaDoc<M>(model));
120                 propSupport.firePropertyChange(MODEL_LOADED_PROPERTY, null, model);
121             }
122         }
123         return model;
124     }
125
126     private static List JavaDoc<WeakReference JavaDoc<AbstractModelFactory>> factories =
127             new ArrayList JavaDoc<WeakReference JavaDoc<AbstractModelFactory>>();
128     
129     private static RequestProcessor.Task SYNCER = null;
130     static {
131         if (getAccessProvider() != null) {
132             SYNCER = RequestProcessor.getDefault().post(
133                 new Runnable JavaDoc() {
134                     public void run() {
135                         try {
136                             for (AbstractModel model : getAllModels()) {
137                                 if (model.isAutoSyncActive() &&
138                                     model.getAccess().dirtyIntervalMillis() > DELAY_DIRTY) {
139                                     model.runAutoSync();
140                                 }
141                             }
142                         } catch (Exception JavaDoc e) {
143                             Logger.getLogger(getClass().getName()).log(Level.FINE, "auto-sync", e);
144                         }
145                         SYNCER.schedule(DELAY_SYNCER);
146                     }
147                 }, DELAY_SYNCER);
148         }
149     }
150     
151     private synchronized static List JavaDoc<AbstractModel> getAllModels() {
152         List JavaDoc<AbstractModel> models = new ArrayList JavaDoc<AbstractModel>();
153         List JavaDoc<WeakReference JavaDoc<AbstractModelFactory>> mfactories =
154             new ArrayList JavaDoc<WeakReference JavaDoc<AbstractModelFactory>>(factories);
155         
156         for (WeakReference JavaDoc<AbstractModelFactory> r : mfactories) {
157             AbstractModelFactory factory = r.get();
158             if (factory != null) {
159                 for (Object JavaDoc m : factory.getModels()) {
160                     if (m instanceof AbstractModel) {
161                         AbstractModel am = (AbstractModel) m;
162                         models.add(am);
163                     }
164                 }
165             }
166         }
167         return models;
168     }
169     
170     /**
171      * Returns list of models currently cached by the factory.
172      */

173     public List JavaDoc<M> getModels() {
174         List JavaDoc<WeakReference JavaDoc<M>> refs;
175         synchronized(this) {
176             refs = new ArrayList JavaDoc<WeakReference JavaDoc<M>>(cachedModels.values());
177         }
178
179         List JavaDoc<M> ret = new ArrayList JavaDoc<M>();
180         for (WeakReference JavaDoc<M> ref : refs) {
181             if (ref != null) {
182                 M model = ref.get();
183                 if (model != null) {
184                     ret.add(model);
185                 }
186             }
187         }
188         return ret;
189     }
190     
191     /**
192      * Adds property change listener on the factory to be notified on
193      * when new models are loaded by the factory.
194      */

195     public void addPropertyChangeListener(PropertyChangeListener JavaDoc l) {
196         propSupport.addPropertyChangeListener(l);
197     }
198
199     /**
200      * Removes property change listener.
201      */

202     public void removePropertyChangeListener(PropertyChangeListener JavaDoc l) {
203         propSupport.removePropertyChangeListener(l);
204     }
205 }
206
207
Popular Tags