001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.forms;
018:
019: import org.apache.avalon.framework.activity.Disposable;
020: import org.apache.avalon.framework.component.Component;
021: import org.apache.avalon.framework.configuration.Configurable;
022: import org.apache.avalon.framework.configuration.Configuration;
023: import org.apache.avalon.framework.configuration.ConfigurationException;
024: import org.apache.avalon.framework.container.ContainerUtil;
025: import org.apache.avalon.framework.context.Context;
026: import org.apache.avalon.framework.context.ContextException;
027: import org.apache.avalon.framework.context.Contextualizable;
028: import org.apache.avalon.framework.logger.AbstractLogEnabled;
029: import org.apache.avalon.framework.logger.Logger;
030: import org.apache.avalon.framework.service.ServiceException;
031: import org.apache.avalon.framework.service.ServiceManager;
032: import org.apache.avalon.framework.service.Serviceable;
033: import org.apache.avalon.framework.thread.ThreadSafe;
034: import org.apache.excalibur.source.Source;
035: import org.apache.excalibur.source.SourceResolver;
036:
037: import org.apache.cocoon.forms.formmodel.Form;
038: import org.apache.cocoon.forms.formmodel.FormDefinition;
039: import org.apache.cocoon.forms.formmodel.FormDefinitionBuilder;
040: import org.apache.cocoon.forms.formmodel.WidgetDefinitionBuilder;
041: import org.apache.cocoon.forms.formmodel.library.LibraryManager;
042: import org.apache.cocoon.forms.formmodel.library.LibraryManagerImpl;
043: import org.apache.cocoon.forms.util.DomHelper;
044: import org.apache.cocoon.forms.util.SimpleServiceSelector;
045: import org.apache.cocoon.util.location.LocationImpl;
046:
047: import org.w3c.dom.Document;
048: import org.w3c.dom.Element;
049: import org.xml.sax.InputSource;
050:
051: /**
052: * Component implementing the {@link FormManager} role.
053: *
054: * @version $Id: DefaultFormManager.java 506463 2007-02-12 14:32:21Z cziegeler $
055: */
056: public class DefaultFormManager extends AbstractLogEnabled implements
057: FormManager, Contextualizable, Serviceable, Configurable,
058: Disposable, ThreadSafe, Component {
059: // NOTE: Component is there to allow this block to run in the 2.1 branch
060:
061: private static final String PREFIX = "CocoonForms:";
062:
063: private Context avalonContext;
064: protected ServiceManager manager;
065: protected SimpleServiceSelector widgetDefinitionBuilderSelector;
066: protected CacheManager cacheManager;
067:
068: protected LibraryManager libraryManager;
069:
070: //
071: // Lifecycle
072: //
073:
074: public DefaultFormManager() {
075: widgetDefinitionBuilderSelector = new SimpleServiceSelector(
076: "widget", WidgetDefinitionBuilder.class);
077: this .libraryManager = new LibraryManagerImpl();
078: }
079:
080: /**
081: * @see org.apache.avalon.framework.logger.AbstractLogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger)
082: */
083: public void enableLogging(Logger logger) {
084: super .enableLogging(logger);
085: widgetDefinitionBuilderSelector.enableLogging(getLogger());
086: ContainerUtil.enableLogging(this .libraryManager, getLogger()
087: .getChildLogger("library"));
088: }
089:
090: /**
091: * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
092: */
093: public void contextualize(Context context) throws ContextException {
094: this .avalonContext = context;
095: widgetDefinitionBuilderSelector.contextualize(avalonContext);
096: ContainerUtil.contextualize(this .libraryManager, avalonContext);
097: }
098:
099: /** Temporary internal method, don't rely on it's existence! Needed to access the context from flowscript. */
100: // FIXME (SW). Extending the FOM is needed.
101: public Context getAvalonContext() {
102: return this .avalonContext;
103: }
104:
105: /**
106: * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
107: */
108: public void service(ServiceManager manager) throws ServiceException {
109: this .manager = manager;
110: this .cacheManager = (CacheManager) manager
111: .lookup(CacheManager.ROLE);
112: widgetDefinitionBuilderSelector
113: .service(new FormServiceManager());
114: ContainerUtil.service(this .libraryManager,
115: new FormServiceManager());
116: }
117:
118: /**
119: * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
120: */
121: public void configure(Configuration configuration)
122: throws ConfigurationException {
123: ContainerUtil.configure(this .libraryManager, configuration
124: .getChild("libraries"));
125: widgetDefinitionBuilderSelector.configure(configuration
126: .getChild("widgets"));
127: }
128:
129: /**
130: * @see org.apache.avalon.framework.activity.Disposable#dispose()
131: */
132: public void dispose() {
133: if (this .widgetDefinitionBuilderSelector != null) {
134: this .widgetDefinitionBuilderSelector.dispose();
135: this .widgetDefinitionBuilderSelector = null;
136: }
137: if (this .libraryManager != null) {
138: ContainerUtil.dispose(this .libraryManager);
139: this .libraryManager = null;
140: }
141: if (this .cacheManager != null) {
142: this .manager.release(this .cacheManager);
143: this .cacheManager = null;
144: }
145: this .manager = null;
146: }
147:
148: //
149: // Business Methods
150: //
151:
152: public Form createForm(String uri) throws Exception {
153: SourceResolver resolver = null;
154: Source source = null;
155: try {
156: try {
157: resolver = (SourceResolver) manager
158: .lookup(SourceResolver.ROLE);
159: source = resolver.resolveURI(uri);
160: } catch (Exception e) {
161: throw new FormsException(
162: "Could not resolve form definition URI.", e,
163: new LocationImpl("[FormManager]", uri));
164: }
165: return createForm(source);
166: } finally {
167: if (source != null) {
168: resolver.release(source);
169: }
170: if (resolver != null) {
171: manager.release(resolver);
172: }
173: }
174: }
175:
176: public Form createForm(Source source) throws Exception {
177: FormDefinition formDefinition = createFormDefinition(source);
178: Form form = (Form) formDefinition.createInstance();
179: form.initialize();
180: return form;
181: }
182:
183: public Form createForm(Element formElement) throws Exception {
184: Form form = (Form) createFormDefinition(formElement)
185: .createInstance();
186: form.initialize();
187: return form;
188: }
189:
190: public FormDefinition createFormDefinition(String uri)
191: throws Exception {
192: SourceResolver sourceResolver = null;
193: Source source = null;
194: try {
195: try {
196: sourceResolver = (SourceResolver) manager
197: .lookup(SourceResolver.ROLE);
198: source = sourceResolver.resolveURI(uri);
199: } catch (Exception e) {
200: throw new FormsException(
201: "Could not resolve form definition.", e,
202: new LocationImpl("[FormManager]", uri));
203: }
204: return createFormDefinition(source);
205: } finally {
206: if (source != null) {
207: sourceResolver.release(source);
208: }
209: if (sourceResolver != null) {
210: manager.release(sourceResolver);
211: }
212: }
213: }
214:
215: public FormDefinition createFormDefinition(Source source)
216: throws Exception {
217: FormDefinition formDefinition = (FormDefinition) this .cacheManager
218: .get(source, PREFIX);
219: if (formDefinition != null
220: && formDefinition.getLocalLibrary()
221: .dependenciesHaveChanged()) {
222: formDefinition = null; // invalidate
223: }
224:
225: if (formDefinition == null) {
226: if (getLogger().isDebugEnabled()) {
227: getLogger().debug("Building Form: " + source.getURI());
228: }
229:
230: Document formDocument;
231: try {
232: InputSource inputSource = new InputSource(source
233: .getInputStream());
234: inputSource.setSystemId(source.getURI());
235: formDocument = DomHelper.parse(inputSource,
236: this .manager);
237: } catch (Exception e) {
238: throw new FormsException(
239: "Could not parse form definition.", e,
240: new LocationImpl("[FormManager]", source
241: .getURI()));
242: }
243:
244: Element formElement = formDocument.getDocumentElement();
245: formDefinition = createFormDefinition(formElement);
246: this .cacheManager.set(formDefinition, source, PREFIX);
247: }
248: return formDefinition;
249: }
250:
251: public FormDefinition createFormDefinition(Element formElement)
252: throws Exception {
253: // check that the root element is a fd:form element
254: if (!FormsConstants.DEFINITION_NS.equals(formElement
255: .getNamespaceURI())
256: || !formElement.getLocalName().equals("form")) {
257: throw new FormsException(
258: "Expected forms definition <fd:form> element.",
259: DomHelper.getLocationObject(formElement));
260: }
261:
262: FormDefinitionBuilder builder = (FormDefinitionBuilder) widgetDefinitionBuilderSelector
263: .select("form");
264: return (FormDefinition) builder
265: .buildWidgetDefinition(formElement);
266: }
267:
268: private class FormServiceManager implements ServiceManager {
269: final String WIDGET_DEFINITION_BUILDER_SELECTOR_ROLE = WidgetDefinitionBuilder.class
270: .getName()
271: + "Selector";
272: final String LIBRARY_MANAGER_ROLE = LibraryManager.ROLE;
273:
274: public Object lookup(String name) throws ServiceException {
275: if (WIDGET_DEFINITION_BUILDER_SELECTOR_ROLE.equals(name)) {
276: return widgetDefinitionBuilderSelector;
277: } else if (LIBRARY_MANAGER_ROLE.equals(name)) {
278: return libraryManager;
279: } else {
280: return manager.lookup(name);
281: }
282: }
283:
284: public boolean hasService(String name) {
285: if (WIDGET_DEFINITION_BUILDER_SELECTOR_ROLE.equals(name)) {
286: return true;
287: } else if (LIBRARY_MANAGER_ROLE.equals(name)) {
288: return true;
289: } else {
290: return manager.hasService(name);
291: }
292: }
293:
294: public void release(Object service) {
295: if (service != widgetDefinitionBuilderSelector
296: && service != libraryManager) {
297: manager.release(service);
298: }
299: }
300: }
301: }
|