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:
018: package org.apache.cocoon.components.modules.input;
019:
020: import org.apache.avalon.framework.service.ServiceException;
021: import org.apache.avalon.framework.service.ServiceManager;
022: import org.apache.avalon.framework.service.Serviceable;
023:
024: import org.apache.avalon.framework.configuration.Configuration;
025: import org.apache.avalon.framework.configuration.ConfigurationException;
026: import org.apache.avalon.framework.thread.ThreadSafe;
027: import org.apache.excalibur.source.SourceResolver;
028:
029: import java.io.IOException;
030: import java.util.Iterator;
031: import java.util.LinkedList;
032: import java.util.List;
033: import java.util.Map;
034: import java.util.Vector;
035:
036: /**
037: * ContextPathModule provides a real filesystem path for a virtual
038: * context-relative path. If this mapping cannot be performed (e.g. Cocoon is
039: * running in a .war file), <code>null</code> will be returned. Compared to
040: * the {@link RealPathModule} this module is able to provide the "real" absolute
041: * path even if the application is mounted outside the webapp tree of Cocoon.
042: * <p>
043: * Note: the primary use for this is to support external code that wants a
044: * filesystem path. For example, The FOP 0.20.x serializer doesn't like
045: * relative image paths, and doesn't understand Cocoon URLs (context:, cocoon:
046: * etc). So we pass the *2fo.xsl stylesheet a real filesystem path to where we
047: * keep our images:
048: * </p>
049: * <p>
050: * A absolute path argument like {contextpath:/resources} will be resolved
051: * from the root context path (ie. COCOON_HOME/build/webapp) whereas a relative
052: * path attribute like {contextpath:./resources} will be resolved from the
053: * location of the sitemap that uses it. If that sitemap is mounted outside the
054: * usual COCOON_HOME/build/webapp the path resolved with this modules points to
055: * the correct location.
056: * </p>
057: * <p>
058: * <pre>
059: * <map:transform src="skins/{forrest:skin}/xslt/fo/document2fo.xsl">
060: * <map:parameter name="basedir" value="{contextpath:resources}/"/>
061: * </map:transform>
062: * </pre>
063: *
064: * And then prepend this to all image paths:
065: * <pre>
066: * ...
067: * <xsl:param name="basedir" select="''"/>
068: * ...
069: * <xsl:template match="img">
070: * <xsl:variable name="imgpath" select="concat($basedir, @src)"/>
071: * <fo:external-graphic src="{$imgpath}" ...
072: * ...
073: * </xsl:template>
074: * </pre>
075: * </p>
076: *
077: * @author <a href="mailto:giacomo at apache dor org">Giacomo Pati</a>
078: * @version $Id: ContextPathModule.java 359191 2005-12-27 08:51:54Z cziegeler $
079: */
080: public class ContextPathModule extends AbstractInputModule implements
081: Serviceable, ThreadSafe {
082:
083: private ServiceManager m_manager;
084: private SourceResolver m_resolver;
085:
086: final static Vector returnNames;
087: static {
088: Vector tmp = new Vector();
089: tmp.add("contextPath");
090: returnNames = tmp;
091: }
092:
093: /** (non-Javadoc)
094: * * @see Serviceable#service(ServiceManager)
095: * */
096: public void service(ServiceManager manager) throws ServiceException {
097: m_manager = manager;
098: m_resolver = (SourceResolver) m_manager
099: .lookup(SourceResolver.ROLE);
100: }
101:
102: /** (non-Javadoc)
103: *
104: * @see org.apache.avalon.framework.activity.Disposable#dispose()
105: *
106: */
107: public void dispose() {
108: super .dispose();
109: if (this .m_manager != null) {
110: this .m_manager.release(this .m_resolver);
111: this .m_manager = null;
112: this .m_resolver = null;
113: }
114: }
115:
116: public Object getAttribute(String name, Configuration modeConf,
117: Map objectModel) throws ConfigurationException {
118: try {
119: if (name.startsWith("/")) {
120: return m_resolver.resolveURI("context:/" + name)
121: .getURI().substring("file:".length());
122: }
123: return m_resolver.resolveURI(name).getURI().substring(
124: "file:".length());
125: } catch (final IOException mue) {
126: throw new ConfigurationException("Cannot resolve realpath",
127: mue);
128: }
129: }
130:
131: public Iterator getAttributeNames(Configuration modeConf,
132: Map objectModel) throws ConfigurationException {
133:
134: return ContextPathModule.returnNames.iterator();
135: }
136:
137: public Object[] getAttributeValues(String name,
138: Configuration modeConf, Map objectModel)
139: throws ConfigurationException {
140:
141: List values = new LinkedList();
142: values.add(this.getAttribute(name, modeConf, objectModel));
143:
144: return values.toArray();
145: }
146: }
|