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.modules.input;
018:
019: import org.apache.avalon.framework.configuration.Configuration;
020: import org.apache.avalon.framework.configuration.ConfigurationException;
021: import org.apache.avalon.framework.thread.ThreadSafe;
022:
023: import org.apache.cocoon.environment.ObjectModelHelper;
024:
025: import java.util.Iterator;
026: import java.util.LinkedList;
027: import java.util.List;
028: import java.util.Map;
029: import java.util.Vector;
030:
031: /**
032: * ProjectPathModule provides relative and absolute paths with regards to the root of a project.
033: * <p>Config:
034: * <pre>
035: * <component-instance logger="core.modules.input"
036: * name="myproject"
037: * class="org.apache.cocoon.components.modules.input.ProjectPathModule">
038: * <uri-prefix>my/project/</uri-prefix>
039: * </component-instance>
040: * </pre>
041: * </p>
042: * <p>Usage:
043: * <pre>
044: * <map:transform src="skins/{forrest:skin}/xslt/fo/document2html.xsl">
045: * <map:parameter name="base" value="{myproject:relative}"/>
046: * </map:transform>
047: *</pre>
048: * And then prepend this to all image paths:
049: * <pre>
050: * ...
051: * <xsl:param name="base"/>
052: * ...
053: * <xsl:template match="img">
054: * <img src="{concat($base, @src)}" ...
055: * ...
056: * </xsl:template>
057: * </pre>
058: * Then if you are in my/project/some/folder/page.html, the image will have a relative path bact to the root of the project.
059: * <pre>
060: * <img src="../../imagename.png"/>
061: * </pre>
062: * Using 'myproject:path' would have given you: /some/folder/page.html<br/>
063: * Using 'myproject:folder' would have given you: /some/folder/
064: * </p>
065: *
066: * @version $Id$
067: *
068: */
069: public class ProjectPathModule extends AbstractInputModule implements
070: ThreadSafe {
071:
072: protected static final String PROJECT_PARAM_NAME = "uri-prefix";
073: protected static final String PROJECT_PARAM_DEFAULT = "/";
074:
075: protected String projectBase;
076:
077: final static Vector returnNames;
078: static {
079: Vector tmp = new Vector();
080: tmp.add("relative");
081: tmp.add("path");
082: tmp.add("folder");
083: returnNames = tmp;
084: }
085:
086: /**
087: * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
088: */
089: public void configure(Configuration conf)
090: throws ConfigurationException {
091: this .projectBase = conf.getChild(PROJECT_PARAM_NAME).getValue();
092: if (getLogger().isDebugEnabled()) {
093: getLogger().debug(
094: "Configuration supplied: " + this .projectBase);
095: }
096: if (this .projectBase == null) {
097: this .projectBase = PROJECT_PARAM_DEFAULT;
098: if (getLogger().isWarnEnabled()) {
099: getLogger().warn(
100: "No configuration supplied, using default: "
101: + PROJECT_PARAM_DEFAULT);
102: }
103: }
104: if (this .projectBase.length() == 0) {
105: this .projectBase = PROJECT_PARAM_DEFAULT;
106: if (getLogger().isWarnEnabled()) {
107: getLogger().warn(
108: "Empty configuration supplied, using default: "
109: + PROJECT_PARAM_DEFAULT);
110: }
111: }
112: }
113:
114: /**
115: * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
116: */
117: public Object getAttribute(String name, Configuration modeConf,
118: Map objectModel) throws ConfigurationException {
119: String uri = ObjectModelHelper.getRequest(objectModel)
120: .getServletPath();
121: StringBuffer result = new StringBuffer(uri.length());
122: int baseIndex = uri.indexOf(this .projectBase);
123: if (baseIndex != -1) {
124: uri = uri.substring(baseIndex + this .projectBase.length());
125: } else {
126: throw new ConfigurationException(
127: "No project-base path found in URI");
128: }
129: try {
130: // provide a relative path back to the project
131: if (name.startsWith("relative")) {
132: int nextIndex = 0;
133: while ((nextIndex = uri.indexOf('/', nextIndex) + 1) > 0) {
134: result.append("../");
135: }
136: } else if (name.startsWith("path")) {
137: // provide the full path from the project
138: result.append("/");
139: result.append(uri);
140: } else if (name.startsWith("folder")) {
141: // provide the folder path from the project
142: result.append("/");
143: result.append(uri
144: .substring(0, uri.lastIndexOf("/") + 1));
145: } else {
146: if (getLogger().isWarnEnabled()) {
147: getLogger().warn("Invalid verb: " + name);
148: }
149: }
150: return result;
151: } catch (final Exception mue) {
152: throw new ConfigurationException(
153: "Problems resolving project path.", mue);
154: }
155: }
156:
157: /**
158: * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeNames(org.apache.avalon.framework.configuration.Configuration, java.util.Map)
159: */
160: public Iterator getAttributeNames(Configuration modeConf,
161: Map objectModel) throws ConfigurationException {
162: return ProjectPathModule.returnNames.iterator();
163: }
164:
165: /**
166: * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeValues(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
167: */
168: public Object[] getAttributeValues(String name,
169: Configuration modeConf, Map objectModel)
170: throws ConfigurationException {
171: List values = new LinkedList();
172: values.add(this.getAttribute(name, modeConf, objectModel));
173:
174: return values.toArray();
175: }
176: }
|