001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.planning.ldm.asset;
028:
029: import java.util.ArrayList;
030: import java.util.Collection;
031: import java.util.HashMap;
032: import java.util.Iterator;
033: import java.util.List;
034:
035: import org.cougaar.planning.ldm.LatePropertyProvider;
036: import org.cougaar.planning.ldm.PropertyProvider;
037: import org.cougaar.planning.ldm.PrototypeProvider;
038: import org.cougaar.planning.service.PrototypeRegistryService;
039:
040: public class PrototypeRegistry implements PrototypeRegistryService {
041: /** THEINITIALREGISTRYSIZE specifies the initial size of the HashMap theRegistry,
042: * which contains the Strings of RegistryTerms
043: **/
044: private final static int THE_INITIAL_REGISTRY_SIZE = 89;
045: private final HashMap myRegistry = new HashMap(
046: THE_INITIAL_REGISTRY_SIZE);
047:
048: public PrototypeRegistry() {
049: }
050:
051: /** set of PrototypeProvider LDM Plugins **/
052: // might want this to be prioritized lists
053: private final List prototypeProviders = new ArrayList();
054:
055: public void addPrototypeProvider(PrototypeProvider prov) {
056: if (prov == null)
057: throw new IllegalArgumentException("prov must be non-null");
058: synchronized (prototypeProviders) {
059: prototypeProviders.add(prov);
060: }
061: }
062:
063: /** set of PropertyProvider LDM Plugins **/
064: private final List propertyProviders = new ArrayList();
065:
066: public void addPropertyProvider(PropertyProvider prov) {
067: if (prov == null)
068: throw new IllegalArgumentException("prov must be non-null");
069: synchronized (propertyProviders) {
070: propertyProviders.add(prov);
071: }
072: }
073:
074: // use the registry for registering prototypes for now.
075: // later, just replace with a hash table.
076: public void cachePrototype(String aTypeName, Asset aPrototype) {
077: if (aTypeName == null)
078: throw new IllegalArgumentException(
079: "aTypeName must be non-null");
080: synchronized (myRegistry) {
081: myRegistry.put(aTypeName.intern(), aPrototype);
082: }
083: }
084:
085: public boolean isPrototypeCached(String aTypeName) {
086: if (aTypeName == null)
087: throw new IllegalArgumentException(
088: "aTypeName must be non-null");
089: synchronized (myRegistry) {
090: return (myRegistry.get(aTypeName) != null);
091: }
092: }
093:
094: public Asset getPrototype(String aTypeName) {
095: if (aTypeName == null)
096: throw new IllegalArgumentException(
097: "aTypeName must be non-null");
098: return getPrototype(aTypeName, null);
099: }
100:
101: public Asset getPrototype(String aTypeName, Class anAssetClass) {
102: if (aTypeName == null)
103: throw new IllegalArgumentException(
104: "aTypeName must be non-null");
105:
106: Asset found = null;
107:
108: // look in our registry first.
109: // the catch is in case some bozo registered a non-asset under this
110: // name.
111: try {
112: synchronized (myRegistry) {
113: found = (Asset) myRegistry.get(aTypeName);
114: }
115: if (found != null)
116: return found;
117: } catch (ClassCastException cce) {
118: }
119:
120: synchronized (prototypeProviders) {
121: // else, try the prototype providers
122: int l = prototypeProviders.size();
123: for (int i = 0; i < l; i++) {
124: PrototypeProvider pp = (PrototypeProvider) prototypeProviders
125: .get(i);
126: found = pp.getPrototype(aTypeName, anAssetClass);
127: if (found != null)
128: return found;
129: }
130: }
131:
132: // might want to throw an exception in a later version
133: return null;
134: }
135:
136: public void fillProperties(Asset anAsset) {
137: if (anAsset == null)
138: throw new IllegalArgumentException(
139: "anAsset must be non-null");
140:
141: // expose the asset to all propertyproviders
142: synchronized (propertyProviders) {
143: int l = propertyProviders.size();
144: for (int i = 0; i < l; i++) {
145: PropertyProvider pp = (PropertyProvider) propertyProviders
146: .get(i);
147: pp.fillProperties(anAsset);
148: }
149: }
150: }
151:
152: /** hash of PropertyGroup interface to Lists of LatePropertyProvider instances. **/
153: private final HashMap latePPs = new HashMap(11);
154: /** list of LatePropertyProviders who supply all PropertyGroups **/
155: private final ArrayList defaultLatePPs = new ArrayList(3);
156:
157: public void addLatePropertyProvider(LatePropertyProvider lpp) {
158: Collection c = lpp.getPropertyGroupsProvided();
159: if (c == null) {
160: synchronized (defaultLatePPs) {
161: defaultLatePPs.add(lpp);
162: }
163: } else {
164: try {
165: for (Iterator it = c.iterator(); it.hasNext();) {
166: Class pgc = (Class) it.next();
167: synchronized (latePPs) {
168: ArrayList l = (ArrayList) latePPs.get(pgc);
169: if (l == null) {
170: l = new ArrayList(3);
171: latePPs.put(pgc, l);
172: }
173: synchronized (l) {
174: l.add(lpp);
175: }
176: }
177: }
178: } catch (ClassCastException e) {
179: System.err.println("LatePropertyProvider " + lpp
180: + " returned an illegal PropertyGroup spec:");
181: e.printStackTrace();
182: }
183: }
184: }
185:
186: /** hook for late-binding **/
187: public PropertyGroup lateFillPropertyGroup(Asset anAsset,
188: Class pgclass, long t) {
189: // specifics
190: ArrayList c;
191: synchronized (latePPs) {
192: c = (ArrayList) latePPs.get(pgclass);
193: }
194: PropertyGroup pg = null;
195: if (c != null) {
196: pg = tryLateFillers(c, anAsset, pgclass, t);
197: }
198: if (pg == null) {
199: pg = tryLateFillers(defaultLatePPs, anAsset, pgclass, t);
200: }
201: return pg;
202: }
203:
204: /** utility method of lateFillPropertyGroup() **/
205: private PropertyGroup tryLateFillers(ArrayList c, Asset anAsset,
206: Class pgclass, long t) {
207: synchronized (c) {
208: int l = c.size();
209: for (int i = 0; i < l; i++) {
210: LatePropertyProvider lpp = (LatePropertyProvider) c
211: .get(i);
212: PropertyGroup pg = lpp.fillPropertyGroup(anAsset,
213: pgclass, t);
214: if (pg != null)
215: return pg;
216: }
217: }
218: return null;
219: }
220:
221: /** Expose the Registry to consumers.
222: **/
223: /*
224: public Registry getRegistry() {
225: return myRegistry;
226: }
227: */
228:
229: //metrics service hooks
230: public int getPrototypeProviderCount() {
231: return prototypeProviders.size();
232: }
233:
234: public int getPropertyProviderCount() {
235: return propertyProviders.size();
236: }
237:
238: public int getCachedPrototypeCount() {
239: return myRegistry.size();
240: }
241:
242: }
|