1 14 15 package com.sun.facelets.compiler; 16 17 import java.io.IOException ; 18 import java.io.InputStream ; 19 import java.lang.reflect.Method ; 20 import java.net.URL ; 21 import java.util.logging.Level ; 22 import java.util.logging.Logger ; 23 24 import javax.xml.parsers.ParserConfigurationException ; 25 import javax.xml.parsers.SAXParser ; 26 import javax.xml.parsers.SAXParserFactory ; 27 28 import org.xml.sax.Attributes ; 29 import org.xml.sax.InputSource ; 30 import org.xml.sax.Locator ; 31 import org.xml.sax.SAXException ; 32 import org.xml.sax.SAXParseException ; 33 import org.xml.sax.XMLReader ; 34 import org.xml.sax.helpers.DefaultHandler ; 35 36 import com.sun.facelets.tag.AbstractTagLibrary; 37 import com.sun.facelets.tag.TagHandler; 38 import com.sun.facelets.tag.TagLibrary; 39 import com.sun.facelets.util.ParameterCheck; 40 import com.sun.facelets.util.Classpath; 41 42 49 public final class TagLibraryConfig { 50 51 private final static String SUFFIX = ".taglib.xml"; 52 53 protected final static Logger log = Logger.getLogger("facelets.compiler"); 54 55 private static class TagLibraryImpl extends AbstractTagLibrary { 56 public TagLibraryImpl(String namespace) { 57 super(namespace); 58 } 59 60 public void putConverter(String name, String id) { 61 ParameterCheck.notNull("name", name); 62 ParameterCheck.notNull("id", id); 63 this.addConverter(name, id); 64 } 65 66 public void putConverter(String name, String id, Class handlerClass) { 67 ParameterCheck.notNull("name", name); 68 ParameterCheck.notNull("id", id); 69 ParameterCheck.notNull("handlerClass", handlerClass); 70 this.addConverter(name, id, handlerClass); 71 } 72 73 74 public void putValidator(String name, String id) { 75 ParameterCheck.notNull("name", name); 76 ParameterCheck.notNull("id", id); 77 this.addValidator(name, id); 78 } 79 80 public void putValidator(String name, String id, Class handlerClass) { 81 ParameterCheck.notNull("name", name); 82 ParameterCheck.notNull("id", id); 83 ParameterCheck.notNull("handlerClass", handlerClass); 84 this.addValidator(name, id, handlerClass); 85 } 86 87 public void putTagHandler(String name, Class type) { 88 ParameterCheck.notNull("name", name); 89 ParameterCheck.notNull("type", type); 90 this.addTagHandler(name, type); 91 } 92 93 public void putComponent(String name, String componentType, 94 String rendererType) { 95 ParameterCheck.notNull("name", name); 96 ParameterCheck.notNull("componentType", componentType); 97 this.addComponent(name, componentType, rendererType); 98 } 99 100 public void putComponent(String name, String componentType, 101 String rendererType, Class handlerClass) { 102 ParameterCheck.notNull("name", name); 103 ParameterCheck.notNull("componentType", componentType); 104 ParameterCheck.notNull("handlerClass", handlerClass); 105 this.addComponent(name, componentType, rendererType, handlerClass); 106 } 107 108 109 public void putUserTag(String name, URL source) { 110 ParameterCheck.notNull("name", name); 111 ParameterCheck.notNull("source", source); 112 this.addUserTag(name, source); 113 } 114 115 public void putFunction(String name, Method method) { 116 ParameterCheck.notNull("name", name); 117 ParameterCheck.notNull("method", method); 118 this.addFunction(name, method); 119 } 120 } 121 122 private static class LibraryHandler extends DefaultHandler { 123 private final String file; 124 125 private final URL source; 126 127 private TagLibrary library; 128 129 private final StringBuffer buffer; 130 131 private Locator locator; 132 133 private String tagName; 134 135 private String componentClassName; 136 137 private String componentType; 138 139 private String rendererType; 140 141 private String functionName; 142 143 private Class handlerClass; 144 145 private Class functionClass; 146 147 private String functionSignature; 148 149 public LibraryHandler(URL source) { 150 this.file = source.getFile(); 151 this.source = source; 152 this.buffer = new StringBuffer (64); 153 } 154 155 public TagLibrary getLibrary() { 156 return this.library; 157 } 158 159 public void endElement(String uri, String localName, String qName) 160 throws SAXException { 161 try { 162 if ("facelet-taglib".equals(qName)) { 163 ; } 165 else if ("library-class".equals(qName)) { 166 this.processLibraryClass(); 167 } 168 else if ("namespace".equals(qName)) { 169 this.library = new TagLibraryImpl(this.captureBuffer()); 170 } 171 else if ("component-type".equals(qName)) { 172 this.componentType = this.captureBuffer(); 173 } 174 else if ("renderer-type".equals(qName)) { 175 this.rendererType = this.captureBuffer(); 176 } 177 else if ("tag-name".equals(qName)) { 178 this.tagName = this.captureBuffer(); 179 } 180 else if ("function-name".equals(qName)) { 181 this.functionName = this.captureBuffer(); 182 } 183 else if ("function-class".equals(qName)) { 184 String className = this.captureBuffer(); 185 this.functionClass = this.createClass(Object .class, className); 186 } 187 else 188 { 189 if (this.library == null) { 193 throw new IllegalStateException ("No <namespace> element"); 194 } 195 196 TagLibraryImpl impl = (TagLibraryImpl) this.library; 197 198 if ("tag".equals(qName)) { 199 if (this.handlerClass != null) { 200 impl.putTagHandler(this.tagName, this.handlerClass); 201 } 202 } 203 else if ("handler-class".equals(qName)) { 204 String cName = this.captureBuffer(); 205 this.handlerClass = this.createClass( 206 TagHandler.class, cName); 207 } 208 else if ("component".equals(qName)) { 209 if (this.handlerClass != null) { 210 impl.putComponent(this.tagName, 211 this.componentType, 212 this.rendererType, 213 this.handlerClass); 214 this.handlerClass = null; 215 } 216 else { 217 impl.putComponent(this.tagName, 218 this.componentType, 219 this.rendererType); 220 } 221 } 222 else if ("converter-id".equals(qName)) { 223 if (this.handlerClass != null) { 224 impl.putConverter(this.tagName, 225 this.captureBuffer(), 226 handlerClass); 227 this.handlerClass = null; 228 } 229 else { 230 impl.putConverter(this.tagName, 231 this.captureBuffer()); 232 } 233 } 234 else if ("validator-id".equals(qName)) { 235 if (this.handlerClass != null) { 236 impl.putValidator(this.tagName, 237 this.captureBuffer(), 238 handlerClass); 239 this.handlerClass = null; 240 } 241 else { 242 impl.putValidator(this.tagName, 243 this.captureBuffer()); 244 } 245 } 246 else if ("source".equals(qName)) { 247 String path = this.captureBuffer(); 248 URL url = new URL (this.source, path); 249 impl.putUserTag(this.tagName, url); 250 } 251 else if ("function-signature".equals(qName)) { 252 this.functionSignature = this.captureBuffer(); 253 Method m = this.createMethod(this.functionClass, this.functionSignature); 254 impl.putFunction(this.functionName, m); 255 } 256 } 257 } catch (Exception e) { 258 SAXException saxe = 259 new SAXException ("Error Handling [" + this.source + "@" 260 + this.locator.getLineNumber() + "," 261 + this.locator.getColumnNumber() + "] <" + qName 262 + ">"); 263 saxe.initCause(e); 264 throw saxe; 265 } 266 } 267 268 private String captureBuffer() throws Exception { 269 String s = this.buffer.toString().trim(); 270 if (s.length() == 0) { 271 throw new Exception ("Value Cannot be Empty"); 272 } 273 this.buffer.setLength(0); 274 return s; 275 } 276 277 private static Class createClass(Class type, String name) throws Exception { 278 Class factory = ReflectionUtil.forName(name); 279 if (!type.isAssignableFrom(factory)) { 280 throw new Exception (name + " must be an instance of " 281 + type.getName()); 282 } 283 return factory; 284 } 285 286 private static Method createMethod(Class type, String s) throws Exception { 287 Method m = null; 288 int pos = s.indexOf(' '); 289 if (pos == -1) { 290 throw new Exception ("Must Provide Return Type: "+s); 291 } else { 292 String rt = s.substring(0, pos).trim(); 293 int pos2 = s.indexOf('(', pos+1); 294 if (pos2 == -1) { 295 throw new Exception ("Must provide a method name, followed by '(': "+s); 296 } else { 297 String mn = s.substring(pos+1, pos2).trim(); 298 pos = s.indexOf(')', pos2 + 1); 299 if (pos == -1) { 300 throw new Exception ("Must close parentheses, ')' missing: "+s); 301 } else { 302 String [] ps = s.substring(pos2 + 1, pos).trim().split(","); 303 Class [] pc; 304 if (ps.length == 1 && "".equals(ps[0])) { 305 pc = new Class [0]; 306 } else { 307 pc = new Class [ps.length]; 308 for (int i = 0; i < pc.length; i ++) { 309 pc[i] = ReflectionUtil.forName(ps[i].trim()); 310 } 311 } 312 try { 313 return type.getMethod(mn, pc); 314 } catch (NoSuchMethodException e) { 315 throw new Exception ("No Function Found on type: "+type.getName()+" with signature: "+s); 316 } 317 318 } 319 320 } 321 } 322 } 323 324 private void processLibraryClass() throws Exception { 325 String name = this.captureBuffer(); 326 Class type = this.createClass(TagLibrary.class, name); 327 this.library = (TagLibrary) type.newInstance(); 328 } 329 330 public InputSource resolveEntity(String publicId, String systemId) 331 throws SAXException { 332 if ("-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" 333 .equals(publicId)) { 334 URL url = Thread.currentThread().getContextClassLoader() 335 .getResource("facelet-taglib_1_0.dtd"); 336 return new InputSource (url.toExternalForm()); 337 } 338 return null; 339 } 340 341 public void characters(char[] ch, int start, int length) 342 throws SAXException { 343 this.buffer.append(ch, start, length); 344 } 345 346 public void startElement(String uri, String localName, String qName, 347 Attributes attributes) throws SAXException { 348 this.buffer.setLength(0); 349 if ("tag".equals(qName)) { 350 this.componentClassName = null; 351 this.handlerClass = null; 352 this.componentType = null; 353 this.rendererType = null; 354 this.tagName = null; 355 } else if ("function".equals(qName)) { 356 this.functionName = null; 357 this.functionClass = null; 358 this.functionSignature = null; 359 } 360 } 361 362 public void error(SAXParseException e) throws SAXException { 363 SAXException saxe = 364 new SAXException ("Error Handling [" + this.source + "@" 365 + e.getLineNumber() + "," + e.getColumnNumber() + "]"); 366 saxe.initCause(e); 367 throw saxe; 368 } 369 370 public void setDocumentLocator(Locator locator) { 371 this.locator = locator; 372 } 373 374 public void fatalError(SAXParseException e) throws SAXException { 375 throw e; 376 } 377 378 public void warning(SAXParseException e) throws SAXException { 379 throw e; 380 } 381 } 382 383 public TagLibraryConfig() { 384 super(); 385 } 386 387 public static TagLibrary create(URL url) throws IOException { 388 InputStream is = null; 389 TagLibrary t = null; 390 try { 391 is = url.openStream(); 392 LibraryHandler handler = new LibraryHandler(url); 393 SAXParser parser = createSAXParser(handler); 394 parser.parse(is, handler); 395 t = handler.getLibrary(); 396 } catch (SAXException e) { 397 IOException ioe = 398 new IOException ("Error parsing [" + url + "]: "); 399 ioe.initCause(e); 400 throw ioe; 401 } catch (ParserConfigurationException e) { 402 IOException ioe = 403 new IOException ("Error parsing [" + url + "]: "); 404 ioe.initCause(e); 405 throw ioe; 406 } finally { 407 if (is != null) 408 is.close(); 409 } 410 return t; 411 } 412 413 public void loadImplicit(Compiler compiler) throws IOException { 414 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 415 URL [] urls = Classpath.search(cl, "META-INF/", SUFFIX); 416 for (int i = 0; i < urls.length; i++) { 417 try { 418 compiler.addTagLibrary(create(urls[i])); 419 log.info("Added Library from: " + urls[i]); 420 } catch (Exception e) { 421 log.log(Level.SEVERE, "Error Loading Library: " + urls[i], e); 422 } 423 } 424 } 425 426 private static final SAXParser createSAXParser(LibraryHandler handler) 427 throws SAXException , ParserConfigurationException { 428 SAXParserFactory factory = SAXParserFactory.newInstance(); 429 factory.setNamespaceAware(false); 430 factory.setFeature("http://xml.org/sax/features/validation", true); 431 factory.setValidating(true); 432 SAXParser parser = factory.newSAXParser(); 433 XMLReader reader = parser.getXMLReader(); 434 reader.setErrorHandler(handler); 435 reader.setEntityResolver(handler); 436 return parser; 437 } 438 439 } 440 | Popular Tags |