001: /*
002: * Copyright 2006 Luca Garulli (luca.garulli@assetdata.it)
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.romaframework.core.schema;
018:
019: import java.util.ArrayList;
020: import java.util.Collection;
021: import java.util.HashMap;
022: import java.util.StringTokenizer;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.romaframework.core.config.Configurable;
027: import org.romaframework.core.config.RomaApplicationContext;
028: import org.romaframework.core.exception.ConfigurationNotFoundException;
029: import org.romaframework.core.schema.config.SchemaConfiguration;
030:
031: /**
032: * Manage the Entities and cache them.
033: *
034: * @author Luca Garulli (luca.garulli@assetdata.it)
035: */
036: public class SchemaManager extends Configurable<String> {
037:
038: private ArrayList<String> ignoreFields = new ArrayList<String>();
039: private ArrayList<String> ignoreActions = new ArrayList<String>();
040:
041: private static final String PAR_IGNORE_FIELDS = "ignore-fields";
042: private static final String PAR_IGNORE_ACTIONS = "ignore-actions";
043:
044: private HashMap<String, SchemaClass> entities = new HashMap<String, SchemaClass>();
045: private static Log log = LogFactory.getLog(SchemaManager.class);
046:
047: public SchemaManager() {
048: }
049:
050: public ArrayList<String> getIgnoreActions() {
051: return ignoreActions;
052: }
053:
054: public ArrayList<String> getIgnoreFields() {
055: return ignoreFields;
056: }
057:
058: public SchemaClass getClassInfo(String iEntityName) {
059: return getClassInfo(iEntityName, null, null);
060: }
061:
062: public SchemaClass getClassInfo(Class<?> iEntityClass,
063: SchemaConfiguration iDescriptor) {
064: SchemaClass entityInfo = entities.get(iEntityClass
065: .getSimpleName());
066: if (entityInfo == null)
067: entityInfo = createClassInfo(iEntityClass, iDescriptor);
068:
069: return entityInfo;
070: }
071:
072: /**
073: * Virtual class: implementation by concrete java class but extended by xml descriptor.
074: *
075: * @param iEntityName
076: * @param iBaseClass
077: * @param iDescriptor
078: * @return
079: */
080: public SchemaClass getClassInfo(String iEntityName,
081: Class<?> iBaseClass, SchemaConfiguration iDescriptor) {
082: SchemaClass entityInfo = entities.get(iEntityName);
083: if (entityInfo == null)
084: entityInfo = createClassInfo(iEntityName, iBaseClass,
085: iDescriptor);
086:
087: return entityInfo;
088: }
089:
090: /**
091: * Return the SchemaField requested.
092: *
093: * @param iClassName
094: * Name of the class
095: * @param iFieldName
096: * Name of the field to search
097: * @return SchemaField object if found, otherwise null
098: */
099: public SchemaField getSchemaField(String iClassName,
100: String iFieldName) {
101: SchemaClass cls = getClassInfo(iClassName);
102: if (cls == null)
103: return null;
104:
105: return cls.getField(iFieldName);
106: }
107:
108: /**
109: * Return the SchemaAction requested.
110: *
111: * @param iClassName
112: * Name of the class
113: * @param iActionName
114: * Name of the action to search
115: * @return SchemaAction object if found, otherwise null
116: */
117: public SchemaElement getSchemaAction(String iClassName,
118: String iActionName) {
119: SchemaClass cls = getClassInfo(iClassName);
120: if (cls == null)
121: return null;
122:
123: return cls.getAction(iActionName);
124: }
125:
126: /**
127: * Return the SchemaEvent requested.
128: *
129: * @param iClassName
130: * Name of the class
131: * @param iEventName
132: * Name of the event to search
133: * @return SchemaEvent object if found, otherwise null
134: */
135: public SchemaEvent getSchemaEvent(String iClassName,
136: String iEventName) {
137: SchemaClass cls = getClassInfo(iClassName);
138: if (cls == null)
139: return null;
140:
141: return cls.getEvent(iEventName);
142: }
143:
144: public SchemaClass createClassInfo(Class<?> iEntityClass,
145: SchemaConfiguration iDescriptor) {
146: // CREATE ENTITY
147: return registerClassInfo(iEntityClass.getSimpleName(),
148: iEntityClass, iEntityClass.getSuperclass(), iDescriptor);
149: }
150:
151: /**
152: * Create and register a class info. Call this if you want to register virtual class built at run-time.
153: *
154: * @param iEntityName
155: * Class name, unique name
156: * @param iClass
157: * Class instance
158: * @param iBaseClass
159: * Base class where to extend
160: * @param iDescriptor
161: * Optional XML descriptor
162: * @return Registered ClassInfo instance.
163: * @throws ConfigurationNotFoundException
164: */
165: public SchemaClass registerClassInfo(String iEntityName,
166: Class<?> iClass, Class<?> iBaseClass,
167: SchemaConfiguration iDescriptor)
168: throws ConfigurationNotFoundException {
169: // CREATE THE SCHEMA INFO INSTANCE
170: SchemaClass cls = new SchemaClass(this , iEntityName, iClass,
171: iBaseClass, iDescriptor);
172:
173: // REGISTER IT (MUST PRECEDE CONFIGURATION FOR SELF-REFERENCED PROPERTIES)
174: entities.put(iEntityName, cls);
175:
176: // CONFIGURE IT
177: cls.configure();
178:
179: return cls;
180: }
181:
182: public SchemaClass createClassInfo(String iEntityName,
183: Class<?> iBaseClass, SchemaConfiguration iDescriptor) {
184: Class<?> clazz = RomaApplicationContext.getInstance().getBean(
185: SchemaClassResolver.class).getEntityClass(iEntityName);
186:
187: if (clazz == null && iBaseClass == null)
188: clazz = getClassForJavaTypes(iEntityName);
189:
190: // CREATE ENTITY
191: return registerClassInfo(iEntityName, clazz, iBaseClass,
192: iDescriptor);
193: }
194:
195: /**
196: * Invoked by IoC container at startup.
197: */
198: public void config() {
199: String cfgIgnore = getConfiguration(PAR_IGNORE_FIELDS);
200: if (cfgIgnore != null) {
201: StringTokenizer tokenizer = new StringTokenizer(cfgIgnore,
202: ",");
203: while (tokenizer.hasMoreTokens())
204: ignoreFields.add(tokenizer.nextToken());
205: }
206:
207: cfgIgnore = getConfiguration(PAR_IGNORE_ACTIONS);
208: if (cfgIgnore != null) {
209: StringTokenizer tokenizer = new StringTokenizer(cfgIgnore,
210: ",");
211: while (tokenizer.hasMoreTokens())
212: ignoreActions.add(tokenizer.nextToken());
213: }
214: }
215:
216: public Collection<SchemaClass> getAllClassesInfo() {
217: return entities.values();
218: }
219:
220: public Collection<SchemaClass> getClassesInfoByInheritance(
221: Class iBaseClass) {
222: Collection<SchemaClass> result = new ArrayList<SchemaClass>();
223: for (SchemaClass schema : entities.values()) {
224: if (iBaseClass.isAssignableFrom(schema.getClazz()))
225: result.add(schema);
226: }
227: return result;
228: }
229:
230: public boolean isAvailableClassInfo(String typeName) {
231: return entities.containsKey(typeName);
232: }
233:
234: /**
235: * Resolve class object for java types.
236: *
237: * @param iEntityName
238: * Java type name
239: * @return Class object if found, otherwise null
240: */
241: private static Class<?> getClassForJavaTypes(String iEntityName) {
242: if (iEntityName.equals("String"))
243: return String.class;
244: else if (iEntityName.equals("Integer"))
245: return Integer.class;
246: else if (iEntityName.equals("Boolean"))
247: return Boolean.class;
248: else if (iEntityName.equals("Float"))
249: return Float.class;
250: else if (iEntityName.equals("Double"))
251: return Double.class;
252: else if (iEntityName.equals("Character"))
253: return Character.class;
254: else if (iEntityName.equals("Byte"))
255: return Byte.class;
256: else if (iEntityName.equals("Object"))
257: return Object.class;
258: return null;
259: }
260: }
|