public static WebMetaData parse( XMLStreamReader reader, DTDInfo info, boolean validation, PropertyReplacer propertyReplacer) throws XMLStreamException { if (reader == null) throw new IllegalArgumentException("Null reader"); if (info == null) throw new IllegalArgumentException("Null info"); reader.require(START_DOCUMENT, null, null); // Read until the first start element while (reader.hasNext() && reader.next() != START_ELEMENT) ; String schemaLocation = readSchemaLocation(reader); Version version = null; if (info.getPublicID() != null) { version = Version.fromPublicID(info.getPublicID()); } if (version == null && info.getSystemID() != null) { version = Version.fromSystemID(info.getSystemID()); } if (version == null && schemaLocation != null) { version = Version.fromSystemID(schemaLocation); } if (version == null) { // Look at the version attribute String versionString = null; final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { if (attributeHasNamespace(reader, i)) { continue; } final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); if (attribute == Attribute.VERSION) { versionString = reader.getAttributeValue(i); } } if ("2.4".equals(versionString)) { version = Version.SERVLET_2_4; } else if ("2.5".equals(versionString)) { version = Version.SERVLET_2_5; } else if ("3.0".equals(versionString)) { version = Version.SERVLET_3_0; } } if (version == null) version = Version.SERVLET_3_0; // throw new IllegalStateException("Cannot obtain servlet version"); WebMetaData wmd = null; switch (version) { case SERVLET_2_2: wmd = new Web22MetaData(); break; case SERVLET_2_3: wmd = new Web23MetaData(); break; case SERVLET_2_4: wmd = new Web24MetaData(); break; case SERVLET_2_5: wmd = new Web25MetaData(); break; case SERVLET_3_0: wmd = new Web30MetaData(); break; } // Set the publicId / systemId if (info != null) wmd.setDTD(info.getBaseURI(), info.getPublicID(), info.getSystemID()); // Set the schema location if we have one if (schemaLocation != null) wmd.setSchemaLocation(schemaLocation); // Handle attributes final int count = reader.getAttributeCount(); for (int i = 0; i < count; i++) { final String value = reader.getAttributeValue(i); if (attributeHasNamespace(reader, i)) { continue; } final Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); switch (attribute) { case ID: { wmd.setId(value); break; } case VERSION: { wmd.setVersion(value); break; } case METADATA_COMPLETE: { if (wmd instanceof Web25MetaData || wmd instanceof Web30MetaData) { if (Boolean.TRUE.equals(Boolean.valueOf(value))) { if (wmd instanceof Web25MetaData) { ((Web25MetaData) wmd).setMetadataComplete(true); } if (wmd instanceof Web30MetaData) { ((Web30MetaData) wmd).setMetadataComplete(true); } } } else { throw unexpectedAttribute(reader, i); } break; } default: throw unexpectedAttribute(reader, i); } } DescriptionGroupMetaData descriptionGroup = new DescriptionGroupMetaData(); EnvironmentRefsGroupMetaData env = new EnvironmentRefsGroupMetaData(); // Handle elements while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { if (WebCommonMetaDataParser.parse(reader, wmd, propertyReplacer)) { continue; } if (EnvironmentRefsGroupMetaDataParser.parse(reader, env, propertyReplacer)) { if (wmd.getJndiEnvironmentRefsGroup() == null) { wmd.setJndiEnvironmentRefsGroup(env); } continue; } if (DescriptionGroupMetaDataParser.parse(reader, descriptionGroup)) { if (wmd.getDescriptionGroup() == null) { wmd.setDescriptionGroup(descriptionGroup); } continue; } final Element element = Element.forName(reader.getLocalName()); switch (element) { case ABSOLUTE_ORDERING: if (wmd instanceof Web30MetaData) { ((Web30MetaData) wmd) .setAbsoluteOrdering( AbsoluteOrderingMetaDataParser.parse(reader, propertyReplacer)); } else { throw unexpectedElement(reader); } break; case MODULE_NAME: if (wmd instanceof Web30MetaData) { ((Web30MetaData) wmd).setModuleName(getElementText(reader, propertyReplacer)); } else { throw unexpectedElement(reader); } break; case TAGLIB: if (wmd instanceof Web22MetaData || wmd instanceof Web23MetaData) { JspConfigMetaData jspConfig = wmd.getJspConfig(); if (jspConfig == null) { jspConfig = new JspConfigMetaData(); wmd.setJspConfig(jspConfig); } List<TaglibMetaData> taglibs = jspConfig.getTaglibs(); if (taglibs == null) { taglibs = new ArrayList<TaglibMetaData>(); jspConfig.setTaglibs(taglibs); } taglibs.add(TaglibMetaDataParser.parse(reader, propertyReplacer)); } else { throw unexpectedElement(reader); } break; default: throw unexpectedElement(reader); } } return wmd; }
@Override public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); if (!DeploymentTypeMarker.isType(DeploymentType.WAR, deploymentUnit)) { return; // Skip non web deployments } final ResourceRoot deploymentRoot = deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT); final VirtualFile alternateDescriptor = deploymentRoot.getAttachment( org.jboss.as.ee.structure.Attachments.ALTERNATE_WEB_DEPLOYMENT_DESCRIPTOR); // Locate the descriptor final VirtualFile webXml; if (alternateDescriptor != null) { webXml = alternateDescriptor; } else { webXml = deploymentRoot.getRoot().getChild(WEB_XML); } final WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY); assert warMetaData != null; if (webXml.exists()) { InputStream is = null; try { is = webXml.openStream(); final XMLInputFactory inputFactory = XMLInputFactory.newInstance(); MetaDataElementParser.DTDInfo dtdInfo = new MetaDataElementParser.DTDInfo(); inputFactory.setXMLResolver(dtdInfo); final XMLStreamReader xmlReader = inputFactory.createXMLStreamReader(is); WebMetaData webMetaData = WebMetaDataParser.parse( xmlReader, dtdInfo, SpecDescriptorPropertyReplacement.propertyReplacer(deploymentUnit)); if (schemaValidation && webMetaData.getSchemaLocation() != null) { XMLSchemaValidator validator = new XMLSchemaValidator(new XMLResourceResolver()); InputStream xmlInput = webXml.openStream(); try { if (webMetaData.is23()) validator.validate( "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN", xmlInput); else if (webMetaData.is24()) validator.validate("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd", xmlInput); else if (webMetaData.is25()) validator.validate("http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd", xmlInput); else if (webMetaData.is30()) validator.validate("http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd", xmlInput); else if (webMetaData.is31()) validator.validate("http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd", xmlInput); else validator.validate( "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN", xmlInput); } catch (SAXException e) { throw new DeploymentUnitProcessingException("Failed to validate " + webXml, e); } finally { xmlInput.close(); } } warMetaData.setWebMetaData(webMetaData); } catch (XMLStreamException e) { throw new DeploymentUnitProcessingException( MESSAGES.failToParseXMLDescriptor( webXml, e.getLocation().getLineNumber(), e.getLocation().getColumnNumber())); } catch (IOException e) { throw new DeploymentUnitProcessingException(MESSAGES.failToParseXMLDescriptor(webXml), e); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { // Ignore } } } }