1 19 20 package org.netbeans.modules.xml.xam; 21 22 import java.beans.PropertyChangeListener ; 23 import java.beans.PropertyChangeSupport ; 24 import java.io.File ; 25 import java.io.IOException ; 26 import java.lang.ref.WeakReference ; 27 import java.util.ArrayList ; 28 import java.util.List ; 29 import java.util.WeakHashMap ; 30 import java.util.logging.Level ; 31 import java.util.logging.Logger ; 32 import org.netbeans.modules.xml.xam.spi.ModelAccessProvider; 33 import org.openide.util.Lookup; 34 import org.openide.util.RequestProcessor; 35 36 41 public abstract class AbstractModelFactory<M extends Model> { 42 public AbstractModelFactory() { 43 factories.add(new WeakReference <AbstractModelFactory>(this)); 44 propSupport = new PropertyChangeSupport (this); 45 } 46 47 public static final int DELAY_SYNCER = 2000; public static final int DELAY_DIRTY = 1000; 50 public static final String MODEL_LOADED_PROPERTY = "modelLoaded"; 51 52 private WeakHashMap <Object , WeakReference <M>> cachedModels = 53 new WeakHashMap <Object ,WeakReference <M>>(); 54 private PropertyChangeSupport propSupport; 55 56 protected abstract M createModel(ModelSource source); 57 58 59 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 ioe) { 75 Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Sync has errors", ioe); 76 } 77 return model; 78 } 79 80 85 protected Object getKey(ModelSource source) { 86 ModelAccessProvider p = getEffectiveAccessProvider(source); 87 if (p != null) { 88 return p.getModelSourceKey(source); 89 } 90 return (File ) source.getLookup().lookup(File .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 key = getKey(source); 108 assert key != null; 109 WeakReference <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 ioe) { 117 Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Sync has errors", ioe); 118 } 119 cachedModels.put(key, new WeakReference <M>(model)); 120 propSupport.firePropertyChange(MODEL_LOADED_PROPERTY, null, model); 121 } 122 } 123 return model; 124 } 125 126 private static List <WeakReference <AbstractModelFactory>> factories = 127 new ArrayList <WeakReference <AbstractModelFactory>>(); 128 129 private static RequestProcessor.Task SYNCER = null; 130 static { 131 if (getAccessProvider() != null) { 132 SYNCER = RequestProcessor.getDefault().post( 133 new Runnable () { 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 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 <AbstractModel> getAllModels() { 152 List <AbstractModel> models = new ArrayList <AbstractModel>(); 153 List <WeakReference <AbstractModelFactory>> mfactories = 154 new ArrayList <WeakReference <AbstractModelFactory>>(factories); 155 156 for (WeakReference <AbstractModelFactory> r : mfactories) { 157 AbstractModelFactory factory = r.get(); 158 if (factory != null) { 159 for (Object 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 173 public List <M> getModels() { 174 List <WeakReference <M>> refs; 175 synchronized(this) { 176 refs = new ArrayList <WeakReference <M>>(cachedModels.values()); 177 } 178 179 List <M> ret = new ArrayList <M>(); 180 for (WeakReference <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 195 public void addPropertyChangeListener(PropertyChangeListener l) { 196 propSupport.addPropertyChangeListener(l); 197 } 198 199 202 public void removePropertyChangeListener(PropertyChangeListener l) { 203 propSupport.removePropertyChangeListener(l); 204 } 205 } 206 207 | Popular Tags |