/*
* JBoss, Home of Professional Open Source.
* Copyright 2014, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.ee.structure;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.jboss.as.ee.logging.EeLogger;
import org.jboss.as.ee.metadata.EJBClientDescriptorMetaData;
import org.jboss.as.server.deployment.DeploymentPhaseContext;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
import org.jboss.as.server.deployment.module.ResourceRoot;
import org.jboss.as.server.moduleservice.ServiceModuleLoader;
import org.jboss.metadata.property.PropertyReplacer;
import org.jboss.staxmapper.XMLMapper;
import org.jboss.vfs.VirtualFile;
/**
* A deployment unit processor which parses jboss-ejb-client.xml in top level deployments.
* If a jboss-ejb-client.xml is found in the top level deployment, then this processor creates a {@link EJBClientDescriptorMetaData}
* out of it and attaches it to the deployment unit at {@link Attachments#EJB_CLIENT_METADATA}
*
* @author Jaikiran Pai
* @author <a href=mailto:tadamski@redhat.com>Tomasz Adamski</a>
* @author <a href="mailto:wfink@redhat.com">Wolf-Dieter Fink</a>
*/
public class EJBClientDescriptorParsingProcessor implements DeploymentUnitProcessor {
public static final String[] EJB_CLIENT_DESCRIPTOR_LOCATIONS = { "META-INF/jboss-ejb-client.xml",
"WEB-INF/jboss-ejb-client.xml" };
private static final QName ROOT_1_0 = new QName(EJBClientDescriptor10Parser.NAMESPACE_1_0, "jboss-ejb-client");
private static final QName ROOT_1_1 = new QName(EJBClientDescriptor11Parser.NAMESPACE_1_1, "jboss-ejb-client");
private static final QName ROOT_1_2 = new QName(EJBClientDescriptor12Parser.NAMESPACE_1_2, "jboss-ejb-client");
private static final QName ROOT_1_3 = new QName(EJBClientDescriptor13Parser.NAMESPACE_1_3, "jboss-ejb-client");
private static final QName ROOT_NO_NAMESPACE = new QName("jboss-ejb-client");
private static final XMLInputFactory INPUT_FACTORY = XMLInputFactory.newInstance();
@Override
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
final XMLMapper mapper = createMapper(deploymentUnit);
final ResourceRoot resourceRoot = deploymentUnit
.getAttachment(org.jboss.as.server.deployment.Attachments.DEPLOYMENT_ROOT);
final ServiceModuleLoader moduleLoader = deploymentUnit
.getAttachment(org.jboss.as.server.deployment.Attachments.SERVICE_MODULE_LOADER);
VirtualFile descriptorFile = null;
for (final String loc : EJB_CLIENT_DESCRIPTOR_LOCATIONS) {
final VirtualFile file = resourceRoot.getRoot().getChild(loc);
if (file.exists()) {
descriptorFile = file;
break;
}
}
if (descriptorFile == null) {
return;
}
if (deploymentUnit.getParent() != null) {
EeLogger.ROOT_LOGGER.subdeploymentIgnored(descriptorFile.getPathName());
return;
}
final File ejbClientDeploymentDescriptorFile;
try {
ejbClientDeploymentDescriptorFile = descriptorFile.getPhysicalFile();
} catch (IOException e) {
throw EeLogger.ROOT_LOGGER.failedToProcessEJBClientDescriptor(e);
}
final EJBClientDescriptorMetaData ejbClientDescriptorMetaData = parse(ejbClientDeploymentDescriptorFile, mapper);
EeLogger.ROOT_LOGGER.debugf("Successfully parsed jboss-ejb-client.xml for deployment unit %s", deploymentUnit);
// attach the metadata
deploymentUnit.putAttachment(Attachments.EJB_CLIENT_METADATA, ejbClientDescriptorMetaData);
}
@Override
public void undeploy(DeploymentUnit context) {
}
private XMLMapper createMapper(final DeploymentUnit deploymentUnit) {
final XMLMapper mapper = XMLMapper.Factory.create();
final PropertyReplacer propertyReplacer = EjbClientDescriptorPropertyReplacement.propertyReplacer(deploymentUnit);
final EJBClientDescriptor10Parser ejbClientDescriptor10Parser = new EJBClientDescriptor10Parser(propertyReplacer);
mapper.registerRootElement(ROOT_1_0, ejbClientDescriptor10Parser);
final EJBClientDescriptor11Parser ejbClientDescriptor11Parser = new EJBClientDescriptor11Parser(propertyReplacer);
mapper.registerRootElement(ROOT_1_1, ejbClientDescriptor11Parser);
final EJBClientDescriptor11Parser ejbClientDescriptor12Parser = new EJBClientDescriptor12Parser(propertyReplacer);
mapper.registerRootElement(ROOT_1_2, ejbClientDescriptor12Parser);
final EJBClientDescriptor13Parser ejbClientDescriptor13Parser = new EJBClientDescriptor13Parser(propertyReplacer);
mapper.registerRootElement(ROOT_1_3, ejbClientDescriptor13Parser);
mapper.registerRootElement(ROOT_NO_NAMESPACE, ejbClientDescriptor13Parser);
return mapper;
}
private EJBClientDescriptorMetaData parse(final File file, final XMLMapper mapper) throws DeploymentUnitProcessingException {
final FileInputStream fis;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
throw EeLogger.ROOT_LOGGER.failedToProcessEJBClientDescriptor(e);
}
try {
return parse(fis, file, mapper);
} finally {
safeClose(fis);
}
}
private EJBClientDescriptorMetaData parse(final InputStream source, final File file, final XMLMapper mapper)
throws DeploymentUnitProcessingException {
try {
final XMLInputFactory inputFactory = INPUT_FACTORY;
setIfSupported(inputFactory, XMLInputFactory.IS_VALIDATING, Boolean.FALSE);
setIfSupported(inputFactory, XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
final XMLStreamReader streamReader = inputFactory.createXMLStreamReader(source);
try {
final EJBClientDescriptorMetaData result = new EJBClientDescriptorMetaData();
mapper.parseDocument(result, streamReader);
return result;
} finally {
safeClose(streamReader);
}
} catch (XMLStreamException e) {
throw EeLogger.ROOT_LOGGER.xmlErrorParsingEJBClientDescriptor(e, file.getAbsolutePath());
}
}
private void setIfSupported(final XMLInputFactory inputFactory, final String property, final Object value) {
if (inputFactory.isPropertySupported(property)) {
inputFactory.setProperty(property, value);
}
}
private static void safeClose(final Closeable closeable) {
if (closeable != null)
try {
closeable.close();
} catch (IOException e) {
// ignore
}
}
private static void safeClose(final XMLStreamReader streamReader) {
if (streamReader != null)
try {
streamReader.close();
} catch (XMLStreamException e) {
// ignore
}
}
}