1 16 package org.apache.cocoon.transformation; 17 18 import java.io.IOException ; 19 import java.util.Map ; 20 import org.apache.avalon.framework.configuration.Configurable; 21 import org.apache.avalon.framework.configuration.Configuration; 22 import org.apache.avalon.framework.configuration.ConfigurationException; 23 import org.apache.avalon.framework.parameters.Parameters; 24 import org.apache.cocoon.ProcessingException; 25 import org.apache.cocoon.caching.CacheableProcessingComponent; 26 import org.apache.cocoon.environment.ObjectModelHelper; 27 import org.apache.cocoon.environment.Request; 28 import org.apache.cocoon.environment.Response; 29 import org.apache.cocoon.environment.Session; 30 import org.apache.cocoon.environment.SourceResolver; 31 import org.apache.cocoon.transformation.AbstractTransformer; 32 import org.apache.excalibur.source.SourceValidity; 33 import org.apache.excalibur.source.impl.validity.NOPValidity; 34 import org.apache.regexp.RE; 35 import org.apache.regexp.RESyntaxException; 36 import org.xml.sax.Attributes ; 37 import org.xml.sax.SAXException ; 38 import org.xml.sax.helpers.AttributesImpl ; 39 40 90 public class EncodeURLTransformer 91 extends AbstractTransformer 92 implements Configurable, CacheableProcessingComponent { 93 94 98 public final static String EXCLUDE_NAME = "exclude-name"; 99 100 104 public final static String INCLUDE_NAME = "include-name"; 105 106 110 public final static String EXCLUDE_NAME_DEFAULT = "img/@src"; 111 112 116 public final static String INCLUDE_NAME_DEFAULT = ".*/@href|.*/@action|frame/@src"; 117 118 private String includeNameConfigure = INCLUDE_NAME_DEFAULT; 119 private String excludeNameConfigure = EXCLUDE_NAME_DEFAULT; 120 121 private ElementAttributeMatching elementAttributeMatching; 122 private Response response; 123 private boolean isEncodeURLNeeded; 124 private Session session; 125 126 133 protected void checkForEncoding(Request request) { 134 this.session = request.getSession(false); 135 this.isEncodeURLNeeded = false; 136 137 if ( null != this.session ) { 138 if ( request.isRequestedSessionIdFromURL() || this.session.isNew()) { 141 this.isEncodeURLNeeded = true; 142 } 143 } 144 } 145 146 157 public void setup(SourceResolver resolver, Map objectModel, String source, Parameters parameters) 158 throws ProcessingException, SAXException , IOException { 159 160 this.checkForEncoding(ObjectModelHelper.getRequest(objectModel)); 161 162 if (this.isEncodeURLNeeded) { 163 this.response = ObjectModelHelper.getResponse(objectModel); 164 165 final String includeName = parameters.getParameter(INCLUDE_NAME, 168 this.includeNameConfigure); 169 final String excludeName = parameters.getParameter(EXCLUDE_NAME, 170 this.excludeNameConfigure); 171 try { 172 this.elementAttributeMatching = new ElementAttributeMatching(includeName, excludeName); 173 } catch (RESyntaxException reex) { 174 final String message = "Cannot parse include-name: " + includeName + " " + 175 "or exclude-name: " + excludeName + "!"; 176 throw new ProcessingException(message, reex); 177 } 178 } 179 } 180 181 182 188 public void configure(Configuration configuration) throws ConfigurationException { 189 Configuration child; 190 191 child = configuration.getChild(INCLUDE_NAME); 192 this.includeNameConfigure = child.getValue(INCLUDE_NAME_DEFAULT); 193 194 child = configuration.getChild(EXCLUDE_NAME); 195 this.excludeNameConfigure = child.getValue(EXCLUDE_NAME_DEFAULT); 196 197 if (this.includeNameConfigure == null) { 198 String message = "Configure " + INCLUDE_NAME + "!"; 199 throw new ConfigurationException(message); 200 } 201 if (this.excludeNameConfigure == null) { 202 String message = "Configure " + EXCLUDE_NAME + "!"; 203 throw new ConfigurationException(message); 204 } 205 } 206 207 208 211 public void recycle() { 212 super.recycle(); 213 this.response = null; 214 this.session = null; 215 this.elementAttributeMatching = null; 216 } 217 218 219 225 public java.io.Serializable getKey() { 226 if (this.isEncodeURLNeeded) { 227 return null; 228 } else { 229 return "1"; 230 } 231 } 232 233 239 public SourceValidity getValidity() { 240 if (this.isEncodeURLNeeded) { 241 return null; 242 } else { 243 return NOPValidity.SHARED_INSTANCE; 244 } 245 } 246 247 256 public void startElement(String uri, String name, String raw, Attributes attributes) 257 throws SAXException { 258 if (this.isEncodeURLNeeded && this.elementAttributeMatching != null) { 259 String lname = name; 260 if (attributes != null && attributes.getLength() > 0) { 261 AttributesImpl new_attributes = new AttributesImpl (attributes); 262 for (int i = 0; i < new_attributes.getLength(); i++) { 263 String attr_lname = new_attributes.getLocalName(i); 264 265 String value = new_attributes.getValue(i); 266 267 if (elementAttributeMatching.matchesElementAttribute(lname, attr_lname, value)) { 268 final String new_value = this.encodeURL(value); 271 if (getLogger().isDebugEnabled()) { 272 this.getLogger().debug("element/@attribute matches: " + name + "/@" + attr_lname); 273 this.getLogger().debug("encodeURL: " + value + " -> " + new_value); 274 } 275 new_attributes.setValue(i, new_value); 276 } 277 } 278 super.contentHandler.startElement(uri, name, raw, new_attributes); 280 return; 281 } 282 } 283 super.contentHandler.startElement(uri, name, raw, attributes); 285 } 286 287 297 private String encodeURL(String url) { 298 String encoded_url; 299 if (this.response != null) { 300 if (this.session != null && url.indexOf(this.session.getId()) > -1) { 302 encoded_url = url; 304 } else { 305 encoded_url = this.response.encodeURL(url); 307 } 308 } else { 309 encoded_url = url; 310 } 311 return encoded_url; 312 } 313 314 325 public static class ElementAttributeMatching { 326 330 protected RE includeNameRE; 331 335 protected RE excludeNameRE; 336 337 338 345 public ElementAttributeMatching(String includeName, String excludeName) throws RESyntaxException { 346 includeNameRE = new RE(includeName, RE.MATCH_CASEINDEPENDENT); 347 excludeNameRE = new RE(excludeName, RE.MATCH_CASEINDEPENDENT); 348 } 349 350 351 361 public boolean matchesElementAttribute(String element_name, String attr_name, String value) { 362 String element_attr_name = canonicalizeElementAttribute(element_name, attr_name, value); 363 364 if (excludeNameRE != null && includeNameRE != null) { 365 return !matchesExcludesElementAttribute(element_attr_name) && 366 matchesIncludesElementAttribute(element_attr_name); 367 } else { 368 return false; 369 } 370 } 371 372 373 385 private String canonicalizeElementAttribute(String element_name, String attr_name, String value) { 386 return element_name + "/@" + attr_name + "=" + value; 387 } 388 389 390 397 private boolean matchesExcludesElementAttribute(String element_attr_name) { 398 boolean match = excludeNameRE.match(element_attr_name); 399 return match; 400 } 401 402 403 410 private boolean matchesIncludesElementAttribute(String element_attr_name) { 411 boolean match = includeNameRE.match(element_attr_name); 412 return match; 413 } 414 } 415 } 416 417 | Popular Tags |