1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.osoco.cowarp.portal.transformation;
17
18 import java.io.IOException;
19 import java.util.Map;
20
21 import org.apache.avalon.framework.parameters.Parameters;
22 import org.apache.cocoon.ProcessingException;
23 import org.apache.cocoon.environment.SourceResolver;
24 import org.apache.cocoon.portal.coplet.CopletInstanceData;
25 import org.apache.cocoon.portal.transformation.AbstractCopletTransformer;
26 import org.apache.cocoon.portal.transformation.CopletTransformer;
27 import org.apache.cocoon.xml.AttributesImpl;
28 import org.apache.excalibur.source.SourceUtil;
29 import org.xml.sax.Attributes;
30 import org.xml.sax.SAXException;
31
32 /***
33 * A new transformer that is not finished yet.
34 *
35 * @author <a href="mailto:cziegeler.at.osoco.org">Carsten Ziegeler</a>
36 *
37 * @version CVS $Id: HTMLEventTransformer.java,v 1.6 2005/02/21 10:33:00 cziegeler Exp $
38 */
39 public class HTMLEventTransformer
40 extends AbstractCopletTransformer {
41
42 /***
43 * Default namespace prefix.
44 */
45 public static final String NAMESPACE_PREFIX = "ct";
46
47 /***
48 * Default prefix for links to resources (images etc.).
49 */
50 public static final String LINK_PREFIX = "htmllink-";
51
52 /***
53 * The coplet instance data.
54 */
55 protected CopletInstanceData copletInstanceData;
56
57 /*** The prefix for the generated link events. */
58 protected String namespacePrefix;
59
60 /*** The namespace for the generated link events. */
61 protected String namespace;
62
63 /*** The prefix for links to resources. */
64 protected String linkPrefix;
65
66 /*** The temporary attribute used to store the uri. */
67 protected String attributeName;
68
69 /*** The jxpath for the attribute. */
70 protected String jxPath;
71
72 /*** Rewrite absolut links. */
73 protected boolean rewriteAbsoluteLinks;
74
75
76
77
78 public void setup(final SourceResolver resolver,
79 final Map objectModel,
80 final String src,
81 final Parameters par)
82 throws ProcessingException, SAXException, IOException {
83 this.copletInstanceData = this.getCopletInstanceData();
84 this.namespacePrefix = par.getParameter("ns-prefix", NAMESPACE_PREFIX);
85 this.namespace = par.getParameter("namespace", CopletTransformer.NAMESPACE_URI);
86 this.linkPrefix = par.getParameter("prefix", LINK_PREFIX);
87
88 this.attributeName = par.getParameter("attribute-name", "application-uri");
89 this.jxPath = "temporaryAttributes/" + this.attributeName;
90 this.rewriteAbsoluteLinks = par.getParameterAsBoolean("rewrite-absolute-links", true);
91 }
92
93
94
95
96 public void recycle() {
97 super.recycle();
98 this.copletInstanceData = null;
99 this.namespacePrefix = null;
100 this.namespace = null;
101 this.linkPrefix = null;
102 this.attributeName = null;
103 this.jxPath = null;
104 }
105
106
107
108
109 public void startDocument() throws SAXException {
110 super.startDocument();
111 super.startPrefixMapping(this.namespacePrefix, this.namespace);
112 }
113
114
115
116
117 public void endDocument() throws SAXException {
118 super.endPrefixMapping(this.namespacePrefix);
119 super.endDocument();
120 }
121
122
123
124
125 public void startElement(final String uri, final String name, final String raw,
126 final Attributes attributes)
127 throws SAXException {
128
129 Attributes converted = attributes;
130
131 if ("form".equalsIgnoreCase(name)) {
132 converted = this.handleTag("action", attributes, (attributes.getIndex("target") > -1), "html-form");
133 } else if ("script".equalsIgnoreCase(name)) {
134 converted = this.handleTag("src", attributes, false, null);
135 } else if ("img".equalsIgnoreCase(name)) {
136 converted = this.handleTag("src", attributes, false, null);
137 } else if ("a".equalsIgnoreCase(name)) {
138 converted = this.handleTag("href", attributes, (attributes.getIndex("target") > -1), "html-link");
139 } else if ("input".equalsIgnoreCase(name)) {
140 converted = this.handleTag("src", attributes, false, null);
141 } else if ("applet".equalsIgnoreCase(name) && attributes.getIndex("codebase") > -1) {
142 converted = this.handleTag("codebase", attributes, true, null);
143 }
144
145 if (converted == null) {
146 this.stack.push(Boolean.TRUE);
147 } else {
148 this.stack.push(Boolean.FALSE);
149 super.startElement(uri, name, raw, converted);
150 }
151 }
152
153
154
155
156 public void endElement(final String uri, final String name, final String raw)
157 throws SAXException {
158 Boolean rewrite = (Boolean)stack.pop();
159 if ( rewrite.booleanValue() ) {
160 super.endElement(this.namespace,
161 CopletTransformer.LINK_ELEM,
162 this.namespacePrefix + ':' + CopletTransformer.LINK_ELEM);
163 } else {
164 super.endElement(uri, name, raw);
165 }
166 }
167
168 /***
169 * Handle a link/reference.
170 * @param attributeName The name of the attribute.
171 * @param attributes All attributes.
172 * @param direct Should the link point directly to the resource.
173 * @param aFormat The format used to create the link.
174 * @return The new attributes set.
175 * @throws SAXException If something goes wrong.
176 */
177 public Attributes handleTag(final String attributeName,
178 final Attributes attributes,
179 final boolean direct,
180 final String aFormat)
181 throws SAXException {
182 String format = aFormat;
183 String remoteURI = attributes.getValue(attributeName);
184
185 final boolean needsRewrite = this.linkNeedsRewrite(remoteURI, attributes);
186 if ( !needsRewrite ) {
187 return attributes;
188 }
189 if (direct) {
190 remoteURI = this.getLink((String)this.copletInstanceData.getTemporaryAttribute(this.attributeName), remoteURI);
191 format = null;
192 } else {
193 if ( format == null ) {
194 final StringBuffer uriBuffer = new StringBuffer(remoteURI.length());
195
196 uriBuffer.append(this.linkPrefix);
197
198 uriBuffer.append(remoteURI);
199
200 final int indexQuestion = remoteURI.indexOf("?");
201 uriBuffer.append((indexQuestion == -1 ? '?' : '&'));
202 uriBuffer.append(this.copletInstanceData.getId());
203 uriBuffer.append('&');
204 uriBuffer.append(this.getPortalService().getPortalName());
205
206 remoteURI = uriBuffer.toString();
207 } else {
208 remoteURI = this.getLink((String)this.copletInstanceData.getTemporaryAttribute(this.attributeName), remoteURI);
209 }
210 }
211
212 final AttributesImpl eventAttributes;
213 if (attributes instanceof AttributesImpl) {
214 eventAttributes = (AttributesImpl) attributes;
215 } else {
216 eventAttributes = new AttributesImpl(attributes);
217 }
218
219 final int index = eventAttributes.getIndex(attributeName);
220 eventAttributes.setValue(index, remoteURI);
221
222 if (format != null) {
223 eventAttributes.addCDATAAttribute("path", this.jxPath);
224 eventAttributes.addCDATAAttribute("value", remoteURI);
225 eventAttributes.addCDATAAttribute("coplet", this.copletInstanceData.getId());
226 eventAttributes.addCDATAAttribute("format", format);
227
228 super.startElement(this.namespace,
229 CopletTransformer.LINK_ELEM,
230 this.namespacePrefix + ':' + CopletTransformer.LINK_ELEM,
231 attributes);
232 return null;
233 }
234 return eventAttributes;
235 }
236
237 /***
238 * External links, anchors and links like mailto or links using
239 * different protocols like ftp are not rewritten.
240 *
241 * @param link The original link.
242 * @param attributes attributes of the node.
243 * @return true if the link should be rewritten.
244 */
245 protected boolean linkNeedsRewrite(final String link, final Attributes attributes) {
246
247 final String external = attributes.getValue("external");
248 if (external != null && external.trim().length() > 0
249 && external.trim().toLowerCase().equals ("true") ) {
250 return false;
251 }
252
253
254
255 if ( link == null
256 || link.startsWith("mailto:")
257 || link.startsWith("ftp://")
258 || link.startsWith("javascript:")
259 || link.startsWith("#") ) {
260 return false;
261 }
262
263
264 if ( !this.rewriteAbsoluteLinks ) {
265 if ( link.startsWith("http://") || link.startsWith("https://") ) {
266 return false;
267 }
268 }
269
270 return true;
271 }
272
273 /***
274 * Absolutize the link.
275 * @param base The base for the relative link
276 * @param link The relative link
277 * @return The absolute link
278 */
279 protected String getLink(final String base, final String link) {
280 final String v = SourceUtil.absolutize(base, link);
281 return v;
282 }
283
284 }