1 16 package org.apache.cocoon.components.language.markup; 17 18 import org.apache.avalon.framework.logger.LogEnabled; 19 import org.apache.avalon.framework.logger.Logger; 20 21 import org.apache.cocoon.ProcessingException; 22 import org.apache.cocoon.components.language.programming.ProgrammingLanguage; 23 import org.apache.cocoon.xml.AbstractXMLPipe; 24 import org.apache.cocoon.xml.XMLConsumer; 25 import org.apache.cocoon.xml.XMLUtils; 26 27 import org.xml.sax.Attributes ; 28 import org.xml.sax.ContentHandler ; 29 import org.xml.sax.SAXException ; 30 import org.xml.sax.ext.LexicalHandler ; 31 import org.xml.sax.helpers.AttributesImpl ; 32 33 import java.io.File ; 34 import java.io.IOException ; 35 import java.util.ArrayList ; 36 import java.util.HashSet ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 import java.util.Set ; 40 41 53 public abstract class CocoonMarkupLanguage extends AbstractMarkupLanguage 54 { 55 58 private final Set dependencies = new HashSet (); 59 60 61 public CocoonMarkupLanguage() { 62 } 63 64 67 public void recycle() { 68 super.recycle(); 69 this.dependencies.clear(); 70 } 71 72 88 protected AbstractXMLPipe getPreprocessFilter(String filename, 89 AbstractXMLPipe filter, 90 ProgrammingLanguage language) { 91 PreProcessFilter prefilter = new PreProcessFilter(filter, filename, language); 92 prefilter.enableLogging(getLogger()); 93 return prefilter; 94 } 95 96 106 protected TransformerChainBuilderFilter getTransformerChainBuilder( 107 LogicsheetCodeGenerator logicsheetMarkupGenerator) 108 { 109 CocoonTransformerChainBuilderFilter filter = 110 new CocoonTransformerChainBuilderFilter( 111 logicsheetMarkupGenerator); 112 filter.enableLogging(getLogger()); 113 return filter; 114 } 115 116 protected void addLogicsheetToList(LanguageDescriptor language, 119 String logicsheetLocation) 120 throws IOException , SAXException , ProcessingException 121 { 122 super.addLogicsheetToList(language, logicsheetLocation); 123 } 124 125 137 protected void addDependency(String location) { 138 dependencies.add(location); 139 } 140 141 144 public abstract String getRootElement(); 145 146 150 161 public class PreProcessFilter extends AbstractXMLPipe implements LogEnabled { 162 protected Logger log; 163 164 protected AbstractXMLPipe filter; 165 166 protected String filename; 167 168 protected boolean isRootElem; 169 170 protected ProgrammingLanguage language; 171 172 protected String localPrefix; 173 174 178 public PreProcessFilter (AbstractXMLPipe filter, String filename, ProgrammingLanguage language) { 179 super (); 180 this.filename = filename; 181 this.language = language; 182 this.filter = filter; 183 super.setLexicalHandler(this.filter); 185 super.setContentHandler(this.filter); 186 } 187 188 public void setConsumer(XMLConsumer consumer) { 189 this.filter.setConsumer(consumer); 191 } 192 193 public void setContentHandler(ContentHandler handler) { 194 this.filter.setContentHandler(handler); 195 } 196 197 public void setLexicalHandler(LexicalHandler handler) { 198 this.filter.setLexicalHandler(handler); 199 } 200 201 public void enableLogging(Logger logger) { 202 if (this.log == null) { 203 this.log = logger; 204 } 205 } 206 207 public void startDocument() throws SAXException { 208 super.startDocument(); 209 isRootElem = true; 210 } 211 212 public void processingInstruction(String target, String data) throws SAXException { 213 if (!"xml-logicsheet".equals(target)) { 214 data = this.language.quoteString(data); 215 } 216 super.processingInstruction(target, data); 217 } 218 219 public void startPrefixMapping(String prefix, String uri) throws SAXException { 220 if (CocoonMarkupLanguage.this.getURI().equals(uri)) { 221 this.localPrefix = prefix; 222 } 223 super.startPrefixMapping(prefix, uri); 224 } 225 226 public void startElement (String namespaceURI, String localName, 227 String qName, Attributes atts) throws SAXException { 228 if (isRootElem) { 229 if (!CocoonMarkupLanguage.this.getURI().equals(namespaceURI) || 230 !CocoonMarkupLanguage.this.getRootElement().equals(localName)) 231 { 232 throw new SAXException ("This page is not valid page of this markup langugage." 233 + " Root element is: " + namespaceURI + ":" + localName 234 + ", must be: " + CocoonMarkupLanguage.this.getURI() 235 + ":" + CocoonMarkupLanguage.this.getRootElement()); 236 } 237 238 isRootElem=false; 239 int pos = this.filename.lastIndexOf(File.separatorChar); 241 String name = this.filename.substring(pos + 1); 242 String path = this.filename.substring(0, pos).replace(File.separatorChar, '/'); 243 AttributesImpl newAtts; 245 if (atts == null || atts.getLength() == 0) { 246 newAtts = new AttributesImpl (); 247 } else { 248 newAtts = new AttributesImpl (atts); 249 } 250 newAtts.addAttribute("", "file-name", "file-name", "CDATA", name); 251 newAtts.addAttribute("", "file-path", "file-path", "CDATA", path); 252 newAtts.addAttribute("", "creation-date", "creation-date", "CDATA", 253 String.valueOf(System.currentTimeMillis())); 254 super.startElement(namespaceURI, localName, qName, newAtts); 256 } else { 257 super.startElement(namespaceURI, localName, qName, atts); 258 } 259 } 260 } 261 262 276 public class CocoonTransformerChainBuilderFilter 277 extends TransformerChainBuilderFilter 278 implements LogEnabled { 279 280 protected Logger log; 281 282 private List startPrefix; 283 284 private Object [] rootElement; 285 286 private StringBuffer rootChars; 287 288 private boolean isRootElem; 289 290 private boolean insideRootElement; 291 292 private boolean finished; 293 294 private String localPrefix; 295 296 299 public CocoonTransformerChainBuilderFilter( 300 LogicsheetCodeGenerator logicsheetMarkupGenerator) 301 { 302 super(logicsheetMarkupGenerator); 303 } 304 305 310 public void enableLogging(Logger logger) { 311 if (this.log == null) { 312 this.log = logger; 313 } 314 } 315 316 public void processingInstruction(String target, String data) throws SAXException { 317 if ("xml-logicsheet".equals(target)) { 319 int start = data.indexOf("href"); 320 if (start >= 0) { 321 start += 6; 323 char quote = data.charAt(start-1); 325 int end = data.indexOf(quote, start); 326 String href = data.substring(start, end); 327 328 try { 329 CocoonMarkupLanguage.this.addLogicsheetToList(language, href); 330 } catch (ProcessingException pe) { 331 log.warn("ProcessingException in SitemapMarkupLanguage", pe); 332 throw new SAXException (pe); 333 } catch (IOException ioe) { 334 log.warn("CocoonMarkupLanguage.processingInstruction", ioe); 335 throw new SAXException (ioe); 336 } 337 } 338 return; 340 } 341 342 super.processingInstruction(target,data); 344 } 345 346 public void startDocument () throws SAXException { 347 isRootElem=true; 348 insideRootElement=false; 349 finished=false; 350 startPrefix = new ArrayList (); 351 rootChars = new StringBuffer (); 352 } 353 354 public void startElement (String namespaceURI, String localName, 355 String qName, Attributes atts) throws SAXException { 356 if (finished) { 357 super.startElement(namespaceURI, localName, qName, atts); 359 } else { 360 if(isRootElem) { 362 localPrefix = ""; 363 if (qName.indexOf(':') != -1) 364 localPrefix = qName.substring(0, qName.indexOf(':')); 365 366 isRootElem = false; 367 rootElement = new Object [4]; 370 rootElement[0]=namespaceURI; 371 rootElement[1]=localName; 372 rootElement[2]=qName; 373 rootElement[3]=atts; 374 } else { 375 insideRootElement = true; 376 if (CocoonMarkupLanguage.this.getURI().equals(namespaceURI) 379 && "logicsheet".equals(localName)) { 380 String href = atts.getValue("location"); 381 try { 382 CocoonMarkupLanguage.this.addLogicsheetToList(language, href); 383 } catch (ProcessingException pe) { 384 log.warn("CocoonMarkupLanguage.startElement", pe); 385 throw new SAXException (pe); 386 } catch (IOException ioe) { 387 log.warn("CocoonMarkupLanguage.startElement", ioe); 388 throw new SAXException (ioe); 389 } 390 } else { 391 finished = true; 397 398 super.startDocument(); 400 401 String [] prefixArray; 403 for (int i=0; i<startPrefix.size(); i++) { 404 prefixArray = (String []) startPrefix.get(i); 405 super.startPrefixMapping(prefixArray[0], prefixArray[1]); 406 } 407 408 super.startElement( 410 (String ) rootElement[0], 411 (String ) rootElement[1], 412 (String ) rootElement[2], 413 (Attributes ) rootElement[3] 414 ); 415 416 char[] ch = rootChars.toString().toCharArray(); 418 if (ch.length > 0) { 419 super.characters(ch, 0, ch.length); 420 } 421 422 char[] locationChars; 426 Iterator iter = CocoonMarkupLanguage.this.dependencies.iterator(); 427 while(iter.hasNext()) { 428 super.startElement( 429 (String ) rootElement[0], "dependency", localPrefix + ":dependency", XMLUtils.EMPTY_ATTRIBUTES 430 ); 431 locationChars = ((String ) iter.next()).toCharArray(); 432 super.characters(locationChars, 0 , locationChars.length); 433 super.endElement((String )rootElement[0], "dependency", localPrefix + ":dependency"); 434 } 435 436 super.startElement(namespaceURI, localName, qName, atts); 438 } 439 } 440 } 441 } 442 443 public void endElement (String namespaceURI, String localName, 444 String qName) throws SAXException { 445 if (finished) { 446 super.endElement(namespaceURI, localName, qName); 448 } 449 } 450 451 public void characters(char[] ch, int start, int length) throws SAXException { 452 if (finished) { 453 super.characters(ch, start, length); 454 } else if(!insideRootElement) { 455 rootChars.append(ch, start, length); 457 } 458 } 459 460 public void startPrefixMapping(String prefix, String uri) throws SAXException { 461 if(finished) { 462 super.startPrefixMapping(prefix, uri); 463 } else { 464 String [] prefixArray = new String [2]; 465 prefixArray[0]= prefix; 466 prefixArray[1]= uri; 467 startPrefix.add(prefixArray); 468 } 469 } 470 } 471 } 472 | Popular Tags |