001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdo.sco;
012:
013: import com.versant.core.metadata.FieldMetaData;
014: import com.versant.core.metadata.MDStaticUtils;
015: import com.versant.core.metadata.MDStatics;
016: import com.versant.core.util.classhelper.ClassHelper;
017:
018: import java.util.*;
019:
020: import com.versant.core.common.BindingSupportImpl;
021:
022: /**
023: * This registry map the SCO types to their factories.
024: */
025: public class VersantSCOFactoryRegistry {
026:
027: private static final VersantSCOFactoryRegistry defaultMapping = new VersantSCOFactoryRegistry();
028:
029: private HashMap typeFactory = new HashMap(32);
030:
031: protected VersantSCOFactoryRegistry() {
032: put(MDStatics.DATE, new DateSCOFactory());
033: put(MDStatics.HASHSET, new SCOHashSetFactory());
034: put(MDStatics.SET, new SCOHashSetFactory());
035: put(MDStatics.TREESET, new SCOTreeSetFactory());
036: put(MDStatics.SORTEDSET, new SCOTreeSetFactory());
037: put(MDStatics.COLLECTION, new SCOListFactory());
038: put(MDStatics.LIST, new SCOListFactory());
039: put(MDStatics.ARRAYLIST, new SCOArrayListFactory());
040: put(MDStatics.LINKEDLIST, new SCOLinkedListFactory());
041:
042: put(MDStatics.VECTOR, new SCOVectorFactory());
043:
044: put(MDStatics.MAP, new SCOHashMapFactory());
045: put(MDStatics.HASHMAP, new SCOHashMapFactory());
046: put(MDStatics.HASHTABLE, new SCOHashtableFactory());
047: put(MDStatics.TREEMAP, new SCOTreeMapFactory());
048: put(MDStatics.SORTEDMAP, new SCOTreeMapFactory());
049: }
050:
051: private void put(int type, Object factory) {
052: if (factory == null)
053: return;
054: String name = MDStaticUtils.toSimpleName(type);
055: if (name == null)
056: return;
057: Class c = MDStaticUtils.toSimpleClass(name);
058: if (c == null)
059: return;
060: typeFactory.put(c, factory);
061: }
062:
063: public VersantSCOFactoryRegistry(Map mapping, ClassLoader loader) {
064: this ();
065: if (mapping == null)
066: return;
067: for (Iterator it = mapping.keySet().iterator(); it.hasNext();) {
068: String key = (String) it.next();
069: String value = (String) mapping.get(key);
070: try {
071: Class javaClass = ClassHelper.get().classForName(key,
072: true, loader);
073: Class scoFactoryClass = ClassHelper.get().classForName(
074: value, true, loader);
075: Object factory = scoFactoryClass.newInstance();
076: typeFactory.put(javaClass, factory);
077: } catch (Exception e) {
078: throw BindingSupportImpl.getInstance().runtime(
079: "Unable to add SCO factory mapping:\n"
080: + e.getMessage(), e);
081: }
082: }
083: }
084:
085: /**
086: * Get the factory for a simple SCO type.
087: */
088: public Object getFactory(FieldMetaData fmd) {
089: if (fmd == null)
090: return null;
091: //create a new SCO data
092: switch (fmd.category) {
093: case MDStatics.CATEGORY_SIMPLE:
094: return getJdoGenieSCOFactory(fmd);
095: case MDStatics.CATEGORY_COLLECTION:
096: return getJDOGenieSCOCollectionFactory(fmd);
097: case MDStatics.CATEGORY_MAP:
098: return getJDOGenieSCOMapFactory(fmd);
099: }
100: return null;
101: }
102:
103: /**
104: * Get the factory for a simple SCO type.
105: */
106: public VersantSCOFactory getJdoGenieSCOFactory(FieldMetaData fmd) {
107: return (VersantSCOFactory) getFactory(fmd,
108: MDStatics.CATEGORY_SIMPLE, VersantSCOFactory.class);
109: }
110:
111: /**
112: * Get the factory for a SCO collection.
113: */
114: public VersantSCOCollectionFactory getJDOGenieSCOCollectionFactory(
115: FieldMetaData fmd) {
116: return (VersantSCOCollectionFactory) getFactory(fmd,
117: MDStatics.CATEGORY_COLLECTION,
118: VersantSCOCollectionFactory.class);
119: }
120:
121: /**
122: * Get the factory for a SCO map.
123: */
124: public VersantSCOMapFactory getJDOGenieSCOMapFactory(
125: FieldMetaData fmd) {
126: return (VersantSCOMapFactory) getFactory(fmd,
127: MDStatics.CATEGORY_MAP, VersantSCOMapFactory.class);
128: }
129:
130: private Object getFactory(FieldMetaData fmd, int category,
131: Class factoryCls) {
132: if (fmd.category != category) {
133: return null;
134: }
135: Class cls = fmd.type;
136:
137: Object o = typeFactory.get(cls);
138:
139: if (o == null) {
140: throw BindingSupportImpl.getInstance().notImplemented(
141: "No SCO factory registered for type: "
142: + MDStaticUtils.toSimpleName(fmd.typeCode)
143: + ".\nClass: "
144: + fmd.classMetaData.cls.getName()
145: + " Field: " + fmd.name);
146: }
147: if (!factoryCls.isAssignableFrom(o.getClass())) {
148: throw BindingSupportImpl.getInstance().notImplemented(
149: "Incorrect SCO factory type.\nExpected:"
150: + factoryCls.getName() + "\nFound:"
151: + o.getClass().getName() + ".\nfor Class: "
152: + fmd.classMetaData.cls.getName()
153: + " Field: " + fmd.name);
154: }
155: return o;
156: }
157:
158: public static String getDefaultMapping(Class javaType) {
159: Object factory = defaultMapping.typeFactory.get(javaType);
160: if (factory != null) {
161: return factory.getClass().getName();
162: }
163: return null;
164: }
165:
166: public static void fillMapWithDefaults(Map map) {
167: for (Iterator it = defaultMapping.typeFactory.keySet()
168: .iterator(); it.hasNext();) {
169: Class javaType = (Class) it.next();
170: Object factory = defaultMapping.typeFactory.get(javaType);
171: map.put(javaType, factory.getClass().getName());
172: }
173: }
174:
175: public static List getValidSCOFactoryList(Class fieldType) {
176: List factoryList = new ArrayList();
177: for (Iterator it = defaultMapping.typeFactory.keySet()
178: .iterator(); it.hasNext();) {
179: Class javaType = (Class) it.next();
180: if (fieldType.isAssignableFrom(javaType)) {
181: Object factory = defaultMapping.typeFactory
182: .get(javaType);
183: if (factory != null) {
184: String factoryName = factory.getClass().getName();
185: if (!factoryList.contains(factoryName)) {
186: factoryList.add(factoryName);
187: }
188: }
189: }
190: }
191: Collections.sort(factoryList);
192: return factoryList;
193: }
194:
195: public static void removeDefaults(Map map) {
196: for (Iterator it = defaultMapping.typeFactory.keySet()
197: .iterator(); it.hasNext();) {
198: Class javaType = (Class) it.next();
199: String factoryName1 = (String) map.get(javaType);
200: if (factoryName1 != null) {
201: Object factory = defaultMapping.typeFactory
202: .get(javaType);
203: if (factory != null) {
204: String factoryName2 = factory.getClass().getName();
205: if (factoryName1.equals(factoryName2)) {
206: map.remove(javaType);
207: }
208: }
209: }
210: }
211: }
212:
213: }
|