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.transformation;
018:
019: import org.apache.avalon.framework.parameters.Parameters;
020: import org.apache.cocoon.ProcessingException;
021: import org.apache.cocoon.environment.ObjectModelHelper;
022: import org.apache.cocoon.environment.Request;
023: import org.apache.cocoon.environment.SourceResolver;
024: import org.xml.sax.Attributes;
025: import org.xml.sax.SAXException;
026: import org.xml.sax.helpers.AttributesImpl;
027:
028: import java.io.IOException;
029: import java.util.HashSet;
030: import java.util.Map;
031: import java.util.Set;
032: import java.util.StringTokenizer;
033:
034: /**
035: * @cocoon.sitemap.component.documentation
036: * Augments all <code>href</code> attributes with the full path to
037: * the request. You can optionally specify the <code>mount</code>
038: * parameter.
039: *
040: * The set of attributes to augment can be specified in the
041: * <code>attributes</code> parameter (defaults to href if
042: * <code>attributes</code> is not present). Any blank character, comma or colon
043: * is considered as a separator to delimit attributes.
044: *
045: * @cocoon.sitemap.component.name augment
046: * @cocoon.sitemap.component.logger sitemap.transformer.augment
047: *
048: * @since October 10, 2001
049: * @version $Id: AugmentTransformer.java 433543 2006-08-22 06:22:54Z crossley $
050: */
051: public class AugmentTransformer extends AbstractTransformer {
052:
053: protected Map objectModel;
054: protected Request request;
055: protected String baseURI;
056: protected Set augmentedAttributes;
057:
058: public static final String AUGMENTED_ATTRIBUTES = "attributes";
059:
060: public void setup(SourceResolver resolver, Map objectModel,
061: String source, Parameters parameters)
062: throws ProcessingException, SAXException, IOException {
063: this .objectModel = objectModel;
064: this .request = ObjectModelHelper.getRequest(this .objectModel);
065:
066: String mountPoint = parameters.getParameter("mount", null);
067:
068: StringBuffer uribuf = new StringBuffer();
069: boolean isSecure = this .request.isSecure();
070: int port = this .request.getServerPort();
071:
072: if (isSecure) {
073: uribuf.append("https://");
074: } else {
075: uribuf.append("http://");
076: }
077: uribuf.append(request.getServerName());
078:
079: if (isSecure) {
080: if (port != 443) {
081: uribuf.append(":").append(port);
082: }
083: } else {
084: if (port != 80) {
085: uribuf.append(":").append(port);
086: }
087: }
088: if (mountPoint == null) {
089: String requestedURI = this .request.getRequestURI();
090: requestedURI = requestedURI.substring(0, requestedURI
091: .lastIndexOf("/"));
092: uribuf.append(requestedURI);
093: uribuf.append("/");
094: } else {
095: uribuf.append(request.getContextPath());
096: uribuf.append("/");
097: uribuf.append(mountPoint);
098: }
099: this .baseURI = uribuf.toString();
100:
101: augmentedAttributes = new HashSet();
102: myAugmentedAttributes(parameters);
103:
104: if (getLogger().isDebugEnabled()) {
105: getLogger().debug(
106: "List of attributes to augment: "
107: + augmentedAttributes);
108: }
109: }
110:
111: public void startElement(String uri, String name, String qname,
112: Attributes attrs) throws SAXException {
113: AttributesImpl newAttrs = null;
114:
115: for (int i = 0, size = attrs.getLength(); i < size; i++) {
116: String attrName = attrs.getLocalName(i);
117: if (augmentedAttributes.contains(attrName)) {
118: String value = attrs.getValue(i);
119:
120: // Don't touch the attribute if it's an absolute URL
121: if (value.startsWith("http:")
122: || value.startsWith("https:")) {
123: continue;
124: }
125:
126: if (newAttrs == null) {
127: newAttrs = new AttributesImpl(attrs);
128: }
129:
130: String newValue = baseURI + value;
131: newAttrs.setValue(i, newValue);
132: }
133: }
134:
135: if (newAttrs == null) {
136: super .startElement(uri, name, qname, attrs);
137: } else {
138: super .startElement(uri, name, qname, newAttrs);
139: }
140: }
141:
142: /**
143: * Recyclable
144: */
145: public void recycle() {
146: this .objectModel = null;
147: this .request = null;
148: this .baseURI = null;
149: super .recycle();
150: }
151:
152: /**
153: * Parses list of attributes names in form of <code>attr1 attr2 attr3</code>
154: * and adds them to <code>augmentedAttributes</code>.
155: * @param parameters
156: */
157: private void myAugmentedAttributes(Parameters parameters) {
158: String augmentedAttributesStr = parameters.getParameter(
159: AUGMENTED_ATTRIBUTES, "href");
160: if (augmentedAttributesStr != null) {
161: StringTokenizer t = new StringTokenizer(
162: augmentedAttributesStr, " \t\r\n\f,:");
163: while (t.hasMoreTokens()) {
164: String attr = t.nextToken();
165: attr = attr.trim();
166: if (attr.length() > 0) {
167: augmentedAttributes.add(attr);
168: }
169: }
170: }
171: }
172: }
|