001: /*
002: * Copyright 2004 Outerthought bvba and Schaubroeck nv
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: package org.outerj.daisy.frontend.editor;
017:
018: import java.io.InputStream;
019: import java.util.Collections;
020: import java.util.HashMap;
021: import java.util.Map;
022:
023: import org.apache.avalon.framework.service.ServiceManager;
024: import org.apache.avalon.framework.context.Context;
025: import org.apache.avalon.framework.logger.Logger;
026: import org.apache.excalibur.source.Source;
027: import org.apache.excalibur.source.SourceResolver;
028: import org.apache.excalibur.store.Store;
029: import org.apache.xmlbeans.XmlOptions;
030: import org.outerj.daisy.frontend.util.CacheHelper;
031: import org.outerj.daisy.repository.schema.FieldTypeUse;
032: import org.outerj.daisy.xmlutil.LocalSAXParserFactory;
033: import org.outerx.daisy.x10Fieldeditor.FieldEditorDocument;
034:
035: public class FieldEditorManager {
036: private static final String STORE_PREFIX = FieldEditorManager.class
037: .getName();
038:
039: public static FieldEditor getFieldEditor(FieldTypeUse fieldTypeUse,
040: ServiceManager serviceManager, Context context,
041: Logger logger) throws Exception {
042: SourceResolver sourceResolver = null;
043: Source source = null;
044: Store store = null;
045: try {
046: sourceResolver = (SourceResolver) serviceManager
047: .lookup(SourceResolver.ROLE);
048: source = sourceResolver
049: .resolveURI("wikidata:/resources/fieldeditors/"
050: + fieldTypeUse.getFieldType().getName()
051: + ".xml");
052: if (!source.exists()) {
053: return new DefaultFieldEditor.Factory().getFieldEditor(
054: fieldTypeUse, Collections.EMPTY_MAP,
055: serviceManager, context, logger);
056: } else {
057: store = (Store) serviceManager
058: .lookup(Store.TRANSIENT_STORE);
059: FieldEditorInfo fieldEditorInfo = (FieldEditorInfo) CacheHelper
060: .getFromCache(store, source, STORE_PREFIX);
061: if (fieldEditorInfo == null) {
062: fieldEditorInfo = buildFieldEditorInfo(source,
063: logger);
064: CacheHelper.setInCache(store, fieldEditorInfo,
065: source, STORE_PREFIX);
066: }
067:
068: if (fieldEditorInfo.isValid()) {
069: return fieldEditorInfo.getBuilder().getFieldEditor(
070: fieldTypeUse,
071: fieldEditorInfo.getProperties(),
072: serviceManager, context, logger);
073: }
074: }
075: } finally {
076: if (source != null)
077: sourceResolver.release(source);
078: if (sourceResolver != null)
079: serviceManager.release(sourceResolver);
080: if (store != null)
081: serviceManager.release(store);
082: }
083: return null;
084: }
085:
086: private static FieldEditorInfo buildFieldEditorInfo(Source source,
087: Logger logger) {
088: FieldEditorDocument fieldEditorDocument;
089: try {
090: InputStream is = null;
091: try {
092: is = source.getInputStream();
093: XmlOptions xmlOptions = new XmlOptions()
094: .setLoadUseXMLReader(LocalSAXParserFactory
095: .newXmlReader());
096: fieldEditorDocument = FieldEditorDocument.Factory
097: .parse(is, xmlOptions);
098: } finally {
099: if (is != null)
100: is.close();
101: }
102:
103: String className = fieldEditorDocument.getFieldEditor()
104: .getClass1();
105: if (className == null)
106: throw new Exception(
107: "Missing class attribute for fieldEditor specification in "
108: + source.getURI());
109:
110: Class clazz;
111: try {
112: clazz = FieldEditorManager.class.getClassLoader()
113: .loadClass(className);
114: } catch (ClassNotFoundException e) {
115: throw new Exception("Class for fieldEditor not found: "
116: + className + " specified in "
117: + source.getURI());
118: }
119:
120: if (!FieldEditorFactory.class.isAssignableFrom(clazz)) {
121: throw new Exception(
122: "Class specified for field editor is not a "
123: + FieldEditorFactory.class.getName()
124: + " at " + source.getURI());
125: }
126:
127: FieldEditorFactory factory = (FieldEditorFactory) clazz
128: .newInstance();
129:
130: Map<String, String> properties = new HashMap<String, String>();
131: FieldEditorDocument.FieldEditor.Properties propertiesXml = fieldEditorDocument
132: .getFieldEditor().getProperties();
133: if (propertiesXml != null) {
134: for (FieldEditorDocument.FieldEditor.Properties.Entry entry : propertiesXml
135: .getEntryList()) {
136: String key = entry.getKey();
137: if (key != null) {
138: properties.put(key, entry.getStringValue());
139: }
140: }
141: }
142:
143: return new FieldEditorInfo(factory, Collections
144: .unmodifiableMap(properties), true);
145: } catch (Throwable e) {
146: logger.error("Error in field editor specification at "
147: + source.getURI(), e);
148: return new FieldEditorInfo(null, null, false);
149: }
150: }
151:
152: static class FieldEditorInfo {
153: private FieldEditorFactory factory;
154:
155: private Map<String, String> properties;
156:
157: private boolean valid;
158:
159: public FieldEditorInfo(FieldEditorFactory factory,
160: Map<String, String> properties, boolean valid) {
161: this .factory = factory;
162: this .properties = properties;
163: this .valid = valid;
164:
165: if (valid && (factory == null || properties == null)) {
166: throw new IllegalArgumentException(
167: "if valid argument is true, the other arguments cannot be null");
168: }
169: }
170:
171: public FieldEditorFactory getBuilder() {
172: return factory;
173: }
174:
175: public Map<String, String> getProperties() {
176: return properties;
177: }
178:
179: public boolean isValid() {
180: return valid;
181: }
182: }
183: }
|