1 16 package org.apache.cocoon.components.source; 17 18 import org.apache.avalon.framework.component.ComponentException; 19 import org.apache.avalon.framework.component.ComponentManager; 20 import org.apache.avalon.framework.logger.Logger; 21 22 import org.apache.excalibur.source.SourceException; 23 24 import org.apache.cocoon.ProcessingException; 25 import org.apache.cocoon.Processor; 26 import org.apache.cocoon.components.CocoonComponentManager; 27 import org.apache.cocoon.components.pipeline.ProcessingPipeline; 28 import org.apache.cocoon.components.sax.XMLDeserializer; 29 import org.apache.cocoon.components.sax.XMLSerializer; 30 import org.apache.cocoon.environment.Environment; 31 import org.apache.cocoon.environment.ModifiableSource; 32 import org.apache.cocoon.environment.wrapper.EnvironmentWrapper; 33 import org.apache.cocoon.xml.AbstractXMLConsumer; 34 import org.apache.cocoon.xml.ContentHandlerWrapper; 35 import org.apache.cocoon.xml.XMLConsumer; 36 import org.xml.sax.ContentHandler ; 37 import org.xml.sax.InputSource ; 38 import org.xml.sax.SAXException ; 39 import org.xml.sax.ext.LexicalHandler ; 40 41 import java.io.ByteArrayInputStream ; 42 import java.io.ByteArrayOutputStream ; 43 import java.io.IOException ; 44 import java.io.InputStream ; 45 import java.net.MalformedURLException ; 46 47 54 public final class SitemapSource 55 extends AbstractXMLConsumer 56 implements ModifiableSource { 57 58 59 private long lastModificationDate; 60 61 62 private String systemId; 63 64 65 private String uri; 66 67 68 private ComponentManager manager; 69 70 71 private Processor processor; 72 73 74 private Processor pipelineProcessor; 75 76 77 private EnvironmentWrapper environment; 78 79 80 private String prefix; 81 82 83 private ProcessingPipeline processingPipeline; 84 85 86 private org.apache.excalibur.source.Source redirectSource; 87 88 89 private SAXException exception; 90 91 92 private boolean needsRefresh; 93 94 95 private Object processKey; 96 97 100 public SitemapSource(ComponentManager manager, 101 String uri, 102 Logger logger) 103 throws IOException , ProcessingException { 104 105 Environment env = CocoonComponentManager.getCurrentEnvironment(); 106 if ( env == null ) { 107 throw new MalformedURLException ("The cocoon protocol can not be used outside an environment."); 108 } 109 110 this.manager = manager; 111 this.enableLogging(logger); 112 boolean rawMode = false; 113 114 int position = uri.indexOf(':') + 1; 116 if (position != 0) { 117 if (uri.startsWith("raw:", position)) { 119 position += 4; 120 rawMode = true; 121 } 122 } 123 124 if (uri.startsWith("//", position)) { 126 position += 2; 127 try { 128 this.processor = (Processor)this.manager.lookup(Processor.ROLE); 129 } catch (ComponentException e) { 130 throw new ProcessingException("Cannot get Processor instance", e); 131 } 132 this.prefix = ""; } else if (uri.startsWith("/", position)) { 134 position ++; 135 this.prefix = null; 136 this.processor = CocoonComponentManager.getActiveProcessor(env); 137 } else { 138 throw new ProcessingException("Malformed cocoon URI."); 139 } 140 141 String queryString = null; 143 int queryStringPos = uri.indexOf('?', position); 144 if (queryStringPos != -1) { 145 queryString = uri.substring(queryStringPos + 1); 146 uri = uri.substring(position, queryStringPos); 147 } else if (position > 0) { 148 uri = uri.substring(position); 149 } 150 151 String requestURI = (this.prefix == null ? env.getURIPrefix() + uri : uri); 153 154 this.systemId = queryString == null ? 156 "cocoon://" + requestURI : 157 "cocoon://" + requestURI + "?" + queryString; 158 159 this.environment = new EnvironmentWrapper(env, requestURI, queryString, logger, manager, rawMode); 160 this.uri = uri; 161 this.refresh(); 162 } 163 164 168 public long getLastModified() { 169 if (this.needsRefresh) { 170 this.refresh(); 171 } 172 return this.lastModificationDate; 173 } 174 175 179 public long getContentLength() { 180 return -1; 181 } 182 183 186 public InputStream getInputStream() 187 throws ProcessingException, IOException { 188 189 if (this.needsRefresh) { 190 this.refresh(); 191 } 192 if (this.exception != null) { 194 throw new ProcessingException(this.exception); 195 } 196 197 if (this.redirectSource != null) { 198 try { 199 return this.redirectSource.getInputStream(); 200 } catch (SourceException se) { 201 throw SourceUtil.handle(se); 202 } 203 } 204 205 try { 206 ByteArrayOutputStream os = new ByteArrayOutputStream (); 207 this.environment.setOutputStream(os); 208 CocoonComponentManager.enterEnvironment(this.environment, 209 this.manager, 210 this.pipelineProcessor); 211 try { 212 this.processingPipeline.process(this.environment); 213 } finally { 214 CocoonComponentManager.leaveEnvironment(); 215 } 216 return new ByteArrayInputStream (os.toByteArray()); 217 218 } catch (ProcessingException e) { 219 throw e; 220 } catch (Exception e) { 221 throw new ProcessingException("Exception during processing of " + this.systemId, e); 222 } finally { 223 this.environment.setOutputStream(null); 225 reset(); 226 } 227 } 228 229 232 public String getSystemId() { 233 return this.systemId; 234 } 235 236 240 public void refresh() { 241 reset(); 242 try { 243 this.processKey = CocoonComponentManager.startProcessing(this.environment); 244 this.environment.setURI(this.prefix, this.uri); 245 this.processingPipeline = this.processor.buildPipeline(this.environment); 246 this.pipelineProcessor = CocoonComponentManager.getActiveProcessor(this.environment); 247 String redirectURL = this.environment.getRedirectURL(); 248 if (redirectURL != null) { 249 if (redirectURL.indexOf(":") == -1) { 250 redirectURL = "cocoon:/" + redirectURL; 251 } 252 this.redirectSource = this.environment.resolveURI(redirectURL); 253 this.lastModificationDate = this.redirectSource.getLastModified(); 254 } 255 } catch (SAXException e) { 256 reset(); 257 this.exception = e; 258 } catch (Exception e) { 259 reset(); 260 this.exception = new SAXException ("Could not get sitemap source " 261 + this.systemId, e); 262 } 263 this.needsRefresh = false; 264 } 265 266 269 public InputSource getInputSource() 270 throws ProcessingException, IOException { 271 InputSource newObject = new InputSource (this.getInputStream()); 272 newObject.setSystemId(this.systemId); 273 return newObject; 274 } 275 276 279 public void toSAX(ContentHandler contentHandler) 280 throws SAXException 281 { 282 if (this.needsRefresh) { 283 this.refresh(); 284 } 285 if (this.exception != null) { 286 throw this.exception; 287 } 288 try { 289 XMLConsumer consumer; 290 if (contentHandler instanceof XMLConsumer) { 291 consumer = (XMLConsumer)contentHandler; 292 } else if (contentHandler instanceof LexicalHandler ) { 293 consumer = new ContentHandlerWrapper(contentHandler, (LexicalHandler )contentHandler); 294 } else { 295 consumer = new ContentHandlerWrapper(contentHandler); 296 } 297 if (this.redirectSource != null) { 298 SourceUtil.parse(this.manager, this.redirectSource, consumer); 299 } else { 300 XMLSerializer xmls = (XMLSerializer) this.manager.lookup(XMLSerializer.ROLE); 303 Object fragment; 304 CocoonComponentManager.enterEnvironment(this.environment, 305 this.manager, 306 this.pipelineProcessor); 307 try { 308 this.processingPipeline.process(this.environment, xmls); 309 fragment = xmls.getSAXFragment(); 310 } finally { 311 this.manager.release(xmls); 312 CocoonComponentManager.leaveEnvironment(); 313 } 314 XMLDeserializer xmld = (XMLDeserializer) this.manager.lookup(XMLDeserializer.ROLE); 315 try { 316 xmld.setConsumer(consumer); 317 xmld.deserialize(fragment); 318 } finally { 319 this.manager.release(xmld); 320 } 321 } 322 } catch (SAXException e) { 323 throw e; 325 } catch (Exception e) { 326 throw new SAXException ("Exception during processing of " 327 + this.systemId, e); 328 } finally { 329 reset(); 330 } 331 } 332 333 private void reset() { 334 if (this.processingPipeline != null) this.processingPipeline.release(); 335 if (this.processKey != null) { 336 CocoonComponentManager.endProcessing(this.environment, this.processKey); 337 this.processKey = null; 338 } 339 this.processingPipeline = null; 340 this.lastModificationDate = 0; 341 this.environment.release(this.redirectSource); 342 this.environment.reset(); 343 this.redirectSource = null; 344 this.exception = null; 345 this.needsRefresh = true; 346 this.pipelineProcessor = null; 347 } 348 349 public void recycle() { 350 reset(); 351 } 352 } 353 | Popular Tags |