1 16 package org.apache.cocoon.generation; 17 18 import java.io.ByteArrayInputStream ; 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 import java.util.Properties ; 24 25 import javax.servlet.http.HttpServletRequest ; 26 27 import org.apache.avalon.framework.activity.Disposable; 28 import org.apache.avalon.framework.configuration.Configurable; 29 import org.apache.avalon.framework.configuration.Configuration; 30 import org.apache.avalon.framework.configuration.ConfigurationException; 31 import org.apache.avalon.framework.parameters.Parameters; 32 import org.apache.avalon.framework.service.ServiceException; 33 import org.apache.avalon.framework.service.ServiceManager; 34 import org.apache.cocoon.ProcessingException; 35 import org.apache.cocoon.ResourceNotFoundException; 36 import org.apache.cocoon.caching.CacheableProcessingComponent; 37 import org.apache.cocoon.components.source.SourceUtil; 38 import org.apache.cocoon.environment.ObjectModelHelper; 39 import org.apache.cocoon.environment.Request; 40 import org.apache.cocoon.environment.SourceResolver; 41 import org.apache.cocoon.environment.http.HttpEnvironment; 42 import org.apache.cocoon.util.PostInputStream; 43 import org.apache.cocoon.xml.dom.DOMBuilder; 44 import org.apache.cocoon.xml.dom.DOMStreamer; 45 import org.apache.excalibur.source.Source; 46 import org.apache.excalibur.source.SourceException; 47 import org.apache.excalibur.source.SourceValidity; 48 import org.apache.excalibur.xml.xpath.XPathProcessor; 49 import org.apache.xerces.parsers.AbstractSAXParser; 50 import org.cyberneko.html.HTMLConfiguration; 51 import org.w3c.dom.Document ; 52 import org.w3c.dom.NodeList ; 53 import org.xml.sax.InputSource ; 54 import org.xml.sax.SAXException ; 55 56 76 public class NekoHTMLGenerator extends ServiceableGenerator 77 implements Configurable, CacheableProcessingComponent, Disposable { 78 79 80 public static final String FORM_NAME = "form-name"; 81 82 83 private Source inputSource; 84 85 86 private InputStream requestStream; 87 88 89 private String xpath = null; 90 91 92 private XPathProcessor processor = null; 93 94 95 private Properties properties; 96 97 public void service(ServiceManager manager) 98 throws ServiceException { 99 super.service( manager ); 100 this.processor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE); 101 } 102 103 public void configure(Configuration config) throws ConfigurationException { 104 105 String configUrl = config.getChild("neko-config").getValue(null); 106 107 if(configUrl != null) { 108 org.apache.excalibur.source.SourceResolver resolver = null; 109 Source configSource = null; 110 try { 111 resolver = (org.apache.excalibur.source.SourceResolver)this.manager.lookup(org.apache.excalibur.source.SourceResolver.ROLE); 112 configSource = resolver.resolveURI(configUrl); 113 if (getLogger().isDebugEnabled()) { 114 getLogger().debug("Loading configuration from " + configSource.getURI()); 115 } 116 117 this.properties = new Properties (); 118 this.properties.load(configSource.getInputStream()); 119 120 } catch (Exception e) { 121 getLogger().warn("Cannot load configuration from " + configUrl); 122 throw new ConfigurationException("Cannot load configuration from " + configUrl, e); 123 } finally { 124 if ( null != resolver ) { 125 this.manager.release(resolver); 126 resolver.release(configSource); 127 } 128 } 129 } 130 } 131 132 136 public void recycle() { 137 if (this.inputSource != null) { 138 this.resolver.release( this.inputSource ); 139 this.inputSource = null; 140 this.requestStream = null; 141 } 142 this.xpath = null; 143 super.recycle(); 144 } 145 146 150 public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) 151 throws ProcessingException, SAXException , IOException { 152 super.setup(resolver, objectModel, src, par); 153 154 Request request = ObjectModelHelper.getRequest(objectModel); 155 156 if (src == null) { 157 161 String contentType = request.getContentType(); 162 163 if (contentType == null ) { 164 throw new IOException ("Content-type was not specified for this request"); 165 } else if (contentType.startsWith("application/x-www-form-urlencoded") || 166 contentType.startsWith("multipart/form-data")) { 167 String requested = parameters.getParameter(FORM_NAME, null); 168 if (requested == null) { 169 throw new ProcessingException( 170 "NekoHtmlGenerator with no \"src\" parameter expects a sitemap parameter called '" + 171 FORM_NAME + "' for handling form data" 172 ); 173 } 174 175 String sXml = request.getParameter(requested); 176 177 requestStream = new ByteArrayInputStream (sXml.getBytes()); 178 179 } else if (contentType.startsWith("text/plain") || 180 contentType.startsWith("text/xml") || 181 contentType.startsWith("application/xml")) { 182 183 HttpServletRequest httpRequest = (HttpServletRequest ) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT); 184 if ( httpRequest == null ) { 185 throw new ProcessingException("This functionality only works in an http environment."); 186 } 187 int len = request.getContentLength(); 188 if (len > 0) { 189 requestStream = new PostInputStream(httpRequest.getInputStream(), len); 190 } else { 191 throw new IOException ("getContentLen() == 0"); 192 } 193 } else { 194 throw new IOException ("Unexpected getContentType(): " + request.getContentType()); 195 } 196 197 198 } 199 200 xpath = request.getParameter("xpath"); 201 if(xpath == null) 202 xpath = par.getParameter("xpath",null); 203 204 if (par.getParameterAsBoolean("copy-parameters", false) 206 && request.getQueryString() != null) { 207 StringBuffer query = new StringBuffer (super.source); 208 query.append(super.source.indexOf("?") == -1 ? '?' : '&'); 209 query.append(request.getQueryString()); 210 super.source = query.toString(); 211 } 212 213 try { 214 if (source != null) 215 this.inputSource = resolver.resolveURI(super.source); 216 } catch (SourceException se) { 217 throw SourceUtil.handle("Unable to resolve " + super.source, se); 218 } 219 } 220 221 229 public java.io.Serializable getKey() { 230 if (this.inputSource == null) 231 return null; 232 233 if (this.xpath != null) { 234 StringBuffer buffer = new StringBuffer (this.inputSource.getURI()); 235 buffer.append(':').append(this.xpath); 236 return buffer.toString(); 237 } else { 238 return this.inputSource.getURI(); 239 } 240 } 241 242 250 public SourceValidity getValidity() { 251 if (this.inputSource == null) 252 return null; 253 return this.inputSource.getValidity(); 254 } 255 256 259 public void generate() 260 throws IOException , SAXException , ProcessingException { 261 try { 262 HtmlSaxParser parser = new HtmlSaxParser(this.properties); 263 264 if (inputSource != null) 265 requestStream = this.inputSource.getInputStream(); 266 267 if(xpath != null) { 268 DOMBuilder builder = new DOMBuilder(); 269 parser.setContentHandler(builder); 270 parser.parse(new InputSource (requestStream)); 271 Document doc = builder.getDocument(); 272 273 DOMStreamer domStreamer = new DOMStreamer(this.contentHandler, 274 this.lexicalHandler); 275 this.contentHandler.startDocument(); 276 NodeList nl = processor.selectNodeList(doc, xpath); 277 int length = nl.getLength(); 278 for(int i=0; i < length; i++) { 279 domStreamer.stream(nl.item(i)); 280 } 281 this.contentHandler.endDocument(); 282 } else { 283 parser.setContentHandler(this.contentHandler); 284 parser.parse(new InputSource (requestStream)); 285 } 286 requestStream.close(); 287 } catch (IOException e){ 288 throw new ResourceNotFoundException("Could not get resource " 289 + this.inputSource.getURI(), e); 290 } catch (SAXException e){ 291 throw e; 292 } catch (Exception e){ 293 throw new ProcessingException("Exception in NekoHTMLGenerator.generate()",e); 294 } 295 } 296 297 298 public void dispose() { 299 if (this.manager != null) { 300 this.manager.release(this.processor); 301 this.manager = null; 302 } 303 this.processor = null; 304 super.dispose(); 305 } 306 307 public static class HtmlSaxParser extends AbstractSAXParser { 308 309 public HtmlSaxParser(Properties properties) { 310 super(getConfig(properties)); 311 } 312 313 private static HTMLConfiguration getConfig(Properties properties) { 314 HTMLConfiguration config = new HTMLConfiguration(); 315 config.setProperty("http://cyberneko.org/html/properties/names/elems", "lower"); 316 if (properties != null) { 317 for (Iterator i = properties.keySet().iterator();i.hasNext();) { 318 String name = (String ) i.next(); 319 config.setProperty(name, properties.getProperty(name)); 320 } 321 } 322 return config; 323 } 324 } 325 } 326 | Popular Tags |