1 16 package org.apache.cocoon.portal.transformation; 17 18 import java.io.IOException ; 19 import java.net.MalformedURLException ; 20 import java.util.Map ; 21 import java.util.Stack ; 22 23 import org.apache.avalon.framework.parameters.Parameters; 24 import org.apache.avalon.framework.service.ServiceException; 25 import org.apache.avalon.framework.service.ServiceManager; 26 import org.apache.avalon.framework.service.Serviceable; 27 import org.apache.cocoon.ProcessingException; 28 import org.apache.cocoon.environment.ObjectModelHelper; 29 import org.apache.cocoon.environment.SourceResolver; 30 import org.apache.cocoon.portal.Constants; 31 import org.apache.cocoon.portal.coplet.CopletInstanceData; 32 import org.apache.cocoon.transformation.AbstractTransformer; 33 import org.apache.cocoon.xml.AttributesImpl; 34 import org.xml.sax.Attributes ; 35 import org.xml.sax.SAXException ; 36 37 59 public class LinkTransformer 60 extends AbstractTransformer 61 implements Serviceable { 62 63 66 public static final String NAMESPACE_PREFIX = "ev"; 67 68 71 protected String copletIdParamString; 72 73 76 protected String portalNameParamString; 77 78 81 protected CopletInstanceData copletInstanceData; 82 83 86 protected String documentBase; 87 88 91 protected Stack elementStack = new Stack (); 92 93 96 protected ServiceManager manager; 97 98 101 public void service(ServiceManager manager) throws ServiceException { 102 this.manager = manager; 103 } 104 105 106 protected String prefix; 107 108 109 protected boolean ignoreTargetSelf; 110 111 114 public void setup(SourceResolver resolver, 115 Map objectModel, 116 String src, 117 Parameters par) 118 throws ProcessingException, SAXException , IOException { 119 this.ignoreTargetSelf = par.getParameterAsBoolean("ignore-target-self", false); 120 121 this.copletInstanceData = 122 ProxyTransformer.getInstanceData( 123 this.manager, 124 objectModel, 125 par); 126 this.copletIdParamString = 127 ProxyTransformer.COPLETID + "=" + copletInstanceData.getId(); 128 129 Map context = (Map ) objectModel.get(ObjectModelHelper.PARENT_CONTEXT); 130 this.portalNameParamString = 131 ProxyTransformer.PORTALNAME 132 + "=" 133 + (String ) context.get(Constants.PORTAL_NAME_KEY); 134 this.prefix = par.getParameter("prefix", ProxyTransformer.PROXY_PREFIX); 135 } 136 137 141 public void recycle() { 142 super.recycle(); 143 this.copletInstanceData = null; 144 this.elementStack.clear(); 145 this.copletIdParamString = null; 146 this.portalNameParamString = null; 147 } 148 149 152 public void startDocument() throws SAXException { 153 super.startDocument(); 154 documentBase = 155 (String )copletInstanceData.getAttribute(ProxyTransformer.DOCUMENT_BASE); 156 super.startPrefixMapping(NAMESPACE_PREFIX, 157 NewEventLinkTransformer.NAMESPACE_URI); 158 } 159 160 163 public void endDocument() throws SAXException { 164 super.endPrefixMapping(NAMESPACE_PREFIX); 165 super.endDocument(); 166 } 167 168 171 public void startElement(String uri, String name, String raw, 172 Attributes attributes) 173 throws SAXException { 174 175 if ("form".equalsIgnoreCase(name)) { 176 handleTag( 177 "action", 178 uri, 179 name, 180 raw, 181 attributes, 182 true, 183 (attributes.getIndex("target") > -1)); 184 } else if ("script".equalsIgnoreCase(name)) { 185 handleTag("src", uri, name, raw, attributes, false, false); 186 } else if ("img".equalsIgnoreCase(name)) { 187 handleTag("src", uri, name, raw, attributes, false, false); 188 } else if ("link".equalsIgnoreCase(name)) { 189 handleTag("href", uri, name, raw, attributes, false, false); 190 } else if ("a".equalsIgnoreCase(name)) { 191 boolean direct; 192 final String v = attributes.getValue("target"); 193 if ( v == null || (this.ignoreTargetSelf && v.equals("self")) ) { 194 direct = false; 195 } else { 196 direct = true; 197 } 198 handleTag("href", uri, name, raw, attributes, true, direct); 199 } else if ("menu-item".equalsIgnoreCase(name)) { 200 handleTag("href", uri, name, raw, attributes, true, false); 201 } else if ("input".equalsIgnoreCase(name)) { 202 handleTag("src", uri, name, raw, attributes, false, false); 203 } else if ("applet".equalsIgnoreCase(name)) { 204 if (attributes.getIndex("codebase") > -1) { 205 handleTag("codebase", uri, name, raw, attributes, false, true); 206 } 207 } else { 208 super.startElement(uri, name, raw, attributes); 209 } 210 } 211 212 215 public void endElement(String uri, String name, String raw) 216 throws SAXException { 217 String elementName = null; 218 219 if (!elementStack.empty()) { 220 elementName = (String ) elementStack.peek(); 221 } 222 223 if (elementName != null && elementName.equals(name)) { 224 elementStack.pop(); 225 super.endElement( 226 NewEventLinkTransformer.NAMESPACE_URI, 227 NewEventLinkTransformer.EVENT_ELEM, 228 NAMESPACE_PREFIX + ":" + NewEventLinkTransformer.EVENT_ELEM); 229 } else { 230 super.endElement(uri, name, raw); 231 } 232 } 233 234 266 public void handleTag(String attributeName, 267 String uri, 268 String elementName, 269 String raw, 270 Attributes attributes, 271 boolean eventLink, 272 boolean direct) 273 throws SAXException { 274 String remoteURI = attributes.getValue(attributeName); 275 276 if ((remoteURI == null) 277 || remoteURI.startsWith("http://") 278 || remoteURI.startsWith("https://") 279 || remoteURI.startsWith("#") 280 || remoteURI.startsWith("ftp://") 281 || remoteURI.startsWith("javascript:") 282 || remoteURI.startsWith("mailto:")) { 283 super.startElement(uri, elementName, raw, attributes); 284 } else { 285 boolean evalTarget; 286 final String v = attributes.getValue("target"); 287 if ( v == null || (this.ignoreTargetSelf && v.equals("self")) ) { 288 evalTarget = false; 289 } else { 290 evalTarget = true; 291 } 292 if (evalTarget || direct) { 293 try { 294 remoteURI = 295 ProxyTransformer.resolveURI(remoteURI, documentBase); 296 eventLink = false; 297 } catch (MalformedURLException ex) { 298 throw new SAXException ( 299 "Invalid URL encountered: " + remoteURI, 300 ex); 301 } 302 } else { 303 remoteURI = this.buildUrlString(remoteURI, !eventLink); 304 } 305 306 Attributes newAttributes = 307 modifyLinkAttribute(attributeName, remoteURI, attributes); 308 309 if (eventLink) { 310 this.startEventLinkElement( 311 elementName, 312 attributeName, 313 newAttributes); 314 } else { 315 super.startElement(uri, elementName, raw, newAttributes); 316 } 317 } 318 } 319 320 327 protected Attributes modifyLinkAttribute(String attribute, 328 String remoteURI, 329 Attributes attributes) { 330 AttributesImpl newAttributes = new AttributesImpl(attributes); 331 332 int index = newAttributes.getIndex(attribute); 333 newAttributes.setValue(index, remoteURI); 334 return newAttributes; 335 } 336 337 345 protected void startEventLinkElement(String element, 346 String attribute, 347 Attributes attributes) 348 throws SAXException { 349 elementStack.push(element); 350 AttributesImpl eventAttributes = null; 351 if (attributes instanceof AttributesImpl) { 352 eventAttributes = (AttributesImpl) attributes; 353 } else { 354 eventAttributes = new AttributesImpl(attributes); 355 } 356 eventAttributes.addCDATAAttribute(NewEventLinkTransformer.ATTRIBUTE_ATTR, attribute); 357 eventAttributes.addCDATAAttribute(NewEventLinkTransformer.ELEMENT_ATTR, element); 358 eventAttributes.addCDATAAttribute("coplet", this.copletInstanceData.getId()); 359 360 super.startElement( 361 NewEventLinkTransformer.NAMESPACE_URI, 362 NewEventLinkTransformer.EVENT_ELEM, 363 NAMESPACE_PREFIX + ":" + NewEventLinkTransformer.EVENT_ELEM, 364 eventAttributes); 365 } 366 367 374 protected String buildUrlString(String uri, 375 boolean applyPrefixAndPortalParams) { 376 StringBuffer uriBuffer = new StringBuffer (uri.length()); 377 378 int index_semikolon = uri.indexOf(";"); 379 int index_question = uri.indexOf("?"); 380 381 if ((index_semikolon > -1)) { 382 String sessionToken = 383 uri.substring( 384 index_semikolon + 1, 385 (index_question == -1 ? uri.length() : index_question)); 386 copletInstanceData.getPersistentAspectData().put( 387 ProxyTransformer.SESSIONTOKEN, 388 sessionToken); 389 } 390 391 if (applyPrefixAndPortalParams) { 392 uriBuffer.append(this.prefix); 393 } 394 395 uriBuffer.append(uri); 396 397 if (applyPrefixAndPortalParams) { 398 uriBuffer.append((index_question == -1 ? '?' : '&')); 399 uriBuffer.append(this.copletIdParamString); 400 uriBuffer.append('&'); 401 uriBuffer.append(this.portalNameParamString); 402 } 403 404 return uriBuffer.toString(); 405 } 406 } | Popular Tags |