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.woody;
018:
019: import org.apache.avalon.framework.CascadingException;
020: import org.apache.avalon.framework.activity.Disposable;
021: import org.apache.avalon.framework.activity.Initializable;
022: import org.apache.avalon.framework.component.Component;
023: import org.apache.avalon.framework.configuration.Configurable;
024: import org.apache.avalon.framework.configuration.Configuration;
025: import org.apache.avalon.framework.configuration.ConfigurationException;
026: import org.apache.avalon.framework.logger.AbstractLogEnabled;
027: import org.apache.avalon.framework.service.ServiceException;
028: import org.apache.avalon.framework.service.ServiceManager;
029: import org.apache.avalon.framework.service.Serviceable;
030: import org.apache.avalon.framework.thread.ThreadSafe;
031: import org.apache.cocoon.woody.formmodel.Form;
032: import org.apache.cocoon.woody.formmodel.FormDefinition;
033: import org.apache.cocoon.woody.formmodel.FormDefinitionBuilder;
034: import org.apache.cocoon.woody.formmodel.WidgetDefinitionBuilder;
035: import org.apache.cocoon.woody.util.DomHelper;
036: import org.apache.cocoon.woody.util.SimpleServiceSelector;
037: import org.apache.excalibur.source.Source;
038: import org.w3c.dom.Document;
039: import org.w3c.dom.Element;
040: import org.xml.sax.InputSource;
041:
042: /**
043: * Component implementing the {@link FormManager} role.
044: *
045: * @version $Id: DefaultFormManager.java 433543 2006-08-22 06:22:54Z crossley $
046: */
047: public class DefaultFormManager extends AbstractLogEnabled implements
048: FormManager, ThreadSafe, Serviceable, Disposable, Configurable,
049: Component, Initializable {
050:
051: protected static final String PREFIX = "WoodyForm:";
052: protected ServiceManager manager;
053: protected Configuration configuration;
054: protected SimpleServiceSelector widgetDefinitionBuilderSelector;
055: protected CacheManager cacheManager;
056:
057: public void service(ServiceManager serviceManager)
058: throws ServiceException {
059: this .manager = serviceManager;
060: this .cacheManager = (CacheManager) serviceManager
061: .lookup(CacheManager.ROLE);
062: }
063:
064: /**
065: * Configurable
066: */
067: public void configure(Configuration configuration)
068: throws ConfigurationException {
069: this .configuration = configuration;
070: }
071:
072: public void initialize() throws Exception {
073: widgetDefinitionBuilderSelector = new SimpleServiceSelector(
074: "widget", WidgetDefinitionBuilder.class);
075: widgetDefinitionBuilderSelector.service(new ServiceManager() {
076: final String WIDGET_DEFINITION_BUILDER_SELECTOR_ROLE = WidgetDefinitionBuilder.class
077: .getName()
078: + "Selector";
079:
080: public Object lookup(String name) throws ServiceException {
081: if (WIDGET_DEFINITION_BUILDER_SELECTOR_ROLE
082: .equals(name))
083: return widgetDefinitionBuilderSelector;
084: else
085: return manager.lookup(name);
086: }
087:
088: public boolean hasService(String name) {
089: if (WIDGET_DEFINITION_BUILDER_SELECTOR_ROLE
090: .equals(name))
091: return true;
092: else
093: return manager.hasService(name);
094: }
095:
096: public void release(Object service) {
097: if (service != widgetDefinitionBuilderSelector)
098: manager.release(service);
099: }
100: });
101: widgetDefinitionBuilderSelector.configure(configuration
102: .getChild("widgets"));
103: }
104:
105: public Form createForm(Source source) throws Exception {
106: FormDefinition formDefinition = getFormDefinition(source);
107: return (Form) formDefinition.createInstance();
108: }
109:
110: public FormDefinition getFormDefinition(Source source)
111: throws Exception {
112: FormDefinition formDefinition = (FormDefinition) this .cacheManager
113: .get(source, PREFIX);
114: if (formDefinition == null) {
115: Document formDocument;
116: try {
117: InputSource inputSource = new InputSource(source
118: .getInputStream());
119: inputSource.setSystemId(source.getURI());
120: formDocument = DomHelper.parse(inputSource);
121: } catch (Exception e) {
122: throw new CascadingException(
123: "Could not parse form definition from "
124: + source.getURI(), e);
125: }
126:
127: Element formElement = formDocument.getDocumentElement();
128:
129: // check that the root element is a wd:form element
130: if (!(formElement.getLocalName().equals("form") || Constants.WD_NS
131: .equals(formElement.getNamespaceURI())))
132: throw new Exception("Expected a Woody form element at "
133: + DomHelper.getLocation(formElement));
134:
135: FormDefinitionBuilder formDefinitionBuilder = (FormDefinitionBuilder) widgetDefinitionBuilderSelector
136: .select("form");
137: formDefinition = (FormDefinition) formDefinitionBuilder
138: .buildWidgetDefinition(formElement);
139: this .cacheManager.set(formDefinition, source, PREFIX);
140: }
141: return formDefinition;
142: }
143:
144: /**
145: * Disposable
146: */
147: public void dispose() {
148: if (this.widgetDefinitionBuilderSelector != null) {
149: this.widgetDefinitionBuilderSelector.dispose();
150: this.widgetDefinitionBuilderSelector = null;
151: }
152: this.manager.release(this.cacheManager);
153: this.cacheManager = null;
154: this.manager = null;
155: }
156: }
|