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.formmodel.library;
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.logger.AbstractLogEnabled;
025: import org.apache.avalon.framework.service.ServiceException;
026: import org.apache.avalon.framework.service.ServiceManager;
027: import org.apache.avalon.framework.service.ServiceSelector;
028: import org.apache.avalon.framework.service.Serviceable;
029: import org.apache.avalon.framework.thread.ThreadSafe;
030: import org.apache.excalibur.source.Source;
031: import org.apache.excalibur.source.SourceResolver;
032:
033: import org.apache.cocoon.forms.CacheManager;
034: import org.apache.cocoon.forms.formmodel.WidgetDefinitionBuilder;
035: import org.apache.cocoon.forms.util.DomHelper;
036: import org.apache.cocoon.util.location.LocationImpl;
037:
038: import org.w3c.dom.Document;
039: import org.xml.sax.InputSource;
040:
041: /**
042: * @version $Id: LibraryManagerImpl.java 451888 2006-10-02 06:25:29Z vgritsenko $
043: *
044: */
045: public class LibraryManagerImpl extends AbstractLogEnabled implements
046: LibraryManager, Serviceable, Configurable, Disposable,
047: ThreadSafe, Component {
048:
049: private static final String PREFIX = "CocoonFormsLibrary:";
050:
051: private ServiceManager manager;
052: private CacheManager cacheManager;
053:
054: private ServiceSelector widgetDefinitionBuilderSelector;
055:
056: //
057: // Lifecycle
058: //
059:
060: public void configure(Configuration configuration)
061: throws ConfigurationException {
062: // TODO Read config to "preload" libraries
063: }
064:
065: public void service(ServiceManager serviceManager)
066: throws ServiceException {
067: this .manager = serviceManager;
068: this .cacheManager = (CacheManager) serviceManager
069: .lookup(CacheManager.ROLE);
070: this .widgetDefinitionBuilderSelector = (ServiceSelector) manager
071: .lookup(WidgetDefinitionBuilder.class.getName()
072: + "Selector");
073: }
074:
075: public void dispose() {
076: if (this .cacheManager != null) {
077: this .manager.release(this .cacheManager);
078: this .cacheManager = null;
079: }
080: this .manager = null;
081: }
082:
083: //
084: // Business methods
085: //
086:
087: public Library get(String sourceURI) throws LibraryException {
088: return get(sourceURI, null);
089: }
090:
091: public Library get(String sourceURI, String baseURI)
092: throws LibraryException {
093: SourceResolver sourceResolver = null;
094: Source source = null;
095: try {
096: try {
097: sourceResolver = (SourceResolver) manager
098: .lookup(SourceResolver.ROLE);
099: source = sourceResolver.resolveURI(sourceURI, baseURI,
100: null);
101: } catch (Exception e) {
102: throw new LibraryException(
103: "Unable to resolve library.", e,
104: new LocationImpl("[LibraryManager]", sourceURI));
105: }
106:
107: Library lib = (Library) this .cacheManager.get(source,
108: PREFIX);
109: if (lib != null && lib.dependenciesHaveChanged()) {
110: if (getLogger().isDebugEnabled()) {
111: getLogger().debug(
112: "Library IS REMOVED from cache: '"
113: + sourceURI + "' relative to '"
114: + baseURI + "'");
115: }
116: this .cacheManager.remove(source, PREFIX); // evict?
117: return null;
118: }
119:
120: if (getLogger().isDebugEnabled()) {
121: if (lib != null) {
122: getLogger()
123: .debug(
124: "Library IS in cache: '"
125: + sourceURI
126: + "' relative to '"
127: + baseURI + "'");
128: } else {
129: getLogger()
130: .debug(
131: "Library IS NOT in cache: '"
132: + sourceURI
133: + "' relative to '"
134: + baseURI + "'");
135: }
136: }
137:
138: return lib;
139: } finally {
140: if (source != null) {
141: sourceResolver.release(source);
142: }
143: if (sourceResolver != null) {
144: manager.release(sourceResolver);
145: }
146: }
147: }
148:
149: public Library load(String sourceURI) throws LibraryException {
150: return load(sourceURI, null);
151: }
152:
153: public Library load(String sourceURI, String baseURI)
154: throws LibraryException {
155: SourceResolver sourceResolver = null;
156: Source source = null;
157:
158: if (getLogger().isDebugEnabled()) {
159: getLogger().debug(
160: "Loading library: '" + sourceURI
161: + "' relative to '" + baseURI + "'");
162: }
163:
164: try {
165: try {
166: sourceResolver = (SourceResolver) manager
167: .lookup(SourceResolver.ROLE);
168: source = sourceResolver.resolveURI(sourceURI, baseURI,
169: null);
170: } catch (Exception e) {
171: throw new LibraryException(
172: "Unable to resolve library.", e,
173: new LocationImpl("[LibraryManager]", sourceURI));
174: }
175:
176: Library lib = (Library) this .cacheManager.get(source,
177: PREFIX);
178: if (lib != null && lib.dependenciesHaveChanged()) {
179: if (getLogger().isDebugEnabled()) {
180: getLogger().debug(
181: "Library IS EXPIRED in cache: '"
182: + sourceURI + "' relative to '"
183: + baseURI + "'");
184: }
185: lib = null;
186: }
187:
188: if (lib == null) {
189: if (getLogger().isDebugEnabled()) {
190: getLogger().debug(
191: "Library IS NOT in cache, loading: '"
192: + sourceURI + "' relative to '"
193: + baseURI + "'");
194: }
195:
196: try {
197: InputSource inputSource = new InputSource(source
198: .getInputStream());
199: inputSource.setSystemId(source.getURI());
200:
201: Document doc = DomHelper.parse(inputSource,
202: this .manager);
203: lib = newLibrary();
204: lib.buildLibrary(doc.getDocumentElement());
205:
206: this .cacheManager.set(lib, source, PREFIX);
207: } catch (Exception e) {
208: throw new LibraryException(
209: "Unable to load library.", e,
210: new LocationImpl("[LibraryManager]", source
211: .getURI()));
212: }
213: }
214:
215: return lib;
216: } finally {
217: if (source != null) {
218: sourceResolver.release(source);
219: }
220: if (sourceResolver != null) {
221: manager.release(sourceResolver);
222: }
223: }
224: }
225:
226: public Library newLibrary() {
227: Library lib = new Library(this , widgetDefinitionBuilderSelector);
228: lib.enableLogging(getLogger());
229: if (getLogger().isDebugEnabled()) {
230: getLogger().debug("Created a new library: " + lib);
231: }
232:
233: return lib;
234: }
235: }
|