001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.jasper.deployment; 019 020 import java.io.File; 021 import java.io.IOException; 022 import java.net.JarURLConnection; 023 import java.net.MalformedURLException; 024 import java.net.URI; 025 import java.net.URISyntaxException; 026 import java.net.URL; 027 import java.util.ArrayList; 028 import java.util.Collection; 029 import java.util.Enumeration; 030 import java.util.HashMap; 031 import java.util.HashSet; 032 import java.util.List; 033 import java.util.Map; 034 import java.util.Set; 035 import java.util.jar.JarEntry; 036 import java.util.jar.JarFile; 037 038 import javax.xml.namespace.QName; 039 040 import org.apache.commons.logging.Log; 041 import org.apache.commons.logging.LogFactory; 042 import org.apache.geronimo.common.DeploymentException; 043 import org.apache.geronimo.deployment.ModuleIDBuilder; 044 import org.apache.geronimo.deployment.service.EnvironmentBuilder; 045 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil; 046 import org.apache.geronimo.gbean.AbstractName; 047 import org.apache.geronimo.gbean.GBeanData; 048 import org.apache.geronimo.gbean.GBeanInfo; 049 import org.apache.geronimo.gbean.GBeanInfoBuilder; 050 import org.apache.geronimo.j2ee.annotation.Holder; 051 import org.apache.geronimo.j2ee.deployment.EARContext; 052 import org.apache.geronimo.j2ee.deployment.Module; 053 import org.apache.geronimo.j2ee.deployment.ModuleBuilderExtension; 054 import org.apache.geronimo.j2ee.deployment.NamingBuilder; 055 import org.apache.geronimo.j2ee.deployment.WebModule; 056 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 057 import org.apache.geronimo.jasper.JasperServletContextCustomizer; 058 import org.apache.geronimo.kernel.GBeanAlreadyExistsException; 059 import org.apache.geronimo.kernel.Naming; 060 import org.apache.geronimo.kernel.config.Configuration; 061 import org.apache.geronimo.kernel.config.ConfigurationStore; 062 import org.apache.geronimo.kernel.repository.Environment; 063 import org.apache.geronimo.schema.SchemaConversionUtils; 064 import org.apache.geronimo.xbeans.javaee.FullyQualifiedClassType; 065 import org.apache.geronimo.xbeans.javaee.JspConfigType; 066 import org.apache.geronimo.xbeans.javaee.ListenerType; 067 import org.apache.geronimo.xbeans.javaee.TagType; 068 import org.apache.geronimo.xbeans.javaee.TaglibDocument; 069 import org.apache.geronimo.xbeans.javaee.TaglibType; 070 import org.apache.geronimo.xbeans.javaee.TldTaglibType; 071 import org.apache.geronimo.xbeans.javaee.WebAppType; 072 import org.apache.xbean.finder.ClassFinder; 073 import org.apache.xmlbeans.XmlCursor; 074 import org.apache.xmlbeans.XmlException; 075 import org.apache.xmlbeans.XmlObject; 076 077 /** 078 * This JSP module builder extension is meant to find all the TLD descriptor files associated with a 079 * deployable artifact, search those TLD files for listeners, search those listeners for 080 * annotations, and ultimately create a ClassFinder using those annoated classes (for later 081 * processing by the various naming builders) 082 * 083 * @version $Rev $Date 084 */ 085 public class JspModuleBuilderExtension implements ModuleBuilderExtension { 086 087 private static final Log log = LogFactory.getLog(JspModuleBuilderExtension.class); 088 089 private final Environment defaultEnvironment; 090 private final NamingBuilder namingBuilders; 091 092 private static final QName TLIB_VERSION = new QName(SchemaConversionUtils.JAVAEE_NAMESPACE, "tlib-version"); 093 private static final QName SHORT_NAME = new QName(SchemaConversionUtils.JAVAEE_NAMESPACE, "short-name"); 094 private static final QName TAG_CLASS = new QName(SchemaConversionUtils.JAVAEE_NAMESPACE, "tag-class"); 095 private static final QName TEI_CLASS = new QName(SchemaConversionUtils.JAVAEE_NAMESPACE, "tei-class"); 096 private static final QName BODY_CONTENT = new QName(SchemaConversionUtils.JAVAEE_NAMESPACE, "body-content"); 097 098 private static final String SCHEMA_LOCATION_URL = "http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"; 099 private static final String VERSION = "2.1"; 100 101 public JspModuleBuilderExtension(Environment defaultEnvironment, NamingBuilder namingBuilders) { 102 this.defaultEnvironment = defaultEnvironment; 103 this.namingBuilders = namingBuilders; 104 } 105 106 public void createModule(Module module, Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, Environment environment, Object moduleContextInfo, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException { 107 } 108 109 public void installModule(JarFile earFile, EARContext earContext, Module module, Collection configurationStores, ConfigurationStore targetConfigurationStore, Collection repository) throws DeploymentException { 110 } 111 112 public void initContext(EARContext earContext, Module module, ClassLoader cl) throws DeploymentException { 113 } 114 115 public void addGBeans(EARContext earContext, Module module, ClassLoader cl, Collection repository) throws DeploymentException { 116 if (!(module instanceof WebModule)) { 117 //not a web module, nothing to do 118 return; 119 } 120 //TODO Only merge if we detect jsps??? 121 EnvironmentBuilder.mergeEnvironments(module.getEnvironment(), defaultEnvironment); 122 123 WebModule webModule = (WebModule) module; 124 WebAppType webApp = (WebAppType) webModule.getSpecDD(); 125 126 EARContext moduleContext = module.getEarContext(); 127 Map sharedContext = module.getSharedContext(); 128 129 GBeanData webAppData = (GBeanData) sharedContext.get(WebModule.WEB_APP_DATA); 130 131 AbstractName moduleName = moduleContext.getModuleName(); 132 Map<NamingBuilder.Key, Object> buildingContext = new HashMap<NamingBuilder.Key, Object>(); 133 buildingContext.put(NamingBuilder.GBEAN_NAME_KEY, moduleName); 134 135 //use the same jndi context as the web app 136 Map compContext = NamingBuilder.JNDI_KEY.get(sharedContext); 137 buildingContext.put(NamingBuilder.JNDI_KEY, compContext); 138 139 //use the same holder object as the web app. 140 Holder holder = NamingBuilder.INJECTION_KEY.get(sharedContext); 141 buildingContext.put(NamingBuilder.INJECTION_KEY, holder); 142 143 XmlObject jettyWebApp = webModule.getVendorDD(); 144 145 Configuration earConfiguration = earContext.getConfiguration(); 146 147 Set<String> listenerNames = new HashSet<String>(); 148 149 ClassFinder classFinder = createJspClassFinder(webApp, webModule, listenerNames); 150 webModule.setClassFinder(classFinder); 151 152 namingBuilders.buildNaming(webApp, jettyWebApp, webModule, buildingContext); 153 154 //only try to install it if reference will work. 155 //Some users (tomcat?) may have back doors into jasper that make adding this gbean unnecessary. 156 GBeanInfo webAppGBeanInfo = webAppData.getGBeanInfo(); 157 if (webAppGBeanInfo.getReference("ContextCustomizer") != null) { 158 AbstractName jspLifecycleName = moduleContext.getNaming().createChildName(moduleName, "jspLifecycleProvider", NameFactory.GERONIMO_SERVICE); 159 GBeanData gbeanData = new GBeanData(jspLifecycleName, JasperServletContextCustomizer.GBEAN_INFO); 160 gbeanData.setAttribute("holder", holder); 161 162 try { 163 moduleContext.addGBean(gbeanData); 164 } catch (GBeanAlreadyExistsException e) { 165 throw new DeploymentException("Duplicate jspLifecycleProvider", e); 166 } 167 168 webAppData.setReferencePattern("ContextCustomizer", jspLifecycleName); 169 } 170 //add listeners if possible 171 //we may need to add them in another way for tomcat 172 Object value = webAppData.getAttribute("listenerClassNames"); 173 if (value instanceof Collection) { 174 ((Collection<String>) value).addAll(listenerNames); 175 } 176 } 177 178 protected ClassFinder createJspClassFinder(WebAppType webApp, WebModule webModule, Set<String> listenerNames) throws DeploymentException { 179 List<URL> urls = getTldFiles(webApp, webModule); 180 List<Class> classes = getListenerClasses(webApp, webModule, urls, listenerNames); 181 return new ClassFinder(classes); 182 } 183 184 185 /** 186 * getTldFiles(): Find all the TLD files in the web module being deployed 187 * 188 * <p>Locations to search for these TLD file(s) (matches the precedence search order for TLD 189 * files per the JSP specs): 190 * <ol> 191 * <li>web.xml <taglib> entries 192 * <li>TLD(s) in JAR files in WEB-INF/lib 193 * <li>TLD(s) under WEB-INF 194 * <li>All TLD files in all META-INF(s) 195 * </ol> 196 * 197 * @param webApp spec DD for module 198 * @param webModule module being deployed 199 * @return list of the URL(s) for the TLD files 200 * @throws DeploymentException if there's a problem finding a tld file 201 */ 202 private List<URL> getTldFiles(WebAppType webApp, WebModule webModule) throws DeploymentException { 203 log.debug("getTldFiles( " + webApp.toString() + "," + webModule.getName() + " ): Entry"); 204 205 List<URL> tldURLs = new ArrayList<URL>(); 206 207 // 1. web.xml <taglib> entries 208 JspConfigType[] jspConfigs = webApp.getJspConfigArray(); 209 for (JspConfigType jspConfig : jspConfigs) { 210 TaglibType[] taglibs = jspConfig.getTaglibArray(); 211 for (TaglibType taglib : taglibs) { 212 String uri = taglib.getTaglibUri().getStringValue().trim(); 213 String location = taglib.getTaglibLocation().getStringValue().trim(); 214 if (!location.equals("")) { 215 if (location.startsWith("/")) { 216 location = location.substring(1); 217 } 218 try { 219 File targetFile = webModule.getEarContext().getTargetFile(new URI(location)); 220 if (targetFile!=null) { 221 tldURLs.add(targetFile.toURL()); 222 } 223 } 224 catch (MalformedURLException mfe) { 225 throw new DeploymentException("Could not locate TLD file specified in <taglib>: URI: " + uri + " Location: " + location + " " + mfe.getMessage(), mfe); 226 } 227 catch (URISyntaxException use) { 228 throw new DeploymentException("Could not locate TLD file specified in <taglib>: URI: " + uri + " Location: " + location + " " + use.getMessage(), use); 229 } 230 } 231 } 232 } 233 234 // 2. TLD(s) in JAR files in WEB-INF/lib 235 // 3. TLD(s) under WEB-INF 236 List<URL> tempURLs = scanModule(webModule); 237 for (URL webInfURL : tempURLs) { 238 tldURLs.add(webInfURL); 239 } 240 241 // 4. All TLD files in all META-INF(s) 242 tempURLs.clear(); 243 try { 244 Enumeration<URL> enumURLs = webModule.getEarContext().getClassLoader().getResources("META-INF"); 245 while (enumURLs.hasMoreElements()) { 246 URL enumURL = enumURLs.nextElement(); 247 tempURLs = scanDirectory(enumURL); 248 for (URL metaInfURL : tempURLs) { 249 tldURLs.add(metaInfURL); 250 } 251 tempURLs.clear(); 252 } 253 } 254 catch (IOException ioe) { 255 throw new DeploymentException("Could not locate TLD files located in META-INF(s) " + ioe.getMessage(), ioe); 256 } 257 258 log.debug("getTldFiles() Exit: URL[" + tldURLs.size() + "]: " + tldURLs.toString()); 259 return tldURLs; 260 } 261 262 263 /** 264 * scanModule(): Scan the module being deployed for JAR files or TLD files in the WEB-INF 265 * directory 266 * 267 * @param webModule module being deployed 268 * @return list of the URL(s) for the TLD files in the module 269 * @throws DeploymentException if module cannot be scanned 270 */ 271 private List<URL> scanModule(WebModule webModule) throws DeploymentException { 272 log.debug("scanModule( " + webModule.getName() + " ): Entry"); 273 274 List<URL> modURLs = new ArrayList<URL>(); 275 try { 276 Enumeration<JarEntry> entries = webModule.getModuleFile().entries(); 277 while (entries.hasMoreElements()) { 278 JarEntry jarEntry = entries.nextElement(); 279 if (jarEntry.getName().startsWith("WEB-INF/") && jarEntry.getName().endsWith(".tld")) { 280 File targetFile = webModule.getEarContext().getTargetFile(new URI(jarEntry.getName())); 281 if (targetFile!=null) { 282 modURLs.add(targetFile.toURL()); 283 } 284 } 285 if (jarEntry.getName().startsWith("WEB-INF/lib/") && jarEntry.getName().endsWith(".jar")) { 286 File targetFile = webModule.getEarContext().getTargetFile(new URI(jarEntry.getName())); 287 List<URL> jarUrls = scanJAR(new JarFile(targetFile), null); 288 for (URL jarURL : jarUrls) { 289 modURLs.add(jarURL); 290 } 291 } 292 } 293 } 294 catch (IOException ioe) { 295 throw new DeploymentException("Could not scan module for TLD files: " + webModule.getName() + " " + ioe.getMessage(), ioe); 296 } 297 catch (Exception e) { 298 throw new DeploymentException("Could not scan module for TLD files: " + webModule.getName() + " " + e.getMessage(), e); 299 } 300 301 log.debug("scanModule() Exit: URL[" + modURLs.size() + "]: " + modURLs.toString()); 302 return modURLs; 303 } 304 305 306 /** 307 * scanJAR(): Scan a JAR files looking for all TLD 308 * 309 * @param jarFile jar file to scan 310 * @param prefix Optional prefix to limit the search to a specific subdirectory in the JAR file 311 * @return list of the URL(s) for the TLD files in the JAR file 312 * @throws DeploymentException if jar file cannot be scanned 313 */ 314 private List<URL> scanJAR(JarFile jarFile, String prefix) throws DeploymentException { 315 log.debug("scanJAR( " + jarFile.getName() + " ): Entry"); 316 317 List<URL> jarURLs = new ArrayList<URL>(); 318 try { 319 Enumeration<JarEntry> entries = jarFile.entries(); 320 while (entries.hasMoreElements()) { 321 JarEntry jarEntry = entries.nextElement(); 322 URL tempURL = null; 323 if (prefix != null) { 324 if (jarEntry.getName().endsWith(".tld") && jarEntry.getName().startsWith(prefix)) { 325 tempURL = new URL("jar:file:" + jarFile.getName() + "!/" + jarEntry.getName()); 326 } 327 } else { 328 if (jarEntry.getName().endsWith(".tld")) { 329 tempURL = new URL("jar:file:" + jarFile.getName() + "!/" + jarEntry.getName()); 330 } 331 } 332 if (tempURL != null) { 333 jarURLs.add(tempURL); 334 } 335 } 336 } 337 catch (MalformedURLException mfe) { 338 throw new DeploymentException("Could not scan JAR file for TLD files: " + jarFile.getName() + " " + mfe.getMessage(), mfe); 339 } 340 catch (Exception e) { 341 throw new DeploymentException("Could not scan JAR file for TLD files: " + jarFile.getName() + " " + e.getMessage(), e); 342 } 343 344 log.debug("scanJAR() Exit: URL[" + jarURLs.size() + "]: " + jarURLs.toString()); 345 return jarURLs; 346 } 347 348 349 /** 350 * scanDirectory(): Scan a directory for all TLD files 351 * 352 * @param url URL for the directory to be scanned 353 * @return list of the URL(s) for the TLD files in the directory 354 * @throws DeploymentException if directory cannot be scanned 355 */ 356 private List<URL> scanDirectory(URL url) throws DeploymentException { 357 log.debug("scanDirectory( " + url.toString() + " ): Entry"); 358 359 List<URL> dirURLs = new ArrayList<URL>(); 360 File directory; 361 if (url != null) { 362 if (url.toString().startsWith("jar:file:")) { 363 try { 364 JarURLConnection jarConnection = (JarURLConnection) url.openConnection(); 365 URL urlJC = jarConnection.getJarFileURL(); 366 URI baseURI = new URI(urlJC.toString().replaceAll(" ", "%20")); 367 directory = new File(baseURI); 368 if (directory.isDirectory()) { 369 if (directory.canRead()) { 370 JarFile temp = new JarFile(directory); 371 List<URL> tempURLs = scanJAR(temp, "META-INF"); 372 for (URL jarURL : tempURLs) { 373 dirURLs.add(jarURL); 374 } 375 } else { 376 log.warn("Cannot read JAR file: " + url.toString()); 377 } 378 } 379 } 380 catch (Exception e) { 381 throw new DeploymentException("Could not scan directory for TLD files: " + url.toString() + " " + e.getMessage(), e); 382 } 383 } else if (url.toString().startsWith("file:")) { 384 try { 385 URI baseURI = new URI(url.toString().replaceAll(" ", "%20")); 386 directory = new File(baseURI); 387 if (directory.isDirectory() && directory.canRead()) { 388 File[] children = directory.listFiles(); 389 for (File child : children) { 390 if (child.getName().endsWith(".tld")) { 391 dirURLs.add(child.toURL()); 392 } 393 } 394 } else { 395 log.warn("Cannot read directory: " + url.toString()); 396 } 397 } 398 catch (Exception e) { 399 throw new DeploymentException("Could not scan directory for TLD files: " + url.toString() + " " + e.getMessage(), e); 400 } 401 } else if (url.toString().startsWith("jar:")) { 402 log.warn("URL type not accounted for: " + url.toString()); 403 } 404 } 405 406 log.debug("scanDirectory() Exit: URL[" + dirURLs.size() + "]: " + dirURLs.toString()); 407 return dirURLs; 408 } 409 410 411 private List<Class> getListenerClasses(WebAppType webApp, WebModule webModule, List<URL> urls, Set<String> listenerNames) throws DeploymentException { 412 log.debug("getListenerClasses( " + webApp.toString() + "," + '\n' + 413 webModule.getName() + " ): Entry"); 414 415 // Get the classloader from the module's EARContext 416 ClassLoader classLoader = webModule.getEarContext().getClassLoader(); 417 List<Class> classes = new ArrayList<Class>(); 418 419 for (URL url : urls) { 420 parseTldFile(url, classLoader, classes, listenerNames); 421 } 422 423 log.debug("getListenerClasses() Exit: Classes[" + classes.size() + "]: " + classes.toString()); 424 return classes; 425 } 426 427 428 private void parseTldFile(URL url, ClassLoader classLoader, List<Class> classes, Set<String> listenerNames) throws DeploymentException { 429 log.debug("parseTLDFile( " + url.toString() + " ): Entry"); 430 431 try { 432 XmlObject xml = XmlBeansUtil.parse(url, null); 433 TaglibDocument tld = convertToTaglibSchema(xml); 434 TldTaglibType tl = tld.getTaglib(); 435 436 // Get all the listeners from the TLD file 437 ListenerType[] listeners = tl.getListenerArray(); 438 for (ListenerType listener : listeners) { 439 FullyQualifiedClassType cls = listener.getListenerClass(); 440 String className = cls.getStringValue().trim(); 441 listenerNames.add(className); 442 try { 443 Class clas = classLoader.loadClass(className); 444 classes.add(clas); 445 } 446 catch (ClassNotFoundException e) { 447 log.warn("JspModuleBuilderExtension: Could not load listener class: " + className + " mentioned in TLD file at " + url.toString()); 448 } 449 } 450 451 // Get all the tags from the TLD file 452 TagType[] tags = tl.getTagArray(); 453 for (TagType tag : tags) { 454 FullyQualifiedClassType cls = tag.getTagClass(); 455 String className = cls.getStringValue().trim(); 456 try { 457 Class clas = classLoader.loadClass(className); 458 classes.add(clas); 459 } 460 catch (ClassNotFoundException e) { 461 log.warn("JspModuleBuilderExtension: Could not load tag class: " + className + " mentioned in TLD file at " + url.toString()); 462 } 463 } 464 } 465 catch (XmlException xmle) { 466 throw new DeploymentException("Could not parse TLD file at " + url.toString(), xmle); 467 } 468 catch (IOException ioe) { 469 throw new DeploymentException("Could not find TLD file at " + url.toString(), ioe); 470 } 471 472 log.debug("parseTLDFile(): Exit"); 473 } 474 475 476 /** 477 * convertToTaglibSchema(): Convert older TLD files based on the 1.1 and 1.2 DTD or the 2.0 XSD 478 * schemas 479 * 480 * <p><strong>Note(s):</strong> 481 * <ul> 482 * <li>Those tags from the 1.1 and 1.2 DTD that are no longer valid (e.g., jsp-version) are 483 * removed 484 * <li>Valid tags from the 1.1 and 1.2 DTD are converted (e.g., tlibversion to 485 * tlib-version) 486 * <li>The <taglib> root and the <tag> root elements are reordered as necessary (i.e., 487 * description, display-name) 488 * <li>The <rtexprvalue> tag is inserted in the <attribute> tag if necessary since it was 489 * not required to preceed <type> in 2.0 schema. Default value of false is used. 490 * </ul> 491 * 492 * @param xmlObject possibly old-style tag lib document 493 * @return converted TagLibDocument in the new shiny schema 494 * @throws XmlException if something goes horribly wrong 495 */ 496 protected static TaglibDocument convertToTaglibSchema(XmlObject xmlObject) throws XmlException { 497 log.debug("convertToTaglibSchema( " + xmlObject.toString() + " ): Entry"); 498 499 XmlCursor cursor = xmlObject.newCursor(); 500 XmlCursor moveable = xmlObject.newCursor(); 501 try { 502 cursor.toStartDoc(); 503 cursor.toFirstChild(); 504 if (SchemaConversionUtils.JAVAEE_NAMESPACE.equals(cursor.getName().getNamespaceURI())) { 505 log.debug("Nothing to do"); 506 } 507 else if (SchemaConversionUtils.J2EE_NAMESPACE.equals(cursor.getName().getNamespaceURI())) { 508 log.debug("Converting XSD 2.0 to 2.1 schema"); 509 SchemaConversionUtils.convertSchemaVersion(cursor, SchemaConversionUtils.JAVAEE_NAMESPACE, SCHEMA_LOCATION_URL, VERSION); 510 cursor.toStartDoc(); 511 cursor.toChild(SchemaConversionUtils.JAVAEE_NAMESPACE, "taglib"); 512 cursor.toFirstChild(); 513 do { 514 String name = cursor.getName().getLocalPart(); 515 if ("tag".equals(name)) { 516 cursor.push(); 517 cursor.toFirstChild(); 518 SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable); 519 do { 520 name = cursor.getName().getLocalPart(); 521 boolean rtexprvalueFound = false; 522 boolean typeFound = false; 523 if ("attribute".equals(name)) { 524 cursor.push(); 525 cursor.toFirstChild(); 526 do { 527 name = cursor.getName().getLocalPart(); 528 if ("rtexprvalue".equals(name)) { 529 rtexprvalueFound = true; 530 } 531 if ("type".equals(name)) { 532 typeFound = true; 533 } 534 } while (cursor.toNextSibling()); 535 cursor.pop(); 536 if (typeFound && !rtexprvalueFound) { 537 //-------------------------------------------------------------- 538 // Handle the case where the <type> tag must now be preceded by 539 // the <rtexprvalue> tag in the 2.1 schema. Cases are: 540 // 1: Only type found: 541 // We are currently positioned directly after the attribute 542 // tag (via the pop) so just insert the rtexprvalue tag 543 // with the default value. The tags will be properly 544 // ordered below. 545 // 2: Both type and rtexprvalue found: 546 // The tags will be properly ordered below with the 547 // convertToAttributeGroup() call, so nothing to do 548 // 3: Only rtexprvalue found: 549 // Nothing to do 550 // 4: Neither found: 551 // Nothing to do 552 //-------------------------------------------------------------- 553 cursor.push(); 554 cursor.toFirstChild(); 555 cursor.insertElementWithText("rtexprvalue", SchemaConversionUtils.JAVAEE_NAMESPACE, "false"); 556 cursor.pop(); 557 } 558 cursor.push(); 559 cursor.toFirstChild(); 560 SchemaConversionUtils.convertToTldAttribute(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable); 561 cursor.pop(); 562 } 563 } while (cursor.toNextSibling()); 564 cursor.pop(); 565 // Do this conversion last after the other tags have been converted 566 SchemaConversionUtils.convertToTldTag(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable); 567 } 568 } while (cursor.toNextSibling()); 569 } 570 else { 571 log.debug("Converting DTD to 2.1 schema"); 572 SchemaConversionUtils.convertToSchema(cursor, SchemaConversionUtils.JAVAEE_NAMESPACE, SCHEMA_LOCATION_URL, VERSION); 573 cursor.toStartDoc(); 574 cursor.toChild(SchemaConversionUtils.JAVAEE_NAMESPACE, "taglib"); 575 cursor.toFirstChild(); 576 SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable); 577 do { 578 String name = cursor.getName().getLocalPart(); 579 if ("jsp-version".equals(name) || 580 "jspversion".equals(name) || 581 "info".equals(name)) { 582 cursor.removeXmlContents(); 583 cursor.removeXml(); 584 } 585 if ("tlibversion".equals(name)) { 586 cursor.setName(TLIB_VERSION); 587 } 588 if ("tlibversion".equals(name)) { 589 cursor.setName(TLIB_VERSION); 590 } 591 if ("shortname".equals(name)) { 592 cursor.setName(SHORT_NAME); 593 } 594 if ("tag".equals(name)) { 595 cursor.push(); 596 cursor.toFirstChild(); 597 SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable); 598 boolean bodyContentFound = false; 599 do { 600 name = cursor.getName().getLocalPart(); 601 if ("tagclass".equals(name)) { 602 cursor.setName(TAG_CLASS); 603 } 604 if ("teiclass".equals(name)) { 605 cursor.setName(TEI_CLASS); 606 } 607 if ("bodycontent".equals(name)) { 608 cursor.setName(BODY_CONTENT); 609 bodyContentFound = true; 610 } 611 if ("body-content".equals(name)) { 612 bodyContentFound = true; 613 } 614 if ("attribute".equals(name)) { 615 cursor.push(); 616 cursor.toFirstChild(); 617 SchemaConversionUtils.convertToTldAttribute(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable); 618 cursor.pop(); 619 } 620 if ("variable".equals(name)) { 621 cursor.push(); 622 cursor.toFirstChild(); 623 SchemaConversionUtils.convertToTldVariable(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable); 624 cursor.pop(); 625 } 626 if ("info".equals(name)) { 627 cursor.removeXmlContents(); 628 cursor.removeXml(); 629 } 630 } while (cursor.toNextSibling()); 631 cursor.pop(); 632 if (!bodyContentFound) { 633 //-------------------------------------------------------------- 634 // Handle the case where the <body-content> tag is missing. We 635 // are currently positioned directly after the <tag> attribute 636 // (via the pop) so just insert the <body-content> tag with the 637 // default value. The tags will be properly ordered below. 638 //-------------------------------------------------------------- 639 cursor.push(); 640 cursor.toFirstChild(); 641 cursor.insertElementWithText("body-content", SchemaConversionUtils.JAVAEE_NAMESPACE, "scriptless"); 642 cursor.pop(); 643 } 644 // Do this conversion last after the other tags have been converted 645 cursor.push(); 646 cursor.toFirstChild(); 647 SchemaConversionUtils.convertToTldTag(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable); 648 cursor.pop(); 649 } 650 if ("validator".equals(name)) { 651 cursor.push(); 652 cursor.toFirstChild(); 653 SchemaConversionUtils.convertToTldValidator(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable); 654 do { 655 name = cursor.getName().getLocalPart(); 656 if ("init-param".equals(name)) { 657 cursor.push(); 658 cursor.toFirstChild(); 659 SchemaConversionUtils.convertToTldInitParam(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable); 660 cursor.pop(); 661 } 662 } while (cursor.toNextSibling()); 663 cursor.pop(); 664 } 665 } while (cursor.toNextSibling()); 666 } 667 } 668 finally { 669 cursor.dispose(); 670 moveable.dispose(); 671 } 672 XmlObject result = xmlObject.changeType(TaglibDocument.type); 673 if (result != null) { 674 try { 675 XmlBeansUtil.validateDD(result); 676 } catch (XmlException e) { 677 log.warn("Invalid transformed taglib", e); 678 } 679 log.debug("convertToTaglibSchema( " + result.toString() + " ): Exit 1"); 680 return (TaglibDocument) result; 681 } 682 try { 683 XmlBeansUtil.validateDD(xmlObject); 684 } catch (XmlException e) { 685 log.warn("Invalid transformed taglib", e); 686 } 687 log.debug("convertToTaglibSchema( " + xmlObject.toString() + " ): Exit 2"); 688 return (TaglibDocument) xmlObject; 689 } 690 691 692 public static final GBeanInfo GBEAN_INFO; 693 694 static { 695 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JspModuleBuilderExtension.class, NameFactory.MODULE_BUILDER); 696 infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true); 697 infoBuilder.addReference("NamingBuilders", NamingBuilder.class, NameFactory.MODULE_BUILDER); 698 699 infoBuilder.setConstructor(new String[]{ 700 "defaultEnvironment", 701 "NamingBuilders"}); 702 GBEAN_INFO = infoBuilder.getBeanInfo(); 703 } 704 705 public static GBeanInfo getGBeanInfo() { 706 return GBEAN_INFO; 707 } 708 }