1 16 package org.apache.cocoon.sitemap; 17 18 import org.apache.avalon.framework.parameters.Parameters; 19 import org.apache.avalon.framework.service.ServiceException; 20 import org.apache.avalon.framework.service.ServiceManager; 21 import org.apache.avalon.framework.service.Serviceable; 22 23 import org.apache.cocoon.ProcessingException; 24 import org.apache.cocoon.caching.CacheableProcessingComponent; 25 import org.apache.cocoon.components.source.SourceUtil; 26 import org.apache.cocoon.environment.SourceResolver; 27 import org.apache.cocoon.generation.Generator; 28 import org.apache.cocoon.xml.ContentHandlerWrapper; 29 import org.apache.cocoon.xml.XMLConsumer; 30 import org.apache.cocoon.xml.XMLUtils; 31 32 import org.apache.commons.lang.BooleanUtils; 33 import org.apache.excalibur.source.Source; 34 import org.apache.excalibur.source.SourceException; 35 import org.apache.excalibur.source.SourceValidity; 36 import org.apache.excalibur.source.impl.validity.AggregatedValidity; 37 import org.xml.sax.Attributes ; 38 import org.xml.sax.SAXException ; 39 40 import java.io.IOException ; 41 import java.io.Serializable ; 42 import java.util.ArrayList ; 43 import java.util.Map ; 44 45 54 public class ContentAggregator extends ContentHandlerWrapper 55 implements Generator, CacheableProcessingComponent, 56 Serviceable { 57 58 59 protected Element rootElement; 60 61 62 protected ArrayList parts = new ArrayList (); 63 64 65 private int rootElementIndex; 66 67 68 protected Element currentElement; 69 70 71 protected SourceResolver resolver; 72 73 74 protected ServiceManager manager; 75 76 77 protected static final class Part { 78 public String uri; 79 public Element element; 80 public Source source; 81 boolean stripRootElement; 82 83 public Part(String uri, Element element, String stripRoot) { 84 this.uri = uri; 85 this.element = element; 86 this.stripRootElement = BooleanUtils.toBoolean(stripRoot); 87 } 88 } 89 90 91 protected static final class Element { 92 public String namespace; 93 public String prefix; 94 public String name; 95 96 public Element(String name, String namespace, String prefix) { 97 this.namespace = namespace; 98 this.prefix = prefix; 99 this.name = name; 100 } 101 } 102 103 106 public void generate() 107 throws IOException , SAXException , ProcessingException { 108 if (getLogger().isDebugEnabled()) { 109 getLogger().debug("Generating aggregated content"); 110 } 111 this.contentHandler.startDocument(); 112 startElem(this.rootElement); 113 114 try { 115 for (int i = 0; i < this.parts.size(); i++) { 116 final Part part = (Part) this.parts.get(i); 117 this.rootElementIndex = part.stripRootElement ? -1 : 0; 118 if (part.element != null) { 119 this.currentElement = part.element; 120 startElem(part.element); 121 } else { 122 this.currentElement = this.rootElement; 123 } 124 125 try { 126 SourceUtil.parse(this.manager, part.source, this); 127 } finally { 128 if (part.element != null) { 129 endElem(part.element); 130 } 131 } 132 } 133 } finally { 134 endElem(this.rootElement); 135 this.contentHandler.endDocument(); 136 } 137 getLogger().debug("Finished aggregating content"); 138 } 139 140 146 public Serializable getKey() { 147 try { 148 StringBuffer buffer = new StringBuffer (64); 149 buffer.append("CA(") 150 .append(this.rootElement.prefix).append(':') 151 .append(this.rootElement.name).append('<') 152 .append(this.rootElement.namespace).append(">)"); 153 154 for (int i = 0; i < this.parts.size(); i++) { 155 final Part part = (Part) this.parts.get(i); 156 final Source source = part.source; 157 158 if (part.element == null) { 159 buffer.append("P=") 160 .append(part.stripRootElement).append(':') 161 .append(source.getURI()).append(';'); 162 } else { 163 buffer.append("P=") 164 .append(part.element.prefix).append(':') 165 .append(part.element.name) 166 .append('<').append(part.element.namespace).append(">:") 167 .append(part.stripRootElement).append(':') 168 .append(source.getURI()).append(';'); 169 } 170 } 171 172 return buffer.toString(); 173 } catch (Exception e) { 174 getLogger().error("Could not generateKey", e); 175 return null; 176 } 177 } 178 179 185 public SourceValidity getValidity() { 186 try { 187 AggregatedValidity v = new AggregatedValidity(); 188 for (int i = 0; i < this.parts.size(); i++) { 189 final Source current = ((Part) this.parts.get(i)).source; 190 final SourceValidity sv = current.getValidity(); 191 192 if (sv == null) { 193 return null; 194 } else { 195 v.add(sv); 196 } 197 } 198 199 return v; 200 } catch (Exception e) { 201 getLogger().error("Could not getValidity", e); 202 return null; 203 } 204 } 205 206 209 public void setRootElement(String element, String namespace, String prefix) { 210 this.rootElement = new Element(element, 211 namespace, 212 prefix); 213 if (getLogger().isDebugEnabled()) { 214 getLogger().debug("Root element='" + element + 215 "' ns='" + namespace + "' prefix='" + prefix + "'"); 216 } 217 } 218 219 222 public void addPart(String uri, 223 String element, 224 String namespace, 225 String stripRootElement, 226 String prefix) { 227 Element elem = null; 228 if (!element.equals("")) { 229 if (namespace.equals("")) { 230 elem = new Element(element, 231 this.rootElement.namespace, 232 this.rootElement.prefix); 233 } else { 234 elem = new Element(element, 235 namespace, 236 prefix); 237 } 238 } 239 this.parts.add(new Part(uri, 240 elem, 241 stripRootElement)); 242 if (getLogger().isDebugEnabled()) { 243 getLogger().debug("Part uri='" + uri + 244 "' element='" + element + "' ns='" + namespace + 245 "' stripRootElement='" + stripRootElement + "' prefix='" + prefix + "'"); 246 } 247 } 248 249 256 public void setConsumer(XMLConsumer consumer) { 257 setContentHandler(consumer); 258 setLexicalHandler(consumer); 259 } 260 261 264 public void recycle() { 265 super.recycle(); 266 267 this.rootElement = null; 268 for (int i = 0; i < this.parts.size(); i++) { 269 final Part current = (Part) this.parts.get(i); 270 if (current.source != null) { 271 if (getLogger().isDebugEnabled()) { 272 getLogger().debug("Releasing " + current.source); 273 } 274 this.resolver.release(current.source); 275 } 276 } 277 this.parts.clear(); 278 this.currentElement = null; 279 this.resolver = null; 280 } 281 282 286 public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) 287 throws ProcessingException, SAXException , IOException { 288 this.resolver = resolver; 289 try { 291 for (int i = 0; i < this.parts.size(); i++) { 292 final Part current = (Part) this.parts.get(i); 293 current.source = resolver.resolveURI(current.uri); 294 } 295 } catch (SourceException se) { 296 throw SourceUtil.handle("Unable to resolve source.", se); 297 } 298 } 299 300 304 private void startElem(Element element) 305 throws SAXException { 306 final String qname = (element.prefix.equals("")) ? element.name : element.prefix + ':' + element.name; 307 if (!element.namespace.equals("")) { 308 this.contentHandler.startPrefixMapping(element.prefix, element.namespace); 309 } 310 this.contentHandler.startElement(element.namespace, element.name, qname, XMLUtils.EMPTY_ATTRIBUTES); 311 } 312 313 317 private void endElem(Element element) throws SAXException { 318 final String qname = (element.prefix.equals("")) ? element.name : element.prefix + ':' + element.name; 319 this.contentHandler.endElement(element.namespace, element.name, qname); 320 if (!element.namespace.equals("")) { 321 this.contentHandler.endPrefixMapping(element.prefix); 322 } 323 } 324 325 328 public void startDocument() throws SAXException { 329 } 330 331 334 public void endDocument() throws SAXException { 335 } 336 337 340 public void startElement(String namespaceURI, String localName, String raw, Attributes atts) 341 throws SAXException { 342 this.rootElementIndex++; 343 if (this.rootElementIndex == 0) { 344 getLogger().debug("Skipping root element start event."); 345 return; 346 } 347 if (namespaceURI == null || namespaceURI.equals("")) { 348 final String qname = this.currentElement.prefix.equals("") ? localName : this.currentElement.prefix + ':' + localName; 349 this.contentHandler.startElement(this.currentElement.namespace, localName, qname, atts); 350 } else { 351 this.contentHandler.startElement(namespaceURI, localName, raw, atts); 352 } 353 } 354 355 358 public void endElement(String namespaceURI, String localName, String raw) throws SAXException { 359 this.rootElementIndex--; 360 if (this.rootElementIndex == -1) { 361 getLogger().debug("Skipping root element end event."); 362 return; 363 } 364 if (namespaceURI == null || namespaceURI.equals("")) { 365 final String qname = this.currentElement.prefix.equals("") ? localName : this.currentElement.prefix + ':' + localName; 366 this.contentHandler.endElement(this.currentElement.namespace, localName, qname); 367 } else { 368 this.contentHandler.endElement(namespaceURI, localName, raw); 369 } 370 } 371 372 375 public void service(ServiceManager manager) throws ServiceException { 376 this.manager = manager; 377 } 378 } 379 | Popular Tags |