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.components.source.impl;
018:
019: import java.io.IOException;
020: import java.net.MalformedURLException;
021: import java.util.Map;
022:
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.components.source.SourceDescriptor;
032: import org.apache.excalibur.source.ModifiableTraversableSource;
033: import org.apache.excalibur.source.Source;
034: import org.apache.excalibur.source.SourceException;
035: import org.apache.excalibur.source.SourceFactory;
036: import org.apache.excalibur.source.SourceResolver;
037:
038: /**
039: * Creates RepositorySources.
040: */
041: public class RepositorySourceFactory extends AbstractLogEnabled
042: implements SourceFactory, Serviceable, Configurable, ThreadSafe {
043:
044: private ServiceManager m_manager;
045: private SourceResolver m_resolver;
046: private SourceDescriptor m_descriptor;
047: private String m_name;
048: private boolean m_isInitialized;
049:
050: public RepositorySourceFactory() {
051: }
052:
053: private synchronized void lazyInitialize() throws IOException {
054: if (m_isInitialized) {
055: return;
056: }
057: if (m_resolver == null) {
058: try {
059: m_resolver = (SourceResolver) m_manager
060: .lookup(SourceResolver.ROLE);
061: } catch (ServiceException e) {
062: throw new IOException(
063: "Resolver service is not available: "
064: + e.toString());
065: }
066: }
067: if (m_manager.hasService(SourceDescriptor.ROLE)) {
068: try {
069: m_descriptor = (SourceDescriptor) m_manager
070: .lookup(SourceDescriptor.ROLE);
071: } catch (ServiceException e) {
072: // impossible
073: }
074: } else {
075: m_descriptor = null;
076: if (getLogger().isInfoEnabled()) {
077: final String message = "SourceDescriptor is not available. "
078: + "RepositorySource will not support "
079: + "source properties.";
080: getLogger().info(message);
081: }
082: }
083: }
084:
085: /**
086: * Read the <code>name</code> attribute.
087: */
088: public void configure(final Configuration configuration)
089: throws ConfigurationException {
090: m_name = configuration.getAttribute("name");
091: }
092:
093: /**
094: * Lookup the SourceDescriptorManager service.
095: */
096: public void service(final ServiceManager manager) {
097: m_manager = manager;
098: }
099:
100: public Source getSource(String location, Map parameters)
101: throws IOException, MalformedURLException {
102:
103: if (getLogger().isDebugEnabled()) {
104: getLogger().debug(
105: "Creating RepositorySource for " + location);
106: }
107:
108: // lazy initialization due to circular dependency
109: if (!m_isInitialized) {
110: lazyInitialize();
111: }
112:
113: // assert location.startsWith(m_name)
114: location = location.substring(m_name.length() + 1);
115: Source source = m_resolver.resolveURI(location);
116: if (!(source instanceof ModifiableTraversableSource)) {
117: final String message = "Delegate should be a ModifiableTraversableSource";
118: throw new SourceException(message);
119: }
120:
121: return new RepositorySource(m_name,
122: (ModifiableTraversableSource) source, m_descriptor,
123: getLogger());
124: }
125:
126: public void release(final Source source) {
127: if (source instanceof RepositorySource) {
128: m_resolver.release(((RepositorySource) source).m_delegate);
129: }
130: }
131:
132: }
|