00001
00065 package com.arcle.rmt.j2se.model.domimpl;
00066
00067 import java.util.WeakHashMap;
00068 import java.util.Hashtable;
00069 import java.util.Map;
00070 import java.util.Observer;
00071 import java.util.Observable;
00072 import org.w3c.dom.Element;
00073 import com.arcle.rmt.rqml.*;
00074 import com.arcle.rmt.j2se.model.domimpl.rqml.*;
00075 import com.arcle.rmt.j2se.util.CounterMap;
00076 import com.arcle.rmt.j2se.util.StringUtilities;
00077
00091 public class AdapterCacheFlyweight implements RQMLSecondClassFactory {
00092
00098 public AdapterCacheFlyweight(Observer elementObserver) {
00099 if (elementObserver == null) {
00100 throw new IllegalArgumentException(
00101 "Parameter 'elementObserver' cannot be null.");
00102 }
00103 _elementObserver = elementObserver;
00104 }
00105
00114 public RQMLSecondClass createRQMLSecondClass(Element elem) {
00115 RQMLSecondClass rqml = (RQMLSecondClass) getCache().get(elem);
00116 if (rqml == null) {
00117 RQMLSecondClassFactory fac = getElementFactory(elem.getNodeName());
00118 if (fac == null) {
00119 throw new UnsupportedOperationException(
00120 "Factory not found for element: " + elem.getNodeName());
00121 }
00122 rqml = fac.createRQMLSecondClass(elem);
00123 assignID(rqml);
00124 addObservable(rqml);
00125 getCache().put(elem, rqml);
00126 }
00127 return rqml;
00128 }
00129
00133 public boolean remove(Element elem) {
00134 Object rqml = getCache().get(elem);
00135 if (rqml instanceof ElementAdapter) {
00136 ElementAdapter ea = (ElementAdapter) rqml;
00137
00138
00139 ea.deleteElement();
00140 }
00141 return getCache().remove(elem) != null;
00142 }
00143
00144
00145 protected boolean addObservable(Object o) {
00146 if (o instanceof Observable) {
00147 Observable obs = (Observable) o;
00148 obs.addObserver(getElementObserver());
00149 return true;
00150 }
00151 return false;
00152 }
00153
00162 protected void assignID(RQMLSecondClass elem) {
00163 String id = elem.getID();
00164 String name = ((RQMLSecondClassImpl) elem).getElementName();
00165 String stripped = StringUtilities.stripAllExceptConsonantsOrFirstChar(name);
00166 int endIndex = Math.min(NAME_PREFIX_LEN, stripped.length());
00167 String prefix = stripped.substring(0, endIndex);
00168
00169
00170
00171
00172
00173
00174
00175 int idValue = getElementIDGenerator().incrementCounter(prefix);
00176 if (id.length() == 0) {
00177 id = prefix + "-" + idValue;
00178 elem.setID(id);
00179 }
00180 }
00181
00182
00183
00184
00185
00192 protected Map getCache() {
00193 if (_cache == null) {
00194 _cache = createCache();
00195 }
00196 return _cache;
00197 }
00198
00205 protected RQMLSecondClassFactory getElementFactory(String elementName) {
00206 if (_elementFactories == null) {
00207 _elementFactories = createElementFactories();
00208 }
00209 return _elementFactories.getFactory(elementName);
00210 }
00211
00216 protected Observer getElementObserver() {
00217 return _elementObserver;
00218 }
00219
00223 protected CounterMap getElementIDGenerator() {
00224 if (_IDGenerator == null) {
00225 _IDGenerator = createElementIDGenerator();
00226 }
00227 return _IDGenerator;
00228 }
00229
00230
00231
00232
00233
00239 protected Map createCache() {
00240 return new WeakHashMap();
00241 }
00242
00247 protected RQMLSecondClassFactoryFacade createElementFactories() {
00248 return new RQMLSecondClassFactoryFacade(this);
00249 }
00250
00255 protected CounterMap createElementIDGenerator() {
00256 return new CounterMap();
00257 }
00258
00259
00260
00261
00267 private RQMLSecondClassFactoryFacade _elementFactories = null;
00268
00275 private Map _cache = null;
00276
00281 private Observer _elementObserver;
00282
00286 private CounterMap _IDGenerator = null;
00287
00291 protected static final int NAME_PREFIX_LEN = 4;
00292
00293
00294
00295
00305 protected abstract class ElementFactory implements RQMLSecondClassFactory {
00306
00312 public RQMLSecondClass createRQMLSecondClass(Element e) {
00313 RQMLSecondClassImpl rcs = doCreateRQMLSecondClass(e);
00314 return rcs;
00315 }
00316
00323 protected abstract RQMLSecondClassImpl doCreateRQMLSecondClass(Element e);
00324 }
00325 }
00326