1 16 package org.apache.cocoon.transformation; 17 18 import java.io.IOException ; 19 import java.io.Serializable ; 20 import java.util.HashMap ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 24 import org.apache.avalon.framework.activity.Disposable; 25 import org.apache.avalon.framework.configuration.Configurable; 26 import org.apache.avalon.framework.configuration.Configuration; 27 import org.apache.avalon.framework.configuration.ConfigurationException; 28 import org.apache.avalon.framework.parameters.Parameters; 29 import org.apache.avalon.framework.service.ServiceException; 30 import org.apache.avalon.framework.service.ServiceManager; 31 import org.apache.avalon.framework.service.Serviceable; 32 33 import org.apache.avalon.excalibur.pool.Recyclable; 34 35 import org.apache.cocoon.ProcessingException; 36 import org.apache.cocoon.caching.CacheableProcessingComponent; 37 import org.apache.cocoon.components.sax.XMLSerializer; 38 import org.apache.cocoon.environment.ObjectModelHelper; 39 import org.apache.cocoon.environment.SourceResolver; 40 import org.apache.cocoon.util.HashUtil; 41 42 import org.apache.excalibur.source.SourceValidity; 43 import org.apache.excalibur.source.impl.validity.NOPValidity; 44 import org.apache.excalibur.store.Store; 45 46 import org.xml.sax.Attributes ; 47 import org.xml.sax.SAXException ; 48 import org.xml.sax.helpers.AttributesImpl ; 49 50 72 public class FragmentExtractorTransformer extends AbstractTransformer 73 implements CacheableProcessingComponent, Configurable, Serviceable, Disposable, Recyclable { 74 75 public static final String FE_URI = "http://apache.org/cocoon/fragmentextractor/2.0"; 76 77 private static final String EXTRACT_URI_NAME = "extract-uri"; 78 private static final String EXTRACT_ELEMENT_NAME = "extract-element"; 79 80 private static final String EXTRACT_URI = "http://www.w3.org/2000/svg"; 81 private static final String EXTRACT_ELEMENT = "svg"; 82 83 private String extractURI; 84 private String extractElement; 85 86 87 protected ServiceManager manager; 88 89 private XMLSerializer serializer; 90 91 private Map prefixMap; 92 93 private int extractLevel; 94 95 private int fragmentID; 96 97 private String requestURI; 98 99 102 public void configure(Configuration conf) throws ConfigurationException { 103 this.extractURI = conf.getChild(EXTRACT_URI_NAME).getValue(EXTRACT_URI); 104 this.extractElement = conf.getChild(EXTRACT_ELEMENT_NAME).getValue(EXTRACT_ELEMENT); 105 if (getLogger().isDebugEnabled()) { 106 getLogger().debug("Extraction URI is " + this.extractURI); 107 getLogger().debug("Extraction element is " + this.extractElement); 108 } 109 } 110 111 115 public void service(ServiceManager manager) throws ServiceException { 116 this.manager = manager; 117 } 118 119 122 public void recycle() { 123 if (this.manager != null) { 124 this.manager.release(serializer); 125 this.serializer = null; 126 } 127 super.recycle(); 128 } 129 130 133 public void dispose() { 134 recycle(); 135 this.manager = null; 136 } 137 138 141 public void setup(SourceResolver resolver, Map objectModel, String src, Parameters parameters) 142 throws ProcessingException, SAXException , IOException { 143 extractLevel = 0; 144 fragmentID = 0; 145 prefixMap = new HashMap (); 146 147 this.requestURI = ObjectModelHelper.getRequest(objectModel).getSitemapURI(); 148 } 149 150 156 public Serializable getKey() { 157 return "1"; 158 } 159 160 166 public SourceValidity getValidity() { 167 return NOPValidity.SHARED_INSTANCE; 168 } 169 170 176 public void startPrefixMapping(String prefix, String uri) 177 throws SAXException { 178 if (extractLevel == 0) { 179 super.startPrefixMapping(prefix, uri); 180 prefixMap.put(prefix, uri); 181 } else { 182 this.serializer.startPrefixMapping(prefix, uri); 183 } 184 } 185 186 191 public void endPrefixMapping(String prefix) 192 throws SAXException { 193 if (extractLevel == 0) { 194 super.endPrefixMapping(prefix); 195 prefixMap.remove(prefix); 196 } else { 197 this.serializer.endPrefixMapping(prefix); 198 } 199 } 200 201 214 public void startElement(String uri, String loc, String raw, Attributes a) 215 throws SAXException { 216 if (uri == null) uri = ""; 217 if (this.extractURI.equals(uri) && this.extractElement.equals(loc)) { 218 extractLevel++; 219 fragmentID++; 220 if (getLogger().isDebugEnabled()) { 221 getLogger().debug("extractLevel now " + extractLevel + "."); 222 } 223 224 try { 225 this.serializer = (XMLSerializer) this.manager.lookup(XMLSerializer.ROLE); 226 } catch (ServiceException se) { 227 throw new SAXException ("Could not lookup for XMLSerializer.", se); 228 } 229 230 this.serializer.startDocument(); 232 233 Iterator itt = prefixMap.entrySet().iterator(); 234 while (itt.hasNext()) { 235 Map.Entry entry = (Map.Entry )itt.next(); 236 this.serializer.startPrefixMapping( 237 (String )entry.getKey(), 238 (String )entry.getValue() 239 ); 240 } 241 } 242 243 if (extractLevel == 0) { 244 super.startElement(uri, loc, raw, a); 245 } else { 246 this.serializer.startElement(uri, loc, raw, a); 247 } 248 } 249 250 251 262 public void endElement(String uri, String loc, String raw) 263 throws SAXException { 264 if (extractLevel == 0) { 265 super.endElement(uri, loc, raw); 266 } else { 267 this.serializer.endElement(uri, loc, raw); 268 if (uri == null) uri = ""; 269 if (this.extractURI.equals(uri) && this.extractElement.equals(loc)) { 270 extractLevel--; 271 if (getLogger().isDebugEnabled()) { 272 getLogger().debug("extractLevel now " + extractLevel + "."); 273 } 274 275 if (extractLevel == 0) { 276 Iterator itt = prefixMap.entrySet().iterator(); 278 while (itt.hasNext()) { 279 Map.Entry entry = (Map.Entry ) itt.next(); 280 this.serializer.endPrefixMapping( 281 (String )entry.getKey() 282 ); 283 } 284 this.serializer.endDocument(); 285 286 Store store = null; 287 String id = Long.toHexString((hashCode()^HashUtil.hash(requestURI)) + fragmentID); 288 try { 289 store = (Store) this.manager.lookup(Store.TRANSIENT_STORE); 290 store.store(id, this.serializer.getSAXFragment()); 291 } catch (ServiceException se) { 292 throw new SAXException ("Could not lookup for transient store.", se); 293 } catch (IOException ioe) { 294 throw new SAXException ("Could not store fragment.", ioe); 295 } finally { 296 this.manager.release(store); 297 this.manager.release(this.serializer); 298 this.serializer = null; 299 } 300 301 if (getLogger().isDebugEnabled()) { 302 getLogger().debug("Stored document " + id + "."); 303 } 304 305 super.startPrefixMapping("fe", FE_URI); 307 AttributesImpl atts = new AttributesImpl (); 308 atts.addAttribute("", "fragment-id", "fragment-id", "CDATA", id); 309 super.startElement(FE_URI, "fragment", "fe:fragment", atts); 310 super.endElement(FE_URI, "fragment", "fe:fragment"); 311 super.endPrefixMapping("fe"); 312 } 313 } 314 } 315 } 316 317 324 public void characters(char c[], int start, int len) 325 throws SAXException { 326 if (extractLevel == 0) { 327 super.characters(c, start, len); 328 } else { 329 this.serializer.characters(c, start, len); 330 } 331 } 332 333 340 public void ignorableWhitespace(char c[], int start, int len) 341 throws SAXException { 342 if (extractLevel == 0) { 343 super.ignorableWhitespace(c, start, len); 344 } else { 345 this.serializer.ignorableWhitespace(c, start, len); 346 } 347 } 348 349 356 public void processingInstruction(String target, String data) 357 throws SAXException { 358 if (extractLevel == 0) { 359 super.processingInstruction(target, data); 360 } else { 361 this.serializer.processingInstruction(target, data); 362 } 363 } 364 365 371 public void skippedEntity(String name) 372 throws SAXException { 373 if (extractLevel == 0) { 374 super.skippedEntity(name); 375 } else { 376 this.serializer.skippedEntity(name); 377 } 378 } 379 380 389 public void startDTD(String name, String publicId, String systemId) 390 throws SAXException { 391 if (extractLevel == 0) { 392 super.startDTD(name, publicId, systemId); 393 } else { 394 throw new SAXException ( 395 "Recieved startDTD after beginning fragment extraction process." 396 ); 397 } 398 } 399 400 403 public void endDTD() 404 throws SAXException { 405 if (extractLevel == 0) { 406 super.endDTD(); 407 } else { 408 throw new SAXException ( 409 "Recieved endDTD after beginning fragment extraction process." 410 ); 411 } 412 } 413 414 420 public void startEntity(String name) 421 throws SAXException { 422 if (extractLevel == 0) { 423 super.startEntity(name); 424 } else { 425 this.serializer.startEntity(name); 426 } 427 } 428 429 434 public void endEntity(String name) 435 throws SAXException { 436 if (extractLevel == 0) { 437 super.endEntity(name); 438 } else { 439 this.serializer.endEntity(name); 440 } 441 } 442 443 446 public void startCDATA() 447 throws SAXException { 448 if (extractLevel == 0) { 449 super.startCDATA(); 450 } else { 451 this.serializer.startCDATA(); 452 } 453 } 454 455 458 public void endCDATA() 459 throws SAXException { 460 if (extractLevel == 0) { 461 super.endCDATA(); 462 } else { 463 this.serializer.endCDATA(); 464 } 465 } 466 467 474 public void comment(char ch[], int start, int len) 475 throws SAXException { 476 if (extractLevel == 0) { 477 super.comment(ch, start, len); 478 } else { 479 this.serializer.comment(ch, start, len); 480 } 481 } 482 } 483 | Popular Tags |