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.logger.AbstractLogEnabled;
024: import org.apache.avalon.framework.service.ServiceException;
025: import org.apache.avalon.framework.service.ServiceManager;
026: import org.apache.avalon.framework.service.Serviceable;
027: import org.apache.avalon.framework.thread.ThreadSafe;
028: import org.apache.excalibur.source.Source;
029: import org.apache.excalibur.source.SourceException;
030: import org.apache.excalibur.source.SourceFactory;
031: import org.apache.excalibur.source.SourceResolver;
032:
033: /**
034: * Implementation of a {@link Source} that gets its content from
035: * a ZIP archive.
036: *
037: * <p>
038: * A ZIP source can be obtained using the <code>zip:</code> pseudo-protocol.
039: * The syntax for protocol is
040: * <pre>
041: * zip:[archive-url]!/[file-path]
042: * </pre>
043: *
044: * Where, <code>archive-url</code> can be any supported Cocoon URL, and
045: * <code>file-path</code> is the path to the file within archive.
046: *
047: * @author <a href="http://apache.org/~reinhard">Reinhard Poetz</a>
048: * @version CVS $Id: ZipSourceFactory.java 517444 2007-03-12 22:49:37Z joerg $
049: * @since 2.1.8
050: */
051: public class ZipSourceFactory extends AbstractLogEnabled implements
052: SourceFactory, ThreadSafe, Serviceable {
053:
054: private ServiceManager manager;
055:
056: public void service(ServiceManager manager) throws ServiceException {
057: this .manager = manager;
058: }
059:
060: public Source getSource(String location, Map parameters)
061: throws IOException, MalformedURLException {
062: // Checks URL syntax
063: int protocolEnd = location.indexOf(":");
064: if (protocolEnd == -1) {
065: throw new MalformedURLException(
066: "Protocol ':' separator is missing in URL: "
067: + location);
068: }
069:
070: int archiveEnd = location.lastIndexOf("!/");
071: if (archiveEnd == -1) {
072: throw new MalformedURLException(
073: "File path '!/' separator is missing in URL: "
074: + location);
075: }
076:
077: // Get protocol. Protocol is configurable via cocoon.xconf
078: final String protocol = location.substring(0, protocolEnd);
079:
080: // Get archive URL
081: final String archiveURL = location.substring(protocolEnd + 1,
082: archiveEnd);
083:
084: // Get file path
085: final String filePath = location.substring(archiveEnd + 2);
086:
087: // Resolve archive source
088: Source archive;
089: SourceResolver resolver = null;
090: try {
091: resolver = (SourceResolver) this .manager
092: .lookup(SourceResolver.ROLE);
093: archive = resolver.resolveURI(archiveURL);
094: } catch (ServiceException se) {
095: throw new SourceException(
096: "SourceResolver is not available.", se);
097: } finally {
098: this .manager.release(resolver);
099: }
100:
101: return new ZipSource(protocol, archive, filePath);
102: }
103:
104: public void release(Source source) {
105: SourceResolver resolver = null;
106: try {
107: resolver = (SourceResolver) this .manager
108: .lookup(SourceResolver.ROLE);
109: ((ZipSource) source).dispose(resolver);
110: } catch (ServiceException e) {
111: // Ignored
112: getLogger()
113: .error(
114: "ServiceException while looking up SourceResolver in release()",
115: e);
116: } finally {
117: this.manager.release(resolver);
118: }
119: }
120:
121: }
|