Index: org/jboss/deployment/JBossWebAppParsingDeployer.java =================================================================== --- org/jboss/deployment/JBossWebAppParsingDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/JBossWebAppParsingDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -73,23 +73,14 @@ protected void createMetaData(DeploymentUnit unit, String name, String suffix) throws DeploymentException { super.createMetaData(unit, name, suffix); - // Merge the spec metadata - WebMetaData specMetaData = unit.getAttachment(WebMetaData.class); - JBossWebMetaData metaData = unit.getAttachment(JBossWebMetaData.class); - if(specMetaData == null && metaData == null) - return; + JBossWebMetaData metaData = unit.getAttachment(JBossWebMetaData.class); // If there no JBossWebMetaData was created from a jboss-web.xml, create one if (metaData == null) { metaData = new JBossWebMetaData(); } - // Create a merged view - JBossWebMetaData mergedMetaData = new JBossWebMetaData(); - mergedMetaData.merge(metaData, specMetaData); - // Set the merged as the output - unit.getTransientManagedObjects().addAttachment(JBossWebMetaData.class, mergedMetaData); - // Keep the raw parsed metadata as well + unit.getTransientManagedObjects().addAttachment(JBossWebMetaData.class, metaData); unit.addAttachment("Raw"+JBossWebMetaData.class.getName(), metaData, JBossWebMetaData.class); } @@ -102,12 +93,10 @@ { super.createMetaData(unit, name, suffix, key); - WebMetaData wmd = unit.getTransientManagedObjects().getAttachment(WebMetaData.class); JBossWebMetaData result = unit.getTransientManagedObjects().getAttachment(getOutput()); - if (result == null && wmd != null) + if (result == null) { result = new JBossWebMetaData(); - result.merge(null, wmd); unit.getTransientManagedObjects().addAttachment(key, result, getOutput()); } } Index: org/jboss/deployment/TldParsingDeployer.java =================================================================== --- org/jboss/deployment/TldParsingDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 0) +++ org/jboss/deployment/TldParsingDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -0,0 +1,65 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2006, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt 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.deployment; + +import org.jboss.deployers.vfs.spi.deployer.SchemaResolverDeployer; +import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit; +import org.jboss.metadata.web.spec.TldMetaData; +import org.jboss.virtual.VirtualFile; + +/** + * An ObjectModelFactoryDeployer for translating tag library descriptors into + * TldMetaData instances. + * + * @author Scott.Stark@jboss.org + * @author adrian@jboss.org + * @version $Revision: 82920 $ + */ +public class TldParsingDeployer extends SchemaResolverDeployer +{ + /** + * Create a new TldParsingDeployer. + */ + public TldParsingDeployer() + { + super(TldMetaData.class); + setSuffix(".tld"); + setAllowMultipleFiles(true); + } + + protected void init(VFSDeploymentUnit unit, TldMetaData metaData, VirtualFile file) throws Exception + { + unit.addAttachment(file.toURL().toString(), metaData, getOutput()); + } + + protected TldMetaData parse(VirtualFile file) throws Exception { + if (file == null) + throw new IllegalArgumentException("Null file"); + + // Implicit TLDs are reserved as the "implicit.tld" name + if (file.getName().equals("implicit.tld")) { + return new TldMetaData(); + } else { + return super.parse(file); + } + } +} Index: org/jboss/deployment/EarLibExcludeDeployer.java =================================================================== --- org/jboss/deployment/EarLibExcludeDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/EarLibExcludeDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -77,7 +77,7 @@ * as we move up the hierarchy, and if there is no VFS caching * we might not have parent for the first file instance. * - * But otoh, by default we should have some VFS caching, which makes this OK. + * But otoh, by default we should have some VFS caching, which makes this OK. */ private class UrlExcludeResourceFilter implements ResourceFilter { Index: org/jboss/deployment/LegacyWebXmlLessDeployer.java =================================================================== --- org/jboss/deployment/LegacyWebXmlLessDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/LegacyWebXmlLessDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -58,11 +58,11 @@ // Detect and ignore OSGi WAR deployments // FIXME Use typed OSGiMetaData when we have it available at runtime - String bundleSymbolicName = (String) unit.getAttachment("org.jboss.osgi.bundle.symbolic.name"); + String bundleSymbolicName = unit.getAttachment("org.jboss.osgi.bundle.symbolic.name", String.class); if (bundleSymbolicName != null) { log.debug("Ignore OSGi webapp: " + bundleSymbolicName); - return; + return; } log.debug("Web archive doesn't contain web.xml: " + unit.getName()); Index: org/jboss/deployment/EARDeployerMBean.java =================================================================== --- org/jboss/deployment/EARDeployerMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/EARDeployerMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -32,7 +32,7 @@ * @author Scott Stark * @version $Revision$ */ -public interface EARDeployerMBean extends SubDeployerExtMBean +public interface EARDeployerMBean { /** The default ObjectName */ ObjectName OBJECT_NAME = ObjectNameFactory.create("jboss.j2ee:service=EARDeployer"); Index: org/jboss/deployment/vfs/VFSCacheStatisticsMBean.java =================================================================== --- org/jboss/deployment/vfs/VFSCacheStatisticsMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/vfs/VFSCacheStatisticsMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -24,6 +24,8 @@ import java.util.Date; /** + * VFS cache stats mbean interface. + * * @author Ales Justin */ public interface VFSCacheStatisticsMBean Index: org/jboss/deployment/vfs/VFSCacheOperations.java =================================================================== --- org/jboss/deployment/vfs/VFSCacheOperations.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 0) +++ org/jboss/deployment/vfs/VFSCacheOperations.java (.../trunk/server/src/main/java) (revision 97312) @@ -0,0 +1,68 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, 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.deployment.vfs; + +import org.jboss.virtual.spi.cache.VFSCache; +import org.jboss.virtual.spi.cache.VFSCacheFactory; + +/** + * Simple vfs cache ops. + * + * @author Ales Justin + */ +public class VFSCacheOperations implements VFSCacheOperationsMBean +{ + private VFSCache cache; + + private VFSCache getCache() + { + if (cache == null) + cache = VFSCacheFactory.getInstance(); + + return cache; + } + + /** + * Set the vfs cache. + * + * @param cache the vfs cache + */ + public void setCache(VFSCache cache) + { + this.cache = cache; + } + + public void start() throws Exception + { + getCache().start(); + } + + public void stop() + { + getCache().stop(); + } + + public void flush() + { + getCache().flush(); + } +} \ No newline at end of file Property changes on: org/jboss/deployment/vfs/VFSCacheOperations.java ___________________________________________________________________ Added: svn:mergeinfo Added: svn:eol-style + native Added: svn:keywords + Author Date Id Revision Index: org/jboss/deployment/vfs/VFSCacheOperationsMBean.java =================================================================== --- org/jboss/deployment/vfs/VFSCacheOperationsMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 0) +++ org/jboss/deployment/vfs/VFSCacheOperationsMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -0,0 +1,47 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, 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.deployment.vfs; + +/** + * VFS cache ops mbean interface. + * + * @author Ales Justin + */ +public interface VFSCacheOperationsMBean +{ + /** + * Start the vfs cache. + * + * @throws Exception for any error + */ + void start() throws Exception; + + /** + * Stop the vfs cache. + */ + void stop(); + + /** + * Flush the vfs cache. + */ + void flush(); +} \ No newline at end of file Property changes on: org/jboss/deployment/vfs/VFSCacheOperationsMBean.java ___________________________________________________________________ Added: svn:mergeinfo Added: svn:eol-style + native Added: svn:keywords + Author Date Id Revision Index: org/jboss/deployment/AnnotationMetaDataDeployer.java =================================================================== --- org/jboss/deployment/AnnotationMetaDataDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/AnnotationMetaDataDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -25,6 +25,7 @@ import java.lang.reflect.AnnotatedElement; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.jar.Attributes; @@ -37,7 +38,7 @@ import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit; import org.jboss.metadata.annotation.creator.client.ApplicationClient5MetaDataCreator; import org.jboss.metadata.annotation.creator.ejb.jboss.JBoss50Creator; -import org.jboss.metadata.annotation.creator.web.Web25MetaDataCreator; +import org.jboss.metadata.annotation.creator.web.Web30MetaDataCreator; import org.jboss.metadata.annotation.finder.AnnotationFinder; import org.jboss.metadata.annotation.finder.DefaultAnnotationFinder; import org.jboss.metadata.client.spec.ApplicationClientMetaData; @@ -45,6 +46,7 @@ import org.jboss.metadata.ejb.spec.EjbJar3xMetaData; import org.jboss.metadata.ejb.spec.EjbJarMetaData; import org.jboss.metadata.web.spec.Web25MetaData; +import org.jboss.metadata.web.spec.Web30MetaData; import org.jboss.metadata.web.spec.WebMetaData; import org.jboss.virtual.VFSUtils; import org.jboss.virtual.VirtualFile; @@ -54,12 +56,10 @@ * annotations * * @author Scott.Stark@jboss.org - * @author Thomas.Diesler@jboss.org * @version $Revision$ */ public class AnnotationMetaDataDeployer extends AbstractDeployer { - public static final String ANNOTATION_META_DATA_COMPLETE = "org.jboss.deployment.annotation.metadata.complete"; public static final String EJB_ANNOTATED_ATTACHMENT_NAME = "annotated."+EjbJarMetaData.class.getName(); public static final String CLIENT_ANNOTATED_ATTACHMENT_NAME = "annotated."+ApplicationClientMetaData.class.getName(); public static final String WEB_ANNOTATED_ATTACHMENT_NAME = "annotated."+WebMetaData.class.getName(); @@ -90,7 +90,7 @@ { if (unit instanceof VFSDeploymentUnit == false) return; - + VFSDeploymentUnit vfsDeploymentUnit = (VFSDeploymentUnit) unit; deploy(vfsDeploymentUnit); } @@ -113,48 +113,42 @@ protected void deploy(VFSDeploymentUnit unit) throws DeploymentException { - boolean isComplete = this.isMetaDataCompleteIsDefault(); - - // Allow deployment units to say that they are metadata complete - // in terms of annotation processing - if (isComplete == false) + /* Ignore any spec metadata complete deployments. This expects that a + deployment unit only represents one of the client, ejb or web + deployments and its metadata completeness applies to the unit in terms + of whether annotations should be scanned for. + */ + boolean isComplete = this.isMetaDataCompleteIsDefault(); + EjbJarMetaData ejbJarMetaData = unit.getAttachment(EjbJarMetaData.class); + if(ejbJarMetaData != null && ejbJarMetaData instanceof EjbJar3xMetaData) { - Boolean unitComplete = unit.getAttachment(ANNOTATION_META_DATA_COMPLETE, Boolean.class); - isComplete = Boolean.TRUE.equals(unitComplete); + isComplete |= ((EjbJar3xMetaData) ejbJarMetaData).isMetadataComplete(); } - - /* Ignore any spec metadata complete deployments. This expects that a - deployment unit only represents one of the client, ejb or web - deployments and its metadata completeness applies to the unit in terms - of whether annotations should be scanned for. - */ - EjbJarMetaData ejbJarMetaData = unit.getAttachment(EjbJarMetaData.class); + else if(ejbJarMetaData != null) + { + // Any ejb-jar.xml 2.1 or earlier deployment is metadata complete + isComplete = true; + } WebMetaData webMetaData = unit.getAttachment(WebMetaData.class); - ApplicationClientMetaData clientMetaData = unit.getAttachment(ApplicationClientMetaData.class); - if (isComplete == false) + if(webMetaData != null) { - if(ejbJarMetaData != null && ejbJarMetaData instanceof EjbJar3xMetaData) - { - isComplete |= ((EjbJar3xMetaData) ejbJarMetaData).isMetadataComplete(); - } - else if(ejbJarMetaData != null) - { - // Any ejb-jar.xml 2.1 or earlier deployment is metadata complete - isComplete = true; - } - if(webMetaData != null && webMetaData instanceof Web25MetaData) - { - isComplete |= ((Web25MetaData)webMetaData).isMetadataComplete(); - } - else if(webMetaData != null) - { - // Any web.xml 2.4 or earlier deployment is metadata complete - isComplete = true; - } - if(clientMetaData != null) - isComplete |= clientMetaData.isMetadataComplete(); + if (webMetaData instanceof Web25MetaData) + { + isComplete |= ((Web25MetaData)webMetaData).isMetadataComplete(); + } + else if (webMetaData instanceof Web30MetaData) + { + isComplete |= ((Web30MetaData)webMetaData).isMetadataComplete(); + } + else + { + // Any web.xml 2.4 or earlier deployment is metadata complete + isComplete = true; + } } - + ApplicationClientMetaData clientMetaData = unit.getAttachment(ApplicationClientMetaData.class); + if(clientMetaData != null) + isComplete |= clientMetaData.isMetadataComplete(); if(isComplete) { log.debug("Deployment is metadata-complete, skipping annotation processing" @@ -165,7 +159,6 @@ ); return; } - VirtualFile root = unit.getRoot(); boolean isLeaf = true; try @@ -182,8 +175,7 @@ if(classpath == null || classpath.isEmpty()) return; - boolean trace = log.isTraceEnabled(); - if (trace) + if (log.isTraceEnabled()) log.trace("Deploying annotations for unit: " + unit + ", classpath: " + classpath); try @@ -208,12 +200,19 @@ protected void processMetaData(VFSDeploymentUnit unit, WebMetaData webMetaData, ApplicationClientMetaData clientMetaData, List classpath) throws Exception { String mainClassName = getMainClassName(unit); - Collection> classes = getClasses(unit, mainClassName, classpath); + Collection> classes = new HashSet>(); + Map>> classesPerJar = new HashMap>>(); + for (VirtualFile path : classpath) + { + Collection> currentClasses = getClasses(unit, mainClassName, path); + classesPerJar.put(path, currentClasses); + classes.addAll(currentClasses); + } if (classes.size() > 0) { AnnotationFinder finder = new DefaultAnnotationFinder(); if (webMetaData != null) - processJBossWebMetaData(unit, finder, classes); + processJBossWebMetaData(unit, finder, classesPerJar); else if (clientMetaData != null || mainClassName != null) processJBossClientMetaData(unit, finder, classes); else @@ -230,22 +229,21 @@ * @return possible classes containing metadata annotations * @throws IOException for any error */ - protected Collection> getClasses(VFSDeploymentUnit unit, String mainClassName, List classpath) throws IOException + protected Collection> getClasses(VFSDeploymentUnit unit, String mainClassName, VirtualFile classpath) throws IOException { - Map> classpathClasses = new HashMap>(); - for(VirtualFile path : classpath) + AnnotatedClassFilter classVisitor = new AnnotatedClassFilter(unit, unit.getClassLoader(), classpath, mainClassName); + classpath.visit(classVisitor); + Map> classes = classVisitor.getAnnotatedClasses(); + if (classes != null && classes.size() > 0) { - AnnotatedClassFilter classVisitor = new AnnotatedClassFilter(unit, unit.getClassLoader(), path, mainClassName); - path.visit(classVisitor); - Map> classes = classVisitor.getAnnotatedClasses(); - if(classes != null && classes.size() > 0) - { - if(log.isTraceEnabled()) - log.trace("Annotated classes: " + classes); - classpathClasses.putAll(classes); - } + if(log.isTraceEnabled()) + log.trace("Annotated classes: " + classes); } - return classpathClasses.values(); + else + { + classes = new HashMap>(); + } + return classes.values(); } /** @@ -283,12 +281,22 @@ * @param classes the candidate classes */ protected void processJBossWebMetaData(VFSDeploymentUnit unit, - AnnotationFinder finder, Collection> classes) + AnnotationFinder finder, Map>> classes) { - Web25MetaDataCreator creator = new Web25MetaDataCreator(finder); - WebMetaData annotationMetaData = creator.create(classes); - if(annotationMetaData != null) - unit.addAttachment(WEB_ANNOTATED_ATTACHMENT_NAME, annotationMetaData, WebMetaData.class); + Web30MetaDataCreator creator = new Web30MetaDataCreator(finder); + boolean metaData = false; + for (VirtualFile path : classes.keySet()) + { + WebMetaData annotationMetaData = creator.create(classes.get(path)); + log.debug("Add annotations: " + WEB_ANNOTATED_ATTACHMENT_NAME + ":" + path.getName()); + if (annotationMetaData != null) + { + unit.addAttachment(WEB_ANNOTATED_ATTACHMENT_NAME + ":" + path.getName(), annotationMetaData, WebMetaData.class); + metaData = true; + } + } + if (metaData) + unit.addAttachment(WEB_ANNOTATED_ATTACHMENT_NAME, Boolean.TRUE); } /** Index: org/jboss/deployment/EARStructure.java =================================================================== --- org/jboss/deployment/EARStructure.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/EARStructure.java (.../trunk/server/src/main/java) (revision 97312) @@ -29,12 +29,10 @@ import org.jboss.deployers.spi.DeploymentException; import org.jboss.deployers.spi.structure.ContextInfo; -import org.jboss.deployers.structure.spi.helpers.RelativeDeploymentContextComparator; import org.jboss.deployers.vfs.plugins.structure.AbstractVFSStructureDeployer; import org.jboss.deployers.vfs.spi.structure.StructureContext; import org.jboss.metadata.ear.jboss.JBossAppMetaData; import org.jboss.metadata.ear.jboss.ServiceModuleMetaData; -import org.jboss.metadata.ear.jboss.JBossAppMetaData.ModuleOrder; import org.jboss.metadata.ear.spec.AbstractModule; import org.jboss.metadata.ear.spec.ConnectorModuleMetaData; import org.jboss.metadata.ear.spec.EarMetaData; @@ -84,7 +82,7 @@ /** * Set the relative order to 1000 by default - */ + */ public EARStructure() { setRelativeOrder(1000); @@ -192,7 +190,7 @@ { if (libDir == null) libDir = "lib"; - + // Add the ear lib contents to the classpath if(trace) log.trace("Checking for ear lib directory: "+libDir); @@ -280,7 +278,6 @@ + " module listed in application.xml is not a recognized deployment, .ear: " + file.getName()); } - } catch (IOException e) { @@ -288,23 +285,12 @@ } } } - - if (appMetaData.getModuleOrderEnum() == ModuleOrder.STRICT) - { - context.setComparatorClassName(RelativeDeploymentContextComparator.class.getName()); - int i = 0; - for (ContextInfo ctx : structureContext.getMetaData().getContexts()) - { - ctx.setRelativeOrder(i++); - } - } } - valid = true; } catch(Exception e) { - throw new RuntimeException("Error determining structure: " + file.getName(), e); + throw new RuntimeException("Error determining structure: " + file.getName(), e); } return valid; @@ -346,7 +332,7 @@ for (VirtualFile vfArchive : archives) { String filename = earRelativePath(earPath, vfArchive.getPathName()); - // Check if the module already exists, i.e. it is declared in jboss-app.xml + // Check if the module already exists, i.e. it is declared in jboss-app.xml ModuleMetaData moduleMetaData = appMetaData.getModule(filename); int type = typeFromSuffix(filename, vfArchive); if (type >= 0 && moduleMetaData == null) @@ -428,7 +414,7 @@ type = J2eeModuleMetaData.EJB; } } - + return type; } @@ -461,12 +447,12 @@ { this.comparatorClassName = comparatorClassName; } - + public void setUseValidation(boolean validateXml) { this.useValidation = validateXml; } - + public boolean isUseValidation() { return useValidation; Property changes on: org/jboss/deployment/JBossMetaDataDeploymentUnitFilter.java ___________________________________________________________________ Added: svn:eol-style + native Index: org/jboss/deployment/JBossEjbParsingDeployer.java =================================================================== --- org/jboss/deployment/JBossEjbParsingDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/JBossEjbParsingDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -23,7 +23,6 @@ import java.net.URL; -import org.jboss.bootstrap.api.as.config.JBossASServerConfig; import org.jboss.deployers.spi.DeploymentException; import org.jboss.deployers.structure.spi.DeploymentUnit; import org.jboss.deployers.vfs.spi.deployer.SchemaResolverDeployer; @@ -32,6 +31,7 @@ import org.jboss.metadata.ejb.spec.EjbJarMetaData; import org.jboss.virtual.VFS; import org.jboss.virtual.VirtualFile; +import org.jboss.bootstrap.spi.as.config.JBossASServerConfig; /** * An ObjectModelFactoryDeployer for translating jboss.xml descriptors into @@ -121,12 +121,12 @@ if(standardJBossXmlPath == null) { // Use default server conf/standardjboss.xml location - final String configUrlProp = JBossASServerConfig.PROP_KEY_JBOSSAS_SERVER_CONF_URL; - String configPath = System.getProperty(configUrlProp); + final String configPropName = JBossASServerConfig.PROP_KEY_JBOSSAS_SERVER_CONF_URL; + String configPath = System.getProperty(configPropName); if(configPath == null ) { if(ignoreMissingStandardJBossXml == false) - throw new DeploymentException("standardjboss.xml not specified and "+configUrlProp+" does not exist"); + throw new DeploymentException("standardjboss.xml not specified and "+configPropName+" does not exist"); return null; } URL configUrl = new URL(configPath); Index: org/jboss/deployment/dependency/ContainerDependencyMetaData.java =================================================================== --- org/jboss/deployment/dependency/ContainerDependencyMetaData.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/dependency/ContainerDependencyMetaData.java (.../trunk/server/src/main/java) (revision 97312) @@ -77,6 +77,7 @@ */ public ContainerDependencyMetaData(String containerName, String componentName, String deploymentPath) { + super(log); this.containerName = containerName; this.componentName = componentName; this.deploymentPath = deploymentPath; Index: org/jboss/deployment/dependency/JndiDependencyMetaData.java =================================================================== --- org/jboss/deployment/dependency/JndiDependencyMetaData.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/dependency/JndiDependencyMetaData.java (.../trunk/server/src/main/java) (revision 97312) @@ -65,6 +65,7 @@ public JndiDependencyMetaData(String jndiName, ClassLoader loader, ControllerState whenRequired) { + super(log); this.jndiName = jndiName; this.loader = loader; this.whenRequired = whenRequired; Index: org/jboss/deployment/OptAnnotationMetaDataDeployer.java =================================================================== --- org/jboss/deployment/OptAnnotationMetaDataDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/OptAnnotationMetaDataDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -51,6 +51,7 @@ /** * A POST_CLASSLOADER deployer which generates metadata from annotations. * Optimized option to its super class. + * TODO: Will need to support per JAR annotations for Servlet 3.0 * * @author Ales.Justin@jboss.org */ Index: org/jboss/deployment/ListDeploymentUnitFilter.java =================================================================== --- org/jboss/deployment/ListDeploymentUnitFilter.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/ListDeploymentUnitFilter.java (.../trunk/server/src/main/java) (revision 97312) @@ -31,7 +31,6 @@ * * @author ales.justin@jboss.org */ -@Deprecated // TODO - remove once we update Deployers to 2.1.x public class ListDeploymentUnitFilter implements VFSDeploymentUnitFilter { private List filters; Property changes on: org/jboss/deployment/ListDeploymentUnitFilter.java ___________________________________________________________________ Added: svn:eol-style + native Index: org/jboss/deployment/DeploymentProvidedDeploymentUnitFilter.java =================================================================== --- org/jboss/deployment/DeploymentProvidedDeploymentUnitFilter.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/DeploymentProvidedDeploymentUnitFilter.java (.../trunk/server/src/main/java) (revision 97312) @@ -37,7 +37,6 @@ * @author Thomas.Diesler@jboss.com * @since 04-Mar-2009 */ -@Deprecated // TODO - remove once we update Deployers to 2.1.x public class DeploymentProvidedDeploymentUnitFilter extends VFS2BaseBridgeDeploymentUnitFilter { @Override Index: org/jboss/deployment/WebAppFragmentParsingDeployer.java =================================================================== --- org/jboss/deployment/WebAppFragmentParsingDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 0) +++ org/jboss/deployment/WebAppFragmentParsingDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -0,0 +1,103 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2006, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt 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.deployment; + +import java.util.Set; + +import org.jboss.deployers.spi.DeploymentException; +import org.jboss.deployers.structure.spi.DeploymentUnit; +import org.jboss.deployers.vfs.spi.deployer.SchemaResolverDeployer; +import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit; +import org.jboss.metadata.web.spec.WebFragmentMetaData; +import org.jboss.virtual.VirtualFile; + +/** + * An ObjectModelFactoryDeployer for translating web-fragment.xml descriptors into + * WebFragmentMetaData instances. + * + * @author Scott.Stark@jboss.org + * @author adrian@jboss.org + * @version $Revision: 82920 $ + */ +public class WebAppFragmentParsingDeployer extends SchemaResolverDeployer +{ + public WebAppFragmentParsingDeployer() + { + super(WebFragmentMetaData.class); + setName("web-fragment.xml"); + setAllowMultipleFiles(true); + } + + /** + * Get the virtual file path for the web-fragment descriptor in the + * DeploymentContext.getMetaDataPath. + * + * @return the current virtual file path for the web-fragment descriptor + */ + public String getWebFragmentXmlPath() + { + return getName(); + } + /** + * Set the virtual file path for the web-fragment descriptor in the + * DeploymentContext.getMetaDataLocation. The standard path is web-fragment.xml + * to be found in the /META-INF/ metdata path in JARs located in /WEB-INF/lib + * in the webapp. + * + * @param WebFragmentMetaData - new virtual file path for the web-fragment descriptor + */ + public void setWebFragmentXmlPath(String WebFragmentMetaData) + { + setName(WebFragmentMetaData); + } + + protected void init(VFSDeploymentUnit unit, WebFragmentMetaData metaData, VirtualFile file) throws Exception + { + unit.addAttachment(file.toURL().toString(), metaData, getOutput()); + } + + protected void createMetaData(DeploymentUnit unit, Set names, String suffix, String key) throws DeploymentException + { + // First see whether it already exists + WebFragmentMetaData result = getMetaData(unit, key); + if (result != null && allowsReparse() == false) + return; + + // Create it + try + { + result = parse(unit, getName(), suffix, result); + } + catch (Exception e) + { + throw DeploymentException.rethrowAsDeploymentException("Error creating managed object for " + unit.getName(), e); + } + + // Doesn't exist + if (result == null) + return; + + // Register it + unit.getTransientManagedObjects().addAttachment(key, result, getOutput()); + } + +} Index: org/jboss/deployment/FileNameVirtualFileFilter.java =================================================================== --- org/jboss/deployment/FileNameVirtualFileFilter.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/deployment/FileNameVirtualFileFilter.java (.../trunk/server/src/main/java) (revision 97312) @@ -33,7 +33,6 @@ * * @author ales.justin@jboss.org */ -@Deprecated // TODO - remove once we update VFS to 2.2.x public class FileNameVirtualFileFilter implements VirtualFileFilter { private Logger log = Logger.getLogger(getClass()); Property changes on: org/jboss/deployment/FileNameVirtualFileFilter.java ___________________________________________________________________ Added: svn:eol-style + native Index: org/jboss/proxy/ejb/StatefulSessionInterceptor.java =================================================================== --- org/jboss/proxy/ejb/StatefulSessionInterceptor.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/proxy/ejb/StatefulSessionInterceptor.java (.../trunk/server/src/main/java) (revision 97312) @@ -118,7 +118,7 @@ return getNext().invoke(invocation); } } - + protected Handle createHandle(int objectName, String jndiName, Invoker invoker, Object id, InvocationContext ctx) { @@ -130,7 +130,7 @@ id, ctx.getValue("InvokerID")); } - + private String toString(InvocationContext ctx) { return ctx.getValue(InvocationKey.JNDI_NAME) + ":" + Index: org/jboss/proxy/ejb/handle/StatefulHandleImpl.java =================================================================== --- org/jboss/proxy/ejb/handle/StatefulHandleImpl.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/proxy/ejb/handle/StatefulHandleImpl.java (.../trunk/server/src/main/java) (revision 97312) @@ -29,19 +29,19 @@ import java.security.AccessControlException; import java.security.AccessController; +import java.security.Principal; import java.security.PrivilegedAction; -import java.security.Principal; import java.util.Hashtable; import javax.ejb.Handle; import javax.ejb.EJBObject; import javax.naming.InitialContext; +import org.jboss.invocation.Invocation; import org.jboss.invocation.InvocationContext; -import org.jboss.invocation.Invoker; -import org.jboss.invocation.Invocation; import org.jboss.invocation.InvocationKey; import org.jboss.invocation.InvocationType; +import org.jboss.invocation.Invoker; import org.jboss.invocation.InvokerInterceptor; import org.jboss.invocation.PayloadKey; import org.jboss.logging.Logger; Property changes on: org/jboss/proxy/ejb/SecurityActions.java ___________________________________________________________________ Added: svn:eol-style + native Property changes on: org/jboss/proxy/ejb/SecurityContextInterceptor.java ___________________________________________________________________ Added: svn:eol-style + native Index: org/jboss/logging/Log4jService.java =================================================================== --- org/jboss/logging/Log4jService.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/logging/Log4jService.java (.../trunk/server/src/main/java) (revision 97312) @@ -1,719 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2008, Red Hat Middleware LLC, 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.logging; - -import java.io.IOException; -import java.io.PrintStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.util.StringTokenizer; -import java.util.Timer; -import java.util.TimerTask; - -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; -import javax.management.Notification; -import javax.management.ObjectName; - -import org.apache.log4j.Level; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.helpers.LogLog; -import org.apache.log4j.xml.DOMConfigurator; -import org.jboss.logging.log4j.JDKLevel; -import org.jboss.logging.util.LoggerStream; -import org.jboss.logging.util.OnlyOnceErrorHandler; -import org.jboss.system.ServiceMBeanSupport; -import org.jboss.util.Strings; -import org.jboss.util.ThrowableHandler; -import org.jboss.util.ThrowableListener; -import org.jboss.util.stream.Streams; - -/** - * Initializes the Log4j logging framework. Supports XML and standard - * configuration file formats. Defaults to using 'log4j.xml' read - * from a system resource. - * - *

Sets up a {@link ThrowableListener} to adapt unhandled - * throwables to a logger. - * - *

Installs {@link LoggerStream} adapters for System.out and - * System.err to catch and redirect calls to Log4j. - * - * @jmx:mbean name="jboss.system:type=Log4jService,service=Logging" - * extends="org.jboss.system.ServiceMBean" - * - * @version $Revision$ - * @author Fulco Muriglio - * @author Scott Stark - * @author David Jencks - * @author Jason Dillon - * @author Dimitris Andreadis - */ -public class Log4jService - extends ServiceMBeanSupport - implements Log4jServiceMBean -{ - /** - * The default url for the configuration file. Reads the value - * from the system property org.jboss.logging.Log4jService.configURL - * or if that is not set defaults to resource:log4j.xml. - */ - public static final String DEFAULT_URL = - System.getProperty(Log4jService.class.getName() + ".configURL", "resource:log4j.xml"); - - /** - * Default flag to enable/disable cacthing System.out. Reads the value - * from the system property org.jboss.logging.Log4jService.catchSystemOut - * or if not set defaults to true. - */ - public static final boolean CATCH_SYSTEM_OUT = - getBoolean(Log4jService.class.getName() + ".catchSystemOut", true); - - /** - * Default flag to enable/disable cacthing System.err. Reads the value - * from the system property org.jboss.logging.Log4jService.catchSystemErr - * or if not set defaults to true. - */ - public static final boolean CATCH_SYSTEM_ERR = - getBoolean(Log4jService.class.getName() + ".catchSystemErr", true); - - /** - * Default value for system property {@link #JBOSS_SERVER_LOG_THRESHOLD_PROPERTY} - * if it is not otherwise configured. - */ - public static final String DEFAULT_JBOSS_SERVER_LOG_THRESHOLD = "DEBUG"; - - /** Helper to get boolean value from system property or use default if not set. */ - private static boolean getBoolean(String name, boolean defaultValue) - { - String value = System.getProperty(name, null); - if (value == null) - return defaultValue; - return new Boolean(value).booleanValue(); - } - - /** The URL to the configuration file. */ - private URL configURL; - - /** The time in seconds between checking for new config. */ - private int refreshPeriod; - - private ThrowableListenerLoggingAdapter throwableAdapter; - - /** The previous value of System.out. */ - private PrintStream out; - - /** The previous value of System.err. */ - private PrintStream err; - - /** - * Flag to enable/disable adapting System.out to the - * STDOUT logger. - */ - private boolean catchSystemOut = CATCH_SYSTEM_OUT; - - /** - * Flag to enable/disable adapting System.out to the - * STDERR logger. - */ - private boolean catchSystemErr = CATCH_SYSTEM_ERR; - - /** The org.apache.log4j.helpers.LogLog.setQuietMode flag setting */ - private boolean log4jQuietMode = true; - - private String defaultJBossServerLogLevel = DEFAULT_JBOSS_SERVER_LOG_THRESHOLD; - - /** The URL watch timer (in daemon mode). */ - private Timer timer; - - /** The specialized timer task to watch our config file. */ - private URLWatchTimerTask timerTask; - - /** - * A flag to enable start/stop to work as expected, - * but still use create to init early. - */ - private boolean initialized; - - /** - * Uses defaults. - * - * @jmx:managed-constructor - * - * @throws MalformedURLException Could not create URL from default (propbably - * a problem with overridden properties). - */ - public Log4jService() throws MalformedURLException - { - this(DEFAULT_URL, 60); - } - - /** - * @jmx:managed-constructor - * - * @param url The configuration URL. - */ - public Log4jService(final URL url) - { - this(url, 60); - } - - /** - * @jmx:managed-constructor - * - * @param url The configuration URL. - */ - public Log4jService(final String url) throws MalformedURLException - { - this(Strings.toURL(url), 60); - } - - /** - * @jmx:managed-constructor - * - * @param url The configuration URL. - * @param refreshPeriod The refreshPeriod in seconds to wait between each check. - */ - public Log4jService(final String url, final int refreshPeriod) - throws MalformedURLException - { - this(Strings.toURL(url), refreshPeriod); - } - - /** - * @jmx:managed-constructor - * - * @param url The configuration URL. - * @param refreshPeriod The refreshPeriod in seconds to wait between each check. - */ - public Log4jService(final URL url, final int refreshPeriod) - { - this.configURL = url; - this.refreshPeriod = refreshPeriod; - } - - /** - * Set the catch System.out flag. - * - * @jmx:managed-attribute - * - * @param flag True to enable, false to disable. - */ - public void setCatchSystemOut(final boolean flag) - { - this.catchSystemOut = flag; - } - - /** - * Get the catch System.out flag. - * - * @jmx:managed-attribute - * - * @return True if enabled, false if disabled. - */ - public boolean getCatchSystemOut() - { - return catchSystemOut; - } - - /** - * Set the catch System.err flag. - * - * @jmx:managed-attribute - * - * @param flag True to enable, false to disable. - */ - public void setCatchSystemErr(final boolean flag) - { - this.catchSystemErr = flag; - } - - /** - * Get the catch System.err flag. - * - * @jmx:managed-attribute - * - * @return True if enabled, false if disabled. - */ - public boolean getCatchSystemErr() - { - return catchSystemErr; - } - - /** - * Get the org.apache.log4j.helpers.LogLog.setQuietMode flag - * - * @jmx:managed-attribute - * - * @return True if enabled, false if disabled. - */ - public boolean getLog4jQuietMode() - { - return log4jQuietMode; - } - /** - * Set the org.apache.log4j.helpers.LogLog.setQuietMode flag - * - * @jmx:managed-attribute - * - * @return True if enabled, false if disabled. - */ - public void setLog4jQuietMode(boolean flag) - { - this.log4jQuietMode = flag; - } - - /** - * Get the refresh period. - * - * @jmx:managed-attribute - */ - public int getRefreshPeriod() - { - return refreshPeriod; - } - - /** - * Set the refresh period. - * - * @jmx:managed-attribute - */ - public void setRefreshPeriod(final int refreshPeriod) - { - this.refreshPeriod = refreshPeriod; - } - - /** - * Get the Log4j configuration URL. - * - * @jmx:managed-attribute - */ - public URL getConfigurationURL() - { - return configURL; - } - - /** - * Set the Log4j configuration URL. - * - * @jmx:managed-attribute - */ - public void setConfigurationURL(final URL url) - { - this.configURL = url; - } - - /** - * {@inheritDoc} - * - * @jmx:managed-attribute - */ - public String getDefaultJBossServerLogThreshold() - { - return defaultJBossServerLogLevel; - } - - /** - * {@inheritDoc} - * - * @jmx:managed-attribute - */ - public void setDefaultJBossServerLogThreshold(String level) - { - this.defaultJBossServerLogLevel = level; - } - - /** - * Sets the level for a logger of the give name. - * - *

Values are trimmed before used. - * - * @jmx:managed-operation - * - * @param name The name of the logger to change level - * @param levelName The name of the level to change the logger to. - */ - public void setLoggerLevel(final String name, final String levelName) - { - org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(name.trim()); - Level level = JDKLevel.toLevel(levelName.trim()); - - logger.setLevel(level); - log.info("Level set to " + level + " for " + name); - } - - /** - * Sets the levels of each logger specified by the given comma - * seperated list of logger names. - * - * @jmx:managed-operation - * - * @see #setLoggerLevel - * - * @param list A comma seperated list of logger names. - * @param levelName The name of the level to change the logger to. - */ - public void setLoggerLevels(final String list, final String levelName) - { - StringTokenizer stok = new StringTokenizer(list, ","); - - while (stok.hasMoreTokens()) { - String name = stok.nextToken(); - setLoggerLevel(name, levelName); - } - } - - /** - * Gets the level of the logger of the give name. - * - * @jmx:managed-operation - * - * @param name The name of the logger to inspect. - */ - public String getLoggerLevel(final String name) - { - org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(name); - Level level = logger.getLevel(); - - if (level != null) - return level.toString(); - - return null; - } - - /** - * Force the logging system to reconfigure. - * - * @jmx:managed-operation - */ - public void reconfigure() throws IOException - { - if (timerTask == null) - throw new IllegalStateException("Service stopped or not started"); - - timerTask.reconfigure(); - } - - /** - * Hack to reconfigure and change the URL. This is needed until we - * have a JMX HTML Adapter that can use PropertyEditor to coerce. - * - * @jmx:managed-operation - * - * @param url The new configuration url - */ - public void reconfigure(final String url) throws IOException, MalformedURLException - { - setConfigurationURL(Strings.toURL(url)); - reconfigure(); - } - - private void installSystemAdapters() - { - org.apache.log4j.Logger logger; - - // Install catchers - if (catchSystemOut) - { - logger = org.apache.log4j.Logger.getLogger("STDOUT"); - out = System.out; - System.setOut(new LoggerStream(logger, Level.INFO, out)); - log.debug("Installed System.out adapter"); - } - - if (catchSystemErr) - { - logger = org.apache.log4j.Logger.getLogger("STDERR"); - err = System.err; - OnlyOnceErrorHandler.setOutput(err); - System.setErr(new LoggerStream(logger, Level.ERROR, err)); - log.debug("Installed System.err adapter"); - } - } - - private void uninstallSystemAdapters() - { - // Remove System adapters - if (out != null) - { - System.out.flush(); - System.setOut(out); - log.debug("Removed System.out adapter"); - out = null; - } - - if (err != null) - { - System.err.flush(); - System.setErr(err); - log.debug("Removed System.err adapter"); - err = null; - } - } - - - /////////////////////////////////////////////////////////////////////////// - // Concrete Service Overrides // - /////////////////////////////////////////////////////////////////////////// - - protected ObjectName getObjectName(MBeanServer server, ObjectName name) - throws MalformedObjectNameException - { - return name == null ? OBJECT_NAME : name; - } - - private void setup() throws Exception - { - if (initialized) return; - - establishDefaultLoggingLevelSystemProperty(); - - timerTask = new URLWatchTimerTask(); - timerTask.run(); - timer = new Timer("Timer-" + getName(), true); - timer.schedule(timerTask, 1000 * refreshPeriod, 1000 * refreshPeriod); - - // Make sure the root Logger has loaded - org.apache.log4j.Logger.getRootLogger(); - - // Install listener for unhandled throwables to turn them into log messages - throwableAdapter = new ThrowableListenerLoggingAdapter(); - ThrowableHandler.addThrowableListener(throwableAdapter); - log.debug("Added ThrowableListener: " + throwableAdapter); - - initialized = true; - } - - private void establishDefaultLoggingLevelSystemProperty() - { - try - { - if (defaultJBossServerLogLevel != null - && SysPropertyActions.getProperty(JBOSS_SERVER_LOG_THRESHOLD_PROPERTY, null) == null) - { - SysPropertyActions.setProperty(JBOSS_SERVER_LOG_THRESHOLD_PROPERTY, - defaultJBossServerLogLevel); - } - } - catch (SecurityException e) - { - log.warn("Cannot configure system property " + JBOSS_SERVER_LOG_THRESHOLD_PROPERTY + - " -- " + e.getLocalizedMessage()); - } - - } - - protected void createService() throws Exception - { - setup(); - } - - protected void startService() throws Exception - { - setup(); - } - - protected void stopService() throws Exception - { - timer.cancel(); - timer = null; - timerTask.cancel(); - timerTask = null; - - // Remove throwable adapter - ThrowableHandler.removeThrowableListener(throwableAdapter); - throwableAdapter = null; - - uninstallSystemAdapters(); - - // allow start to re-initalize - initialized = false; - } - - protected void emitReconfigureNotification() - { - // emit a reconfigure notification with the configURL - Notification n = new Notification(RECONFIGURE_NOTIFICATION_TYPE, - this, getNextNotificationSequenceNumber(), "Log4j subsystem reconfigured"); - n.setUserData(configURL); - - super.sendNotification(n); - } - - /////////////////////////////////////////////////////////////////////////// - // ThrowableListener Adapter // - /////////////////////////////////////////////////////////////////////////// - - /** - * Adapts ThrowableHandler to the Loggger interface. Using nested - * class instead of anoynmous class for better logger naming. - */ - private static class ThrowableListenerLoggingAdapter - implements ThrowableListener - { - private Logger log = Logger.getLogger(ThrowableListenerLoggingAdapter.class); - - public void onThrowable(int type, Throwable t) - { - switch (type) - { - default: - // if type is not valid then make it any error - - case ThrowableHandler.Type.ERROR: - log.error("Unhandled Throwable", t); - break; - - case ThrowableHandler.Type.WARNING: - log.warn("Unhandled Throwable", t); - break; - - case ThrowableHandler.Type.UNKNOWN: - // these could be red-herrings, so log them as trace - log.trace("Ynhandled Throwable; status is unknown", t); - break; - } - } - } - - - /////////////////////////////////////////////////////////////////////////// - // URL Watching Timer Task // - /////////////////////////////////////////////////////////////////////////// - - /** - * A timer task to check when a URL changes (based on - * last modified time) and reconfigure Log4j. - */ - private class URLWatchTimerTask - extends TimerTask - { - private Logger log = Logger.getLogger(URLWatchTimerTask.class); - - private long lastConfigured = -1; - - public void run() - { - log.trace("Checking if configuration changed"); - - boolean trace = log.isTraceEnabled(); - - try - { - URLConnection conn = configURL.openConnection(); - if (trace) - log.trace("connection: " + conn); - - long lastModified = conn.getLastModified(); - if (trace) - { - log.trace("last configured: " + lastConfigured); - log.trace("last modified: " + lastModified); - } - - if (lastConfigured < lastModified) - { - reconfigure(conn); - } - } - catch (Exception e) - { - log.warn("Failed to check URL: " + configURL, e); - } - } - - public void reconfigure() throws IOException - { - URLConnection conn = configURL.openConnection(); - reconfigure(conn); - } - - private void reconfigure(final URLConnection conn) - { - log.info("Configuring from URL: " + configURL); - - boolean xml = false; - boolean trace = log.isTraceEnabled(); - - // check if the url is xml - String contentType = conn.getContentType(); - if (trace) - log.trace("content type: " + contentType); - - if (contentType == null) - { - String filename = configURL.getFile().toLowerCase(); - if (trace) log.trace("filename: " + filename); - - xml = filename.endsWith(".xml"); - } - else - { - xml = contentType.equalsIgnoreCase("text/xml"); - xml |= contentType.equalsIgnoreCase("application/xml"); - } - if (trace) - log.trace("reconfiguring; xml=" + xml); - - // Dump our config if trace is enabled - if (trace) - { - try - { - java.io.InputStream is = conn.getInputStream(); - Streams.copy(is, System.out); - } - catch (Exception e) - { - log.error("Failed to dump config", e); - } - } - - // need to uninstall adapters to avoid problems - uninstallSystemAdapters(); - - if (xml) - { - DOMConfigurator.configure(configURL); - } - else - { - PropertyConfigurator.configure(configURL); - } - - /* Set the LogLog.QuietMode. As of log4j1.2.8 this needs to be set to - avoid deadlock on exception at the appender level. See bug#696819. - */ - LogLog.setQuietMode(log4jQuietMode); - - // but make sure they get reinstalled again - installSystemAdapters(); - - // and then remember when we were last changed - lastConfigured = System.currentTimeMillis(); - - // notify other mbeans that might be interested - emitReconfigureNotification(); - } - } -} Index: org/jboss/logging/Log4jServiceMBean.java =================================================================== --- org/jboss/logging/Log4jServiceMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/logging/Log4jServiceMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -1,134 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2008, Red Hat Middleware LLC, 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.logging; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; - -import javax.management.ObjectName; - -import org.jboss.mx.util.ObjectNameFactory; -import org.jboss.system.ServiceMBean; - -/** - * MBean interface. - */ -public interface Log4jServiceMBean extends ServiceMBean -{ - /** The default object name */ - ObjectName OBJECT_NAME = ObjectNameFactory.create("jboss.system:type=Log4jService,service=Logging"); - - /** Notification type used to indicate a log4j reconfiguration */ - String RECONFIGURE_NOTIFICATION_TYPE = "jboss.logging.log4j.reconfigure"; - - /** Name of system property used to control the logging threshold for the server.log file */ - String JBOSS_SERVER_LOG_THRESHOLD_PROPERTY = "jboss.server.log.threshold"; - - // Attributes ---------------------------------------------------- - - /** - * The catch System.out flag. - * @param flag True to enable, false to disable. - */ - void setCatchSystemOut(boolean flag); - boolean getCatchSystemOut(); - - /** - * The catch System.err flag. - * @param flag True to enable, false to disable. - */ - void setCatchSystemErr(boolean flag); - boolean getCatchSystemErr(); - - /** - * The org.apache.log4j.helpers.LogLog.setQuietMode flag - * @return True if enabled, false if disabled. - */ - void setLog4jQuietMode(boolean flag); - boolean getLog4jQuietMode(); - - /** - * The refresh period. - */ - void setRefreshPeriod(int refreshPeriod); - int getRefreshPeriod(); - - /** - * The Log4j configuration URL. - */ - void setConfigurationURL(URL url); - URL getConfigurationURL(); - - /** - * The value to assign to system property {@link #JBOSS_SERVER_LOG_THRESHOLD_PROPERTY} - * if it is not already set. This system property in turn controls - * the logging threshold for the server.log file. - *

- * If the system property is already set when this service is created, - * this value is ignored. - *

- */ - void setDefaultJBossServerLogThreshold(String level); - String getDefaultJBossServerLogThreshold(); - - // Operations ---------------------------------------------------- - - /** - * Sets the level for a logger of the give name. - *

Values are trimmed before used. - * - * @param name The name of the logger to change level - * @param levelName The name of the level to change the logger to. - */ - void setLoggerLevel(String name, String levelName); - - /** - * Sets the levels of each logger specified by the given comma seperated list of logger names. - * @see #setLoggerLevel - * - * @param list A comma seperated list of logger names. - * @param levelName The name of the level to change the logger to. - */ - void setLoggerLevels(String list, String levelName); - - /** - * Gets the level of the logger of the give name. - * - * @param name The name of the logger to inspect. - */ - String getLoggerLevel(String name); - - /** - * Force the logging system to reconfigure. - */ - void reconfigure() throws IOException; - - /** - * Hack to reconfigure and change the URL. This is needed until - * we have a JMX HTML Adapter that can use PropertyEditor to coerce. - * - * @param url The new configuration url - */ - void reconfigure(String url) throws IOException, MalformedURLException; - -} Index: org/jboss/logging/Log4jSocketServer.java =================================================================== --- org/jboss/logging/Log4jSocketServer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/logging/Log4jSocketServer.java (.../trunk/server/src/main/java) (revision 97312) @@ -219,33 +219,42 @@ public void run() { - while (!shuttingDown) + boolean intr = false; + try { - - if (!enabled) + while (!shuttingDown) { - try + + if (!enabled) { - log.debug("Disabled, waiting for notification"); - synchronized (lock) + try { - lock.wait(); + log.debug("Disabled, waiting for notification"); + synchronized (lock) + { + lock.wait(); + } } + catch (InterruptedException ignore) + { + intr = true; + } } - catch (InterruptedException ignore) + + try { + doRun(); } + catch (Throwable e) + { + log.error("Exception caught from main loop; ignoring", e); + } } - - try - { - doRun(); - } - catch (Throwable e) - { - log.error("Exception caught from main loop; ignoring", e); - } } + finally + { + if (intr) Thread.currentThread().interrupt(); + } } protected void doRun() throws Exception Property changes on: org/jboss/logging/SysPropertyActions.java ___________________________________________________________________ Added: svn:eol-style + native Index: org/jboss/Shutdown.java =================================================================== --- org/jboss/Shutdown.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/Shutdown.java (.../trunk/server/src/main/java) (revision 97312) @@ -21,25 +21,26 @@ */ package org.jboss; -import gnu.getopt.Getopt; -import gnu.getopt.LongOpt; - -import java.io.BufferedReader; -import java.io.InputStreamReader; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; +import java.util.Hashtable; import java.util.ArrayList; -import java.util.Hashtable; - +import java.io.BufferedReader; +import java.io.InputStreamReader; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.naming.Context; import javax.naming.InitialContext; -import org.jboss.bootstrap.api.server.Server; + +import gnu.getopt.Getopt; +import gnu.getopt.LongOpt; + +import org.jboss.bootstrap.spi.as.server.JBossASServer; import org.jboss.naming.HttpNamingContextFactory; +import org.jboss.system.server.ServerImplMBean; import org.jboss.security.SecurityAssociation; import org.jboss.security.SimplePrincipal; import org.jnp.interfaces.NamingContext; @@ -78,6 +79,8 @@ System.out.println(); System.out.println("operations:"); System.out.println(" -S, --shutdown Shutdown the server"); + System.out.println(" -e, --exit= Force the VM to exit with a status code"); + System.out.println(" -H, --halt= Force the VM to halt with a status code"); System.out.println(); } @@ -89,7 +92,7 @@ System.exit(0); } - String sopts = "-:hD:s:n:a:u:p:S"; + String sopts = "-:hD:s:n:a:u:p:Se:H:"; LongOpt[] lopts = { new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'), @@ -97,6 +100,8 @@ new LongOpt("adapter", LongOpt.REQUIRED_ARGUMENT, null, 'a'), new LongOpt("serverName", LongOpt.REQUIRED_ARGUMENT, null, 'n'), new LongOpt("shutdown", LongOpt.NO_ARGUMENT, null, 'S'), + new LongOpt("exit", LongOpt.REQUIRED_ARGUMENT, null, 'e'), + new LongOpt("halt", LongOpt.REQUIRED_ARGUMENT, null, 'H'), new LongOpt("user", LongOpt.REQUIRED_ARGUMENT, null, 'u'), new LongOpt("password", LongOpt.REQUIRED_ARGUMENT, null, 'p'), }; @@ -109,7 +114,10 @@ String adapterName = "jmx/rmi/RMIAdaptor"; String username = null; String password = null; - ObjectName serverJMXName = new ObjectName("jboss.system:type=Server"); + ObjectName serverJMXName = ServerImplMBean.OBJECT_NAME; + boolean exit = false; + boolean halt = false; + int exitcode = -1; while ((code = getopt.getopt()) != -1) { @@ -170,6 +178,14 @@ password = getopt.getOptarg(); SecurityAssociation.setCredential(password); break; + case 'e': + exitcode = Integer.parseInt(getopt.getOptarg()); + exit = true; + break; + case 'H': + exitcode = Integer.parseInt(getopt.getOptarg()); + halt = true; + break; } } @@ -208,11 +224,11 @@ MBeanServerConnection adaptor = (MBeanServerConnection) obj; ServerProxyHandler handler = new ServerProxyHandler(adaptor, serverJMXName); - Class[] ifaces = {Server.class}; + Class[] ifaces = {JBossASServer.class}; ClassLoader tcl = Thread.currentThread().getContextClassLoader(); - Server server = (Server) Proxy.newProxyInstance(tcl, ifaces, handler); + JBossASServer server = (JBossASServer) Proxy.newProxyInstance(tcl, ifaces, handler); server.shutdown(); - + System.out.println("Shutdown message has been posted to the server."); System.out.println("Server shutdown may take a while - check logfiles for completion"); } Index: org/jboss/jmx/connector/invoker/InvokerAdaptorService.java =================================================================== --- org/jboss/jmx/connector/invoker/InvokerAdaptorService.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/jmx/connector/invoker/InvokerAdaptorService.java (.../trunk/server/src/main/java) (revision 97312) @@ -76,7 +76,6 @@ extends ServiceMBeanSupport implements InvokerAdaptorServiceMBean { - private ObjectName mbeanRegistry; /** */ private Map marshalledInvocationMapping = new HashMap(); /** */ @@ -210,16 +209,12 @@ ObjectName objectName = (ObjectName) invocation.getValue("JMX_OBJECT_NAME"); if (objectName != null) { - // Obtain the ClassLoader associated with the MBean deployment newCL = server.getClassLoaderFor(objectName); } if (newCL != null && newCL != oldCL) SecurityActions.setContextClassLoader(newCL); - //JBAS-6449: Cache the incoming security context to be retained on exit - SecurityContext previousSecurityContext = SecurityActions.getSecurityContext(); - try { // Set the method hash to Method mapping @@ -280,11 +275,8 @@ finally { // Restore the input security context - SecurityActions.popSubjectContext(); - if(previousSecurityContext != null) - SecurityActions.setSecurityContext(previousSecurityContext); - else - SecurityActions.clearSecurityContext(); + SecurityActions.popSubjectContext(); + SecurityActions.clearSecurityContext(); // Restore the input class loader if (newCL != null && newCL != oldCL) SecurityActions.setContextClassLoader(oldCL); Index: org/jboss/executor/ControllerExecutorInstaller.java =================================================================== --- org/jboss/executor/ControllerExecutorInstaller.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 0) +++ org/jboss/executor/ControllerExecutorInstaller.java (.../trunk/server/src/main/java) (revision 97312) @@ -0,0 +1,145 @@ +/* +* JBoss, Home of Professional Open Source. +* Copyright 2006, Red Hat Middleware LLC, 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.executor; + +import java.util.concurrent.Executor; +import java.util.concurrent.RejectedExecutionException; + +import org.jboss.dependency.plugins.AbstractController; +import org.jboss.dependency.spi.ControllerContext; + +/** + * Executor implementation which installs itself in the controller to be used for asynchronous deployments. + * It wraps two executors. One used during bootstrap ({@link #setBootstrapExecutor(Executor)}), + * and one which is deployed later ({@link #setMainExecutor(Executor)}). + * + * @author Kabir Khan + * @version $Revision: 1.1 $ + */ +public class ControllerExecutorInstaller implements Executor +{ + ControllerContext context; + + volatile Executor bootstrapExecutor; + + volatile Executor mainExecutor; + + /** + * Contextual injection + * + * @return My ControllerContext + */ + public ControllerContext getContext() + { + return context; + } + + /** + * Contextual injection + * + * @param context My ControllerContext + */ + public void setContext(ControllerContext context) + { + this.context = context; + } + + /** + * Get the bootstrap executor to be used until the main executor is deployed. + * + * @return The bootstrap executor + */ + public Executor getBootstrapExecutor() + { + return bootstrapExecutor; + } + + /** + * Set the bootstrap executor to be used until the main executor is deployed. + * + * @param mainExecutor The bootstrap executor. + */ + public void setBootstrapExecutor(Executor executor) + { + this.bootstrapExecutor = executor; + } + + /** + * Set the main executor once that is deployed + * @param mainExecutor The system executor + */ + public Executor getMainExecutor() + { + return mainExecutor; + } + + /** + * Set the main executor once that is deployed + * @param mainExecutor The system executor + */ + public void setMainExecutor(Executor mainExecutor) + { + this.mainExecutor = mainExecutor; + } + + /** + * Set myself as the executor in the controller + */ + public void start() + { + ((AbstractController)context.getController()).setExecutor(this); + } + + /** + * Unset myself as the executor in the controller + */ + public void stop() + { + ((AbstractController)context.getController()).setExecutor(null); + } + + /** + * Execute the command, using the mainExecutor if available. If there + * is no mainExecutor, use the bootstrapExecutor. + * @param command the command to execute + * @throws java.util.concurrent.RejectedExecutionException if there is no mainExecutor or bootstrapExecutor + * @see Executor#execute(Runnable) + */ + public void execute(Runnable command) + { + Executor exec = mainExecutor; + if (exec != null) + { + exec.execute(command); + return; + } + + exec = bootstrapExecutor; + if (exec != null) + { + exec.execute(command); + return; + } + + throw new RejectedExecutionException("No executor available in " + this.getClass().getName()); + } +} Index: org/jboss/executor/ThreadPoolExecutorFactory.java =================================================================== --- org/jboss/executor/ThreadPoolExecutorFactory.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 0) +++ org/jboss/executor/ThreadPoolExecutorFactory.java (.../trunk/server/src/main/java) (revision 97312) @@ -0,0 +1,301 @@ +/* +* JBoss, Home of Professional Open Source. +* Copyright 2006, Red Hat Middleware LLC, 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.executor; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Creates a ThreadPoolExecutor that can be configured as an MC bean. + * + * @author Kabir Khan + * @version $Revision: 1.1 $ + */ +public class ThreadPoolExecutorFactory +{ + final static ThreadFactory DEFAULT_THREAD_FACTORY = Executors.defaultThreadFactory(); + + final static RejectedExecutionHandler DEFAULT_REJECTED_EXECUTION_HANDLER = new ThreadPoolExecutor.AbortPolicy(); + + final static int DEFAULT_KEEP_ALIVE_TIME = 30; + + final static TimeUnit DEFAULT_KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS; + + float corePoolSizeBase; + + float corePoolSizePerCpu; + + float maxPoolSizeBase; + + float maxPoolSizePerCpu; + + int keepAliveTime; + + TimeUnit keepAliveTimeUnit = TimeUnit.SECONDS; + + BlockingQueue workQueue; + + ThreadFactory threadFactory; + + RejectedExecutionHandler rejectedExecutionHandler; + + Executor executor; + + /** + * Gets the keep alive time to be used in the created pool. + * @return the keep alive time + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public int getKeepAliveTime() + { + return keepAliveTime; + } + + /** + * Sets the keep alive time to be used in the created pool. + * @param keepAliveTime The time + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public void setKeepAliveTime(int keepAliveTime) + { + this.keepAliveTime = keepAliveTime; + } + + /** + * Gets the time unit for keep alive time to be used in the created pool. + * @return The keep alive time unit + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public TimeUnit getKeepAliveTimeUnit() + { + return keepAliveTimeUnit; + } + + /** + * Sets the time unit for keep alive time to be used in the created pool. The default is TimeUnit.SECONDS + * @param keepAliveTimeUnit The time unit + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public void setKeepAliveTimeUnit(TimeUnit keepAliveTimeUnit) + { + this.keepAliveTimeUnit = keepAliveTimeUnit; + } + + /** + * Gets work queue to be used in the created pool. + * @return The work queue + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public BlockingQueue getWorkQueue() + { + return workQueue; + } + + /** + * Sets the work queue to be used in the created pool. By default it will create an instance of {@link LinkedBlockingQueue} + * @param workQueue The work queue + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public void setWorkQueue(BlockingQueue workQueue) + { + this.workQueue = workQueue; + } + + /** + * Gets the thread factory to be used in the created pool. + * @return The thread factory + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public ThreadFactory getThreadFactory() + { + return threadFactory; + } + + /** + * Sets the thread factory to be used in the created pool. By default it will use {@link Executors#defaultThreadFactory()} + * @return The thread factory + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public void setThreadFactory(ThreadFactory threadFactory) + { + this.threadFactory = threadFactory; + } + + /** + * Gets the base value for the calculation of the core pool size to be used as the corePoolSize argument in the created pool. + * @return the base core pool size + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public float getCorePoolSizeBase() + { + return corePoolSizeBase; + } + + /** + * Sets the base value for the calculation of the core pool size to be used as the corePoolSize argument in the created pool. + * The calculation is corePoolSizeBase + (corePoolSizePerCpu * Runtime.availableProcessors()) + * @param the base core pool size + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public void setCorePoolSizeBase(float corePoolSizeBase) + { + this.corePoolSizeBase = corePoolSizeBase; + } + + /** + * Gets the per cpu value for the calculation of the core pool size to be used as the corePoolSize argument in the created pool. + * @return the per cpu core pool size + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public float getCorePoolSizePerCpu() + { + return corePoolSizePerCpu; + } + + /** + * Sets the per cpu value for the calculation of the core pool size to be used as the corePoolSize argument in the created pool. + * The calculation is corePoolSizeBase + (corePoolSizePerCpu * Runtime.availableProcessors()) + * @param the per cpu core pool size + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public void setCorePoolSizePerCpu(float corePoolSizePerCpu) + { + this.corePoolSizePerCpu = corePoolSizePerCpu; + } + + /** + * Gets the base value for the calculation of the max pool size to be used as the maxPoolSize in the created pool. + * @return the base max pool size + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public float getMaxPoolSizeBase() + { + return maxPoolSizeBase; + } + + /** + * Sets the base value for the calculation of the max pool size to be used as the maxPoolSize argument in the created pool. + * The calculation is maxPoolSizeBase + (maxPoolSizePerCpu * Runtime.availableProcessors()) + * @param the base max pool size + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public void setMaxPoolSizeBase(float maxPoolSizeBase) + { + this.maxPoolSizeBase = maxPoolSizeBase; + } + + /** + * Gets the per cpu value for the calculation of the max pool size to be used as the maxPoolSize argument in the created pool. + * @return the per cpu max pool size + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public float getMaxPoolSizePerCpu() + { + return maxPoolSizePerCpu; + } + + /** + * Sets the per cpu value for the calculation of the max pool size to be used as the maxPoolSize argument in the created pool. + * The calculation is maxPoolSizeBase + (maxPoolSizePerCpu * Runtime.availableProcessors()) + * @param the per cpu max pool size + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public void setMaxPoolSizePerCpu(float maxPoolSizePerCpu) + { + this.maxPoolSizePerCpu = maxPoolSizePerCpu; + } + + /** + * Gets the rejected execution handler to be used in the created pool. + * @return The rejected execution handler + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public RejectedExecutionHandler getRejectedExecutionHandler() + { + return rejectedExecutionHandler; + } + + /** + * Sets the rejected execution handler to be used in the created pool. The default is to create an instance of {@link ThreadPoolExecutor.AbortPolicy} + * @param rejectedExecutionHandler The rejected execution handler + * @See {@link ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, TimeUnit, BlockingQueue, ThreadFactory, RejectedExecutionHandler)} + */ + public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) + { + this.rejectedExecutionHandler = rejectedExecutionHandler; + } + + /** + * Creates and returns an instance of the ThreadPoolExecutor configured by this bean. Subsequent invocations + * will return the same instance. + * @return The created executor + */ + public Executor getExecutor() + { + synchronized(this) + { + if (executor == null) + { + executor = createExecutor(); + } + } + return executor; + } + + private ThreadPoolExecutor createExecutor() + { + int coreSize = Math.max(calcPoolSize(corePoolSizeBase, corePoolSizePerCpu), 0); + if (coreSize == 0) + { + throw new IllegalStateException("Core size was calculated to 0"); + } + int maxSize = Math.max(calcPoolSize(maxPoolSizeBase, maxPoolSizePerCpu), 0); + if (maxSize == 0) + { + throw new IllegalStateException("Max size was calculated to 0"); + } + BlockingQueue queue = workQueue == null ? new LinkedBlockingQueue() : workQueue; + ThreadFactory factory = threadFactory == null ? DEFAULT_THREAD_FACTORY : threadFactory; + RejectedExecutionHandler handler = rejectedExecutionHandler == null ? DEFAULT_REJECTED_EXECUTION_HANDLER : rejectedExecutionHandler; + + return new ThreadPoolExecutor(coreSize, maxSize, keepAliveTime, keepAliveTimeUnit, queue, factory, handler); + } + + private static int calcPoolSize(float count, float perCpu) + { + if (Float.isNaN(count) || Float.isInfinite(count) || count < 0.0f) + { + count = 0.0f; + } + if (Float.isNaN(perCpu) || Float.isInfinite(perCpu) || perCpu < 0.0f) + { + perCpu = 0.0f; + } + return Math.round(count + ((float) Runtime.getRuntime().availableProcessors()) * perCpu); + } +} Index: org/jboss/ejb/StatefulSessionContainerMBean.java =================================================================== --- org/jboss/ejb/StatefulSessionContainerMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/StatefulSessionContainerMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -1,34 +0,0 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2008, Red Hat Middleware LLC, 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.ejb; - -public interface StatefulSessionContainerMBean extends ContainerMBean -{ - - /** - * Get the number of instances in this container that are currently passivated. - * - * @return the number of passivated instances - */ - public long getPassivatedCount(); - -} Index: org/jboss/ejb/EjbModule.java =================================================================== --- org/jboss/ejb/EjbModule.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/EjbModule.java (.../trunk/server/src/main/java) (revision 97312) @@ -49,7 +49,6 @@ import org.jboss.deployers.structure.spi.DeploymentUnit; import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit; import org.jboss.deployment.DeploymentException; -import org.jboss.deployment.DeploymentInfo; import org.jboss.ejb.plugins.SecurityProxyInterceptor; import org.jboss.ejb.plugins.StatefulSessionInstancePool; import org.jboss.ejb.txtimer.EJBTimerService; @@ -216,15 +215,6 @@ unit.addAttachment(ApplicationMetaData.class, metaData); } - /** - * @deprecated DeploymentInfo is obsolete - */ - @Deprecated - public EjbModule(final DeploymentInfo di, TransactionManager tm, ObjectName webServiceName) - { - this.name = "deprecated"; - } - public void setTransactionManagerFactory(TransactionManagerFactory tm) { this.tmFactory = tm; @@ -622,7 +612,6 @@ con.setWebClassLoader(null); con.setClassLoader(null); con.setEjbModule(null); - con.setDeploymentInfo(null); con.setTransactionManager(null); con.setSecurityManager(null); con.setRealmMapping(null); Index: org/jboss/ejb/EntityContainerMBean.java =================================================================== --- org/jboss/ejb/EntityContainerMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/EntityContainerMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -26,13 +26,17 @@ * @see Container * @see EntityEnterpriseContext */ -public interface EntityContainerMBean extends org.jboss.ejb.ContainerMBean { +public interface EntityContainerMBean extends ContainerMBean +{ + /** + * Get the cache size + * + * @return the cache size + */ + long getCacheSize(); - long getCacheSize() ; - /** * Flush the cache */ - void flushCache() ; - + void flushCache(); } Index: org/jboss/ejb/ContainerMBean.java =================================================================== --- org/jboss/ejb/ContainerMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/ContainerMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -21,25 +21,24 @@ */ package org.jboss.ejb; -import java.util.Map; +import javax.ejb.TimerService; +import javax.naming.Context; +import javax.naming.NamingException; +import org.jboss.invocation.Invocation; + /** * MBean interface. - * @see EJBDeployer */ -public interface ContainerMBean extends org.jboss.system.ServiceMBean { +public interface ContainerMBean extends org.jboss.system.ServiceMBean +{ /** - * Gets the application deployment unit for this container. All the bean containers within the same application unit share the same instance. + * @return Gets the application deployment unit for this container. All the bean containers within the same application unit share the same instance. */ - org.jboss.ejb.EjbModule getEjbModule() ; + EjbModule getEjbModule(); /** - * Gets the deployment name of the deployment unit that contains this container. - */ - String getDeploymentName(); - - /** * Gets the type of bean (Session, Entity, etc) * * @return type of bean @@ -47,59 +46,32 @@ String getBeanTypeName(); /** - * Gets the number of create invocations that have been made + * @return Gets the number of create invocations that have been made */ - long getCreateCount() ; + long getCreateCount(); /** - * Gets the number of remove invocations that have been made + * @return Gets the number of remove invocations that have been made */ - long getRemoveCount() ; + long getRemoveCount(); /** - * Gets the invocation statistics collection + * @return Gets the invocation statistics collection */ - org.jboss.invocation.InvocationStatistics getInvokeStats() ; + org.jboss.invocation.InvocationStatistics getInvokeStats(); - /** - * Converts the method invocation stats into a detyped nested map structure. - * The format is: - * - * {methodName => {statisticTypeName => longValue}} - * - * @return A map indexed by method name with map values indexed by statistic type - */ - Map> getDetypedInvocationStatistics(); - - /** - * Get current pool size of the pool associated with this container, - * also known as the method ready count - * - * @throws UnsupportedOperationException if the container type does not support an instance pool - */ - int getCurrentPoolSize(); - - /** - * Gets the max pool size of the pool associated with this container - * - * @throws UnsupportedOperationException if the container type does not support an instance pool - */ - int getMaxPoolSize(); - - /** - * Resets the current invocation stats - */ - void resetInvocationStats(); - /** * Get the components environment context - * @return Environment Context */ - javax.naming.Context getEnvContext() throws javax.naming.NamingException; + * @return Environment Context + * @throws NamingException for any error + */ + Context getEnvContext() throws NamingException; /** * Returns the metadata of this container. - * @return metaData; */ - org.jboss.metadata.BeanMetaData getBeanMetaData() ; + * @return metaData; + */ + org.jboss.metadata.BeanMetaData getBeanMetaData(); /** * Creates the single Timer Servic for this container if not already created @@ -108,20 +80,19 @@ * @throws IllegalStateException If the type of EJB is not allowed to use the timer service * @see javax.ejb.EJBContext#getTimerService */ - javax.ejb.TimerService getTimerService(java.lang.Object pKey) throws java.lang.IllegalStateException; + TimerService getTimerService(Object pKey) throws IllegalStateException; /** * Removes Timer Servic for this container * @param pKey Bean id * @throws IllegalStateException If the type of EJB is not allowed to use the timer service */ - void removeTimerService(java.lang.Object pKey) throws java.lang.IllegalStateException; + void removeTimerService(Object pKey) throws IllegalStateException; /** * The detached invoker operation. * @param mi - the method invocation context * @return the value of the ejb invocation * @throws Exception on error */ - java.lang.Object invoke(org.jboss.invocation.Invocation mi) throws java.lang.Exception; - + Object invoke(Invocation mi) throws Exception; } Index: org/jboss/ejb/deployers/EjbDeployer.java =================================================================== --- org/jboss/ejb/deployers/EjbDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/deployers/EjbDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -65,7 +65,7 @@ /** * A real deployer that translates JBossMetaData into ServiceMetaData for * the ejb module service mbeans. - * + * * @author Scott.Stark@jboss.org * @author adrian@jboss.org * @version $Revision$ @@ -81,13 +81,18 @@ private String ccmServiceName; /** The ejb timer service */ private String timerServiceName; - + private boolean callByValue; private String unauthenticatedIdentity = null; private String securityManagementName; private String securityContextClassName; private String defaultSecurityDomain; + + /** + * Inject Policy Registration Bean Name + */ + private String policyRegistrationName; /** Verify EJB-jar contents on deployments */ private boolean verifyDeployments; @@ -100,11 +105,6 @@ private boolean strictVerifier; /** - * Inject Policy Registration Bean Name - */ - private String policyRegistrationName; - - /** * Create a new EjbDeployer. */ public EjbDeployer() @@ -169,7 +169,7 @@ /** * Obtain an unauthenticated identity - * + * * @return the unauthenticated identity */ public String getUnauthenticatedIdentity() @@ -185,7 +185,7 @@ { this.unauthenticatedIdentity = unauthenticatedIdentity; } - + public void setDefaultSecurityDomain(String defaultSecurityDomain) { this.defaultSecurityDomain = defaultSecurityDomain; @@ -195,11 +195,11 @@ { this.securityManagementName = sm; } - + public void setSecurityContextClassName(String securityContextClassName) { this.securityContextClassName = securityContextClassName; - } + } /** * Get the PolicyRegistration Name @@ -322,7 +322,7 @@ attr.setName("PolicyRegistration"); ServiceInjectionValueMetaData prInjectionValue = new ServiceInjectionValueMetaData(policyRegistrationName); attr.setValue(prInjectionValue); - attrs.add(attr); + attrs.add(attr); // Add injection of the WebServiceName String wsName = getWebServiceName(); if (wsName != null) @@ -343,8 +343,8 @@ tms.setValue(tmsDepends); attrs.add(tms); - ejbModule.setAttributes(attrs); - + ejbModule.setAttributes(attrs); + List dependencies = new ArrayList(); // CCM for CachedConnectionInterceptor dependency // TODO: this should be injected directly to the interceptor @@ -437,7 +437,7 @@ ObjectName n = new ObjectName(depend); ServiceDependencyMetaData sdmd = new ServiceDependencyMetaData(); sdmd.setIDependOn(n.toString()); - dependencies.add(sdmd); + dependencies.add(sdmd); } } catch(MalformedObjectNameException e) @@ -459,7 +459,7 @@ //Pass the unauthenticated identity if(this.unauthenticatedIdentity != null) unit.addAttachment("EJB.unauthenticatedIdentity", this.unauthenticatedIdentity, String.class); - //Pass the SecurityContextClassName + //Pass the SecurityContextClassName if(this.securityContextClassName != null) unit.addAttachment("EJB.securityContextClassName", securityContextClassName, String.class); //Pass the Default SecurityDomain @@ -469,7 +469,7 @@ @Override public void undeploy(VFSDeploymentUnit unit, JBossMetaData deployment) - { + { } /** @@ -480,7 +480,7 @@ * @param unit the deployment unit * @param metaData - the ejb jar metaData * @return "jboss.j2ee:service=EjbModule,module="+unit.getSimpleName() - * @throws MalformedObjectNameException + * @throws MalformedObjectNameException */ protected ObjectName getObjectName(VFSDeploymentUnit unit, JBossMetaData metaData) throws MalformedObjectNameException @@ -500,41 +500,41 @@ } unitShortName = unitShortName.substring(unitShortName.lastIndexOf("/") + 1); - // + // unitShortName = ObjectName.quote(unitShortName); - name = EjbModule.BASE_EJB_MODULE_NAME + ",module=" + unitShortName + ",uid=" + System.identityHashCode(metaData); + name = EjbModule.BASE_EJB_MODULE_NAME + ",module=" + unitShortName; } return new ObjectName(name); } - public boolean getStrictVerifier() - { - return strictVerifier; - } + public boolean getStrictVerifier() + { + return strictVerifier; + } - public boolean getVerifierVerbose() - { - return verifierVerbose; - } + public boolean getVerifierVerbose() + { + return verifierVerbose; + } - public boolean getVerifyDeployments() - { - return verifyDeployments; - } + public boolean getVerifyDeployments() + { + return verifyDeployments; + } - public void setStrictVerifier(boolean strictVerifier) - { - this.strictVerifier = strictVerifier; - } + public void setStrictVerifier(boolean strictVerifier) + { + this.strictVerifier = strictVerifier; + } - public void setVerifierVerbose(boolean verbose) - { - this.verifierVerbose = verbose; - } + public void setVerifierVerbose(boolean verbose) + { + this.verifierVerbose = verbose; + } - public void setVerifyDeployments(boolean verify) - { - this.verifyDeployments = verify; - } + public void setVerifyDeployments(boolean verify) + { + this.verifyDeployments = verify; + } } Index: org/jboss/ejb/plugins/SingletonStatelessSessionInstancePool.java =================================================================== --- org/jboss/ejb/plugins/SingletonStatelessSessionInstancePool.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/plugins/SingletonStatelessSessionInstancePool.java (.../trunk/server/src/main/java) (revision 97312) @@ -61,33 +61,41 @@ public synchronized EnterpriseContext get() throws Exception { - // Wait while someone else is using it - while(inUse && isSynchronized) + boolean intr = false; + try { - try { this.wait(); } catch (InterruptedException e) {} - } + // Wait while someone else is using it + while(inUse && isSynchronized) + { + try { this.wait(); } catch (InterruptedException e) { intr = true; } + } - // Create if not already created (or it has been discarded) - if (ctx == null) - { - try + // Create if not already created (or it has been discarded) + if (ctx == null) { - ctx = create(getContainer().createBeanClassInstance()); - } catch (InstantiationException e) + try + { + ctx = create(getContainer().createBeanClassInstance()); + } catch (InstantiationException e) + { + throw new EJBException("Could not instantiate bean", e); + } catch (IllegalAccessException e) + { + throw new EJBException("Could not instantiate bean", e); + } + } + else { - throw new EJBException("Could not instantiate bean", e); - } catch (IllegalAccessException e) - { - throw new EJBException("Could not instantiate bean", e); } + + // Lock and return instance + inUse = true; + return ctx; } - else + finally { + if (intr) Thread.currentThread().interrupt(); } - - // Lock and return instance - inUse = true; - return ctx; } /** Index: org/jboss/ejb/plugins/cmp/jdbc2/schema/Schema.java =================================================================== --- org/jboss/ejb/plugins/cmp/jdbc2/schema/Schema.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/plugins/cmp/jdbc2/schema/Schema.java (.../trunk/server/src/main/java) (revision 97312) @@ -28,13 +28,12 @@ import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCEntityBridge2; import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMRFieldBridge2; import org.jboss.deployment.DeploymentException; -import org.jboss.tm.TransactionLocal; import javax.ejb.EJBException; -import javax.transaction.Synchronization; import javax.transaction.RollbackException; -import javax.transaction.SystemException; +import javax.transaction.Synchronization; import javax.transaction.Status; +import javax.transaction.SystemException; import javax.transaction.Transaction; import java.sql.SQLException; @@ -53,7 +52,7 @@ public Schema(String ejbModuleName) { - this.viewsTxLocalKey = ejbModuleName + ".schema.views"; + this.viewsTxLocalKey = ejbModuleName + ".schema.views"; } public EntityTable createEntityTable(JDBCEntityMetaData metadata, JDBCEntityBridge2 entity) Index: org/jboss/ejb/plugins/cmp/jdbc2/schema/TableCache.java =================================================================== --- org/jboss/ejb/plugins/cmp/jdbc2/schema/TableCache.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/plugins/cmp/jdbc2/schema/TableCache.java (.../trunk/server/src/main/java) (revision 97312) @@ -127,23 +127,32 @@ public synchronized void lock() { - if(locked) + boolean intr = false; + try { - long start = System.currentTimeMillis(); - while(locked) + if(locked) { - try + long start = System.currentTimeMillis(); + while(locked) { - wait(); + try + { + wait(); + } + catch(InterruptedException e) + { + intr = true; + } } - catch(InterruptedException e) - { - } + + listener.contention(partitionIndex, System.currentTimeMillis() - start); } - - listener.contention(partitionIndex, System.currentTimeMillis() - start); + locked = true; } - locked = true; + finally + { + if (intr) Thread.currentThread().interrupt(); + } } public void lock(Object key) Index: org/jboss/ejb/plugins/cmp/jdbc2/schema/PartitionedTableCache.java =================================================================== --- org/jboss/ejb/plugins/cmp/jdbc2/schema/PartitionedTableCache.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/plugins/cmp/jdbc2/schema/PartitionedTableCache.java (.../trunk/server/src/main/java) (revision 97312) @@ -276,22 +276,31 @@ public void run() { - while(run) + boolean intr = false; + try { - long lastUpdated = System.currentTimeMillis() - maxAgeMs; - for(int i = 0; i < partitions.length; ++i) + while(run) { - partitions[i].ageOut(lastUpdated); - } + long lastUpdated = System.currentTimeMillis() - maxAgeMs; + for(int i = 0; i < partitions.length; ++i) + { + partitions[i].ageOut(lastUpdated); + } - try - { - Thread.sleep(periodMs); + try + { + Thread.sleep(periodMs); + } + catch(InterruptedException e) + { + intr = true; + } } - catch(InterruptedException e) - { - } } + finally + { + if (intr) Thread.currentThread().interrupt(); + } } } } Index: org/jboss/ejb/plugins/cmp/ejbql/JBossQLParser.jjt =================================================================== --- org/jboss/ejb/plugins/cmp/ejbql/JBossQLParser.jjt (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/plugins/cmp/ejbql/JBossQLParser.jjt (.../trunk/server/src/main/java) (revision 97312) @@ -1,1331 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2005, JBoss Inc., and individual contributors as indicated - * by the @authors tag. See the copyright.txt 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. - */ - -options { - BUILD_NODE_FILES=false; - MULTI=true; - VISITOR=true; - - JAVA_UNICODE_ESCAPE = true; - STATIC = false; - - CHOICE_AMBIGUITY_CHECK = 5; - OTHER_AMBIGUITY_CHECK = 5; - - LOOKAHEAD = 1; - DEBUG_PARSER = false; - DEBUG_LOOKAHEAD = false; - DEBUG_TOKEN_MANAGER = false; - ERROR_REPORTING = true; - UNICODE_INPUT = false; - IGNORE_CASE = false; - USER_TOKEN_MANAGER = false; - USER_CHAR_STREAM = false; - BUILD_PARSER = true; - BUILD_TOKEN_MANAGER = true; - SANITY_CHECK = true; - FORCE_LA_CHECK = false; -} - -PARSER_BEGIN(JBossQLParser) -package org.jboss.ejb.plugins.cmp.ejbql; - -import java.io.CharArrayReader; -import java.util.ArrayList; -import java.util.List; -import org.jboss.ejb.plugins.cmp.bridge.EntityBridge; -import org.jboss.ejb.plugins.cmp.bridge.CMPFieldBridge; -import org.jboss.ejb.plugins.cmp.bridge.CMRFieldBridge; -import org.jboss.ejb.plugins.cmp.bridge.FieldBridge; - -/** - * This class parses JBossQL into an abstract syntax tree. - * - * @author Dain Sundstrom - * @author Alex Loubyansky - * @version $Revision$ - */ -public class JBossQLParser { - private Catalog catalog; - private Class[] argumentTypes; - private IdentifierManager idManager; - private boolean selectDistinct; - private String selectPath; - - public ASTEJBQL parse(Catalog catalog, Class[] argumentTypes, String ejbql) - throws ParseException { - - this.catalog = catalog; - token_source.catalog = catalog; - this.argumentTypes = argumentTypes; - token_source.argumentTypes = argumentTypes; - idManager = new IdentifierManager(catalog); - token_source.idManager = idManager; - - String lowerCase = ejbql.toLowerCase(); - int fromBeginIndex = indexOf(lowerCase, "from"); - if(fromBeginIndex < 0) { - throw new ParseException("FROM not found"); - } - - int fromEndIndex = indexOf(lowerCase, "where"); - ///////////////////// CHANGED ////////////////////////////// - if(fromEndIndex < 0) { - fromEndIndex = indexOfOrderBy(lowerCase); - } - if(fromEndIndex < 0) { - fromEndIndex = indexOf(lowerCase, "offset"); - } - if(fromEndIndex < 0) { - fromEndIndex = indexOf(lowerCase, "limit"); - } - if(fromEndIndex < 0) { - fromEndIndex = ejbql.length(); - } - //////////////////////////////////////////////////////////// - - // just the from clause - char[] from = ejbql.toCharArray(); - clear(from, 0, fromBeginIndex); - clear(from, fromEndIndex, from.length); - - // everything except for the from clause - char[] sansFrom = ejbql.toCharArray(); - clear(sansFrom, fromBeginIndex + 4, fromEndIndex); - - // From clause - ReInit(new CharArrayReader(from)); - ASTFrom fromNode = ParseFromClause(); - - // Everything else - ReInit(new CharArrayReader(sansFrom)); - ASTEJBQL ejbqlNode = EJBQL(); - - // replace the dummy from clause in the EJBQL - // node with the real from node - ejbqlNode.jjtAddChild(fromNode, 1); - - return ejbqlNode; - } - - /** - * Returns the first index of the word (surrounded with whitespaces) in the string - * or -1 if the word was not found. - */ - private static final int indexOf(String ql, String word) - { - return indexOf(ql, word, 0); - } - - /** - * Returns the first index of the word (surrounded with whitespaces) in the string - * starting with startInd position or -1 if the word was not found. - */ - private static final int indexOf(String ql, String word, int startInd) - { - int i = ql.indexOf(word, startInd); - if(i < 0) - { - return -1; - } - - int qlLength = ql.length(); - int wordLength = word.length(); - while(i >= 0) - { - int endInd = i + wordLength; - if((i == 0 || Character.isWhitespace(ql.charAt(i - 1))) && - (endInd == qlLength || endInd < qlLength && Character.isWhitespace(ql.charAt(endInd)))) - { - break; - } - - i = ql.indexOf(word, i + 1); - } - return i; - } - - private static final int indexOfOrderBy(String ql) - { - int orderInd = indexOf(ql, "order", 0); - int byInd = -1; - while(orderInd > 0) - { - if(byInd < orderInd) - { - byInd = indexOf(ql, "by", orderInd + 5); - } - - if(byInd > 0) - { - int i = byInd - 1; - while(i >= orderInd + 5 && Character.isWhitespace(ql.charAt(i--))); - if(i == orderInd + 4) - { - break; - } - else - { - orderInd = indexOf(ql, "order", orderInd + 5); - } - } - else - { - orderInd = -1; - } - } - return orderInd; - } - - private final void clear(char[] c, int beginIndex, int endIndex) { - for(int i=beginIndex; i < endIndex; i++) { - if(c[i]!='\r' && c[i]!='\n' && c[i]!='\t') { - c[i] = ' '; - } - } - } - - private final void initPathNode(ASTPath pathNode, String path, int type) { - pathNode.pathList = idManager.getPathList(path); - pathNode.fieldList = idManager.getFieldList(path); - pathNode.type = type; - } - - private final void initParameterNode( - ASTParameter parameterNode, - String number, - int type) { - - parameterNode.number = Integer.parseInt(number); - parameterNode.type = type; - } -} - -PARSER_END(JBossQLParser) - -////////////////////// New or changed elements ///////////////////////////// - -ASTEJBQL EJBQL() #EJBQL : -{} -{ - SelectClause() FromKeyword() [WhereClause()] [OrderByClause()] [LimitClause()] - { return jjtThis; } -} - -ASTOrderBy OrderByClause() #OrderBy : -{} -{ - OrderByPathExpression() ( OrderByPathExpression() ) * - { return jjtThis; } -} - -void OrderByPathExpression() #OrderByPath : -{} -{ - ( NumericValuedPath() | StringValuedPath() | DatetimeValuedPath() | ValueClassExpression()) - [ | { jjtThis.ascending=false; } ] -} - -void LimitClause() #LimitOffset : -{} -{ - ArithmeticValue() { jjtThis.hasOffset = true; } [ ArithmeticValue() { jjtThis.hasLimit = true; }] - | ArithmeticValue() { jjtThis.hasLimit = true; } -} - -//////////////////////////////////////////////////////////////////////////// - -void FromKeyword() #From : -{} -{ - -} - -ASTFrom ParseFromClause() #void : -{ ASTFrom node; } -{ - node = FromClause() - { return node; } -} - -ASTFrom FromClause() #From : -{} -{ - ( - IdentificationVariableDeclaration() - ( IdentificationVariableDeclaration() )* - ) { return jjtThis; } -} - -void IdentificationVariableDeclaration() #void : -{} -{ - (CollectionMemberDeclaration() | RangeVariableDeclaration()) -} - -void CollectionMemberDeclaration() : -{ - Token path; - Token id; -} -{ - ( path=CollectionValuedPath() - [] id=Identifier() ) - { idManager.declareCollectionMember(id.image, path.image); } -} - -void RangeVariableDeclaration() : -{ - Token schema; - Token id; -} -{ - ( schema=AbstractSchema() [] id=Identifier() ) - { idManager.declareRangeVariable(id.image, schema.image); } -} - -ASTSelect SelectClause() #Select : -{} -{ - ( - [ { jjtThis.distinct=true; }] - ( - IdentificationVariable() | - SelectExpression() - ) - ) { return jjtThis; } -} - -void SelectExpression() #void : -{} -{ - SingleValuedPath() | AggregateSelectExpression() -} - -ASTWhere WhereClause() #Where : -{} -{ - WhereExpression() - { return jjtThis; } -} - -// -// ASTWhereExpression and ASTWhereConditionalTerm mimic -// ConditionalExpression and ConditionalTerm. -// They are added to support joins per WhereConditionalTerm. -// -void WhereExpression() #void : -{} -{ - ( - WhereConditionalTerm() ( WhereConditionalTerm() )* - ) #Or(>1) -} - -ASTWhereConditionalTerm WhereConditionalTerm() #WhereConditionalTerm : -{} -{ - ( - ConditionalFactor() ( ConditionalFactor() )* - ) #And(>1) - {return jjtThis;} -} - -void ConditionalExpression() #void : -{} -{ - ( - ConditionalTerm() ( ConditionalTerm() )* - ) #Or(>1) -} - -void ConditionalTerm() #void : -{} -{ - ( - ConditionalFactor() ( ConditionalFactor() )* - ) #And(>1) -} - -void ConditionalFactor() #void : -{ boolean not = false; } -{ - ( - [{ not=true; }] ConditionalTest() - ) #Not(not) -} - -void ConditionalTest() #void : -{} -{ - ConditionalPrimary() -} - -void ConditionalPrimary() #void : -{} -{ - LOOKAHEAD( ConditionalExpression() ) - ( ConditionalExpression() ) #ConditionalParenthetical -| - SimpleCondExpression() -} - -void SimpleCondExpression() #void : -{} -{ - EmptyCollectionComparisonExpression() -| - LOOKAHEAD({ getToken(2).kind==IS }) - NullComparisonExpression() -| - LOOKAHEAD({ getToken(2).kind==MEMBER || getToken(3).kind==MEMBER }) - CollectionMemberExpression() -| - LOOKAHEAD({ getToken(2).kind==LIKE || getToken(3).kind==LIKE }) - LikeExpression() -| - LOOKAHEAD({ getToken(2).kind==IN || getToken(3).kind==IN }) - InExpression() -| - ComparisonExpression() -} - -void BetweenExpression() #Between : -{} -{ - ArithmeticExpression() [ { jjtThis.not=true; } ] - ArithmeticExpression() ArithmeticExpression() -} - -void InExpression() #In : -{} -{ - (StringExpression() [ { jjtThis.not=true; } ] - StringExpression() ( StringExpression() )* ) -| - (ArithmeticPrimary() [ { jjtThis.not=true; } ] - ArithmeticPrimary() ( ArithmeticPrimary() )* ) -} - -void LikeExpression() #Like : -{} -{ - StringValuedPath() [ { jjtThis.not=true; } ] - StringExpression() [ (StringLiteral() | NumericValuedParameter())] -} - -void NullComparisonExpression() #NullComparison : -{} -{ - ( - SingleValuedPath() | - NumericValuedParameter() | - EntityValuedParameter() | - StringValuedParameter() | - DatetimeValuedParameter() | - BooleanValuedParameter() - ) - [ { jjtThis.not=true; } ] -} - -void EmptyCollectionComparisonExpression() #IsEmpty : -{} -{ - CollectionValuedPath() [ { jjtThis.not=true; } ] -} - -void CollectionMemberExpression() #MemberOf : -{} -{ - (EntityValuedPath() | - IdentificationVariable() | - EntityValuedParameter()) - [ { jjtThis.not=true; } ] [] CollectionValuedPath() -} - - -void ComparisonExpression() #void : -{} -{ - ( - StringValue() - ( - { jjtThis.opp="="; } | - { jjtThis.opp=">"; } | - { jjtThis.opp=">="; } | - { jjtThis.opp="<"; } | - { jjtThis.opp="<="; } | - { jjtThis.opp="<>"; } - ) - StringExpression() - ) #StringComparison -| - ( - BooleanValue() - [ - ( - { jjtThis.opp="="; } | - { jjtThis.opp="<>"; } - ) BooleanExpression() - ] - ) #BooleanComparison -| - ( - DatetimeValue() - ( - { jjtThis.opp="="; } | - { jjtThis.opp=">"; } | - { jjtThis.opp="<"; } | - { jjtThis.opp="<>"; } | - { jjtThis.opp=">="; } | - { jjtThis.opp="<="; } - ) - DatetimeExpression() - ) #DatetimeComparison -| - ( - EntityBeanValue() - ( - { jjtThis.opp="="; } | - { jjtThis.opp="<>"; } - ) - EntityBeanExpression() - ) #EntityComparison -| - LOOKAHEAD(ArithmeticValue() ( | | | | | ) ) - ( - ArithmeticValue() - ( - { jjtThis.opp="="; } | - { jjtThis.opp=">"; } | - { jjtThis.opp=">="; } | - { jjtThis.opp="<"; } | - { jjtThis.opp="<="; } | - { jjtThis.opp="<>"; } - ) - SingleValueDesignator() - ) #ArithmeticComparison -| - BetweenExpression() -} - -void ArithmeticValue() #void : -{} -{ - NumericValuedPath() | FunctionsReturningNumerics() -} - -void SingleValueDesignator() #void : -{} -{ - ScalarExpression() -} - -void ScalarExpression() #void : -{} -{ - ArithmeticExpression() -} - -void ArithmeticExpression() #void : -{} -{ - ( - ArithmeticTerm() - ( - ( - { jjtThis.addOpp("+"); } | - { jjtThis.addOpp("-"); } - ) ArithmeticTerm() - )* - ) #PlusMinus(>1) -} - -void ArithmeticTerm() #void : -{} -{ - ( - ArithmeticFactor() - ( - ( - { jjtThis.addOpp("*"); } | -
{ jjtThis.addOpp("/"); } - ) ArithmeticFactor() - )* - ) #MultDiv(>1) -} - -void ArithmeticFactor() #void : -{ boolean negation = false; } -{ - ( - [|{negation=true;}] ArithmeticPrimary() - ) #Negation(negation) -} - -void ArithmeticPrimary() #void : -{} -{ - NumericValuedPath() | - NumericLiteral() | - ( ArithmeticExpression() ) #ArithmeticParenthetical | - NumericValuedParameter() | - FunctionsReturningNumerics() -} - -void StringValue() #void : -{} -{ - StringValuedPath() | FunctionsReturningStrings() -} - -void StringExpression() #void : -{} -{ - StringPrimary() | StringValuedParameter() -} - -void StringPrimary() #void : -{} -{ - StringValuedPath() | - StringLiteral() | - ( StringExpression() ) #StringParenthetical | - FunctionsReturningStrings() -} - -void DatetimeValue() #void : -{} -{ - DatetimeValuedPath() -} - -void DatetimeExpression() #void : -{} -{ - DatetimeValue() | DatetimeValuedParameter() -} - -void BooleanValue() #void : -{} -{ - BooleanValuedPath() -} - -void BooleanExpression() #void : -{} -{ - BooleanValue() | BooleanValuedParameter() | BooleanLiteral() -} - -void EntityBeanValue() #void : -{} -{ - EntityValuedPath() | IdentificationVariable() -} - -void EntityBeanExpression() #void : -{} -{ - EntityBeanValue() | EntityValuedParameter() -} - -void FunctionsReturningStrings() #void : -{} -{ - ( - StringExpression() StringExpression() - ) #Concat -| - ( - - StringExpression() - ArithmeticExpression() - ArithmeticExpression() - ) #Substring -} - -void FunctionsReturningNumerics() #void : -{} -{ - ( - StringExpression() - ) #Length -| - ( - - StringExpression() StringExpression() - [ ArithmeticExpression()] - ) #Locate -| - ( - ArithmeticExpression() - ) #Abs -| - ( - ArithmeticExpression() - ) #Sqrt -| - ( - ArithmeticExpression() ArithmeticExpression() - ) #Mod -} - -Token CollectionValuedPath() #Path : -{ Token t; } -{ - t= - { - initPathNode(jjtThis, t.image, EJBQLTypes.ENTITY_TYPE); - return t; - } -} - -Token IdentificationVariable() #Path : -{ Token t; } -{ - t= - { - t.image = t.image.toLowerCase(); - initPathNode(jjtThis, t.image, EJBQLTypes.ENTITY_TYPE); - return t; - } -} - -Token AbstractSchema() #AbstractSchema : -{ Token t; } -{ - t= - { - jjtThis.abstractSchemaName = t.image; - jjtThis.entity = catalog.getEntityByAbstractSchemaName(t.image); - return t; - } - | - t= - { - jjtThis.abstractSchemaName = t.image; - jjtThis.entity = catalog.getEntityByAbstractSchemaName(t.image); - return t; - } -} - -Token Identifier() #Identifier : -{ Token t; } -{ - t= - { - t.image = t.image.toLowerCase(); - jjtThis.identifier = t.image; - return t; - } -} - -void SingleValuedPath() #void : -{} -{ - NumericValuedPath() -| StringValuedPath() -| DatetimeValuedPath() -| BooleanValuedPath() -| EntityValuedPath() -| ValueClassValuedPath() -} - -void NumericValuedPath() #Path : -{ Token t; } -{ - t= - { initPathNode(jjtThis, t.image, EJBQLTypes.NUMERIC_TYPE); } -} - -void StringValuedPath() #Path : -{ Token t; } -{ - t= - { initPathNode(jjtThis, t.image, EJBQLTypes.STRING_TYPE); } -} - -void DatetimeValuedPath() #Path : -{ Token t; } -{ - t= - { initPathNode(jjtThis, t.image, EJBQLTypes.DATETIME_TYPE); } -} - -void BooleanValuedPath() #Path : -{ Token t; } -{ - t= - { initPathNode(jjtThis, t.image, EJBQLTypes.BOOLEAN_TYPE); } -} - -void EntityValuedPath() #Path : -{ Token t; } -{ - t= - { initPathNode(jjtThis, t.image, EJBQLTypes.ENTITY_TYPE); } -} - -void ValueClassValuedPath() #Path : -{ Token t; } -{ - t= - { initPathNode(jjtThis, t.image, EJBQLTypes.VALUE_CLASS_TYPE); } -} - -void NumericValuedParameter() #Parameter : -{ Token t; } -{ - t= - { initParameterNode(jjtThis, t.image, EJBQLTypes.NUMERIC_TYPE); } -} - -void StringValuedParameter() #Parameter : -{ Token t; } -{ - t= - { initParameterNode(jjtThis, t.image, EJBQLTypes.STRING_TYPE); } -} - -void DatetimeValuedParameter() #Parameter : -{ Token t; } -{ - t= - { initParameterNode(jjtThis, t.image, EJBQLTypes.DATETIME_TYPE); } -} - -void BooleanValuedParameter() #Parameter : -{ Token t; } -{ - t= - { initParameterNode(jjtThis, t.image, EJBQLTypes.BOOLEAN_TYPE); } -} - -void EntityValuedParameter() #Parameter : -{ Token t; } -{ - t= - { initParameterNode(jjtThis, t.image, EJBQLTypes.ENTITY_TYPE); } -} - -void ValueClassValuedParameter() #Parameter : -{ Token t; } -{ - t= - { initParameterNode(jjtThis, t.image, EJBQLTypes.VALUE_CLASS_TYPE); } -} - -void NumericLiteral() #void : -{ Token t; } -{ - ( - t= { jjtThis.setValue(t.image); } - ) #ExactNumericLiteral -| - ( - t= { jjtThis.setValue(t.image); } - ) #ApproximateNumericLiteral -} - -void StringLiteral() #StringLiteral : -{ Token t; } -{ - t= - { jjtThis.value=t.image; } -} - -void BooleanLiteral() #BooleanLiteral : -{ Token t; } -{ - { jjtThis.value=true; } | { jjtThis.value=false; } -} - -void AggregateSelectExpression() #void: -{} -{ - ( - [ {jjtThis.distinct="DISTINCT";}] SingleValuedPath() - ) #Avg -| - ( - [ {jjtThis.distinct="DISTINCT";}] SingleValuedPath() - ) #Max -| - ( - [ {jjtThis.distinct="DISTINCT";}] SingleValuedPath() - ) #Min -| - ( - [ {jjtThis.distinct="DISTINCT";}] SingleValuedPath() - ) #Sum -| - ( - [ {jjtThis.distinct="DISTINCT";}] - ( - SingleValuedPath() | EntityBeanValue() - ) - - ) #Count -} - -///////////////////////// -// Tokens -///////////////////////// - -TOKEN_MGR_DECLS : -{ - public Catalog catalog; - public Class[] argumentTypes; - public IdentifierManager idManager; - - // used for navigation building - private List pathList; - private List fieldList; - private String path; - - private void resetPath() { - path = ""; - pathList = new ArrayList(); - fieldList = new ArrayList(); - } - - private void throwUnknownPath( - String reason, - String fieldName) { - - throw new UnknownPathException( - reason, - path, - fieldName, - input_stream.getEndLine(), - input_stream.getEndColumn()); - } - - private void addPath(String nav) { - String fieldName = nav.substring(0, nav.length()-1); - if(fieldList.size() > 0) { - FieldBridge field = getCurrentSchema().getFieldByName(fieldName); - if(field == null) { - throwUnknownPath("Unknown cmr field in path", fieldName); - } - if(!(field instanceof CMRFieldBridge)) { - throwUnknownPath("In path field is not a cmr field", fieldName); - } - - CMRFieldBridge cmrField = (CMRFieldBridge)field; - if(!cmrField.isSingleValued()) { - throwUnknownPath("In path cmr field is collection valued", - fieldName); - } - fieldList.add(cmrField); - } else { - EntityBridge entityBridge = idManager.getEntity(fieldName); - if(entityBridge == null) { - throwUnknownPath("Unknown initial identifier", fieldName); - } - fieldList.add(entityBridge); - } - pathList.add(path + fieldName); - path += nav; - } - - private EntityBridge getCurrentSchema() { - Object lastElement = fieldList.get(fieldList.size()-1); - if(lastElement instanceof EntityBridge) { - return (EntityBridge)lastElement; - } else if(lastElement instanceof CMRFieldBridge) { - return ((CMRFieldBridge)lastElement).getRelatedEntity(); - } - // should never happen - throw new IllegalStateException("Unknown path element type: " + - lastElement); - } -} - - SKIP : -{ - " " -| "\t" -| "\n" -| "\r" -} - - TOKEN [IGNORE_CASE] : /* RESERVED WORDS */ -{ - < ABS: "ABS" > -| < AND: "AND" > -| < AS: "AS" > -| < BETWEEN: "BETWEEN" > -| < CONCAT: "CONCAT" > -| < DISTINCT: "DISTINCT" > -| < EMPTY: "EMPTY" > -| < ESCAPE: "ESCAPE" > -| < FROM: "FROM" > -| < IN: "IN" > -| < IS: "IS" > -| < LENGTH: "LENGTH" > -| < LIKE: "LIKE" > -| < LOCATE: "LOCATE" > -| < NOT: "NOT" > -| < NULL: "NULL" > -| < OBJECT: "OBJECT" > -| < OF: "OF " > -| < OR: "OR" > -| < SELECT: "SELECT" > -| < SUBSTRING: "SUBSTRING" > -| < SQRT: "SQRT" > -| < UNKNOWN: "UNKNOWN" > -| < WHERE: "WHERE" > -| < MEMBER: "MEMBER" > - -// EJB QL 2.1 tokens - -| < ORDER: "ORDER" > -| < BY: "BY" > -| < ASC: "ASC" > -| < DESC: "DESC" > -| < COUNT: "COUNT" > -| < MAX: "MAX" > -| < MIN: "MIN" > -| < AVG: "AVG" > -| < SUM: "SUM" > -| < MOD: "MOD" > -} - - TOKEN : /* SEPARATORS */ -{ - < LPAREN: "(" > -| < RPAREN: ")" > -| < COMMA: "," > -| < DOT: "." > -} - - TOKEN : /* OPERATORS */ -{ - < GT: ">" > -| < LT: "<" > -| < EQ: "=" > -| < LE: "<=" > -| < GE: ">=" > -| < NE: "<>" > -| < PLUS: "+" > -| < MINUS: "-" > -| < MULT: "*" > -| < DIV: "/" > -} - - TOKEN : /* String Literal */ -{ - < STRING_LITERAL: "'" (~["'"])* ( "''" (~["'"])* )* "'" > -} - - TOKEN : /* Numeric Literal */ -{ - < INTEGER_LITERAL: - (["l","L"])? - | (["l","L"])? - | (["l","L"])? - > -| - < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* > -| - < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ > -| - < #OCTAL_LITERAL: "0" (["0"-"7"])* > -| - < FLOATING_POINT_LITERAL: - (["0"-"9"])+ "." (["0"-"9"])* ()? (["f","F","d","D"])? - | "." (["0"-"9"])+ ()? (["f","F","d","D"])? - | (["0"-"9"])+ (["f","F","d","D"])? - | (["0"-"9"])+ ()? ["f","F","d","D"] - > -| - < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > -} - - TOKEN [IGNORE_CASE] : /* Boolean Literal */ -{ - < FALSE: "FALSE" > -| < TRUE: "TRUE" > -} - - TOKEN : /* IDENTIFIERS */ -{ - < IDENTIFIER: > - { - if(catalog.getEntityByAbstractSchemaName(matchedToken.image) != null) { - matchedToken.kind = ABSTRACT_SCHEMA; - } else if(idManager.getEntity(matchedToken.image.toLowerCase()) != null) { - matchedToken.kind = IDENTIFICATION_VARIABLE; - matchedToken.image = matchedToken.image.toLowerCase(); - - List pathList = new ArrayList(); - pathList.add(matchedToken.image); - List fieldList = new ArrayList(); - fieldList.add(idManager.getEntity(matchedToken.image)); - idManager.registerPath(matchedToken.image, pathList, fieldList); - } - } -| - < ABSTRACT_SCHEMA: [] > -| - < IDENTIFICATION_VARIABLE: [] > -| - < #NAME: (|)* > -| - < #LETTER: - [ - "\u0024", - "\u0041"-"\u005a", - "\u005f", - "\u0061"-"\u007a", - "\u00c0"-"\u00d6", - "\u00d8"-"\u00f6", - "\u00f8"-"\u00ff", - "\u0100"-"\u1fff", - "\u3040"-"\u318f", - "\u3300"-"\u337f", - "\u3400"-"\u3d2d", - "\u4e00"-"\u9fff", - "\uf900"-"\ufaff" - ] - > -| - < #DIGIT: - [ - "\u0030"-"\u0039", - "\u0660"-"\u0669", - "\u06f0"-"\u06f9", - "\u0966"-"\u096f", - "\u09e6"-"\u09ef", - "\u0a66"-"\u0a6f", - "\u0ae6"-"\u0aef", - "\u0b66"-"\u0b6f", - "\u0be7"-"\u0bef", - "\u0c66"-"\u0c6f", - "\u0ce6"-"\u0cef", - "\u0d66"-"\u0d6f", - "\u0e50"-"\u0e59", - "\u0ed0"-"\u0ed9", - "\u1040"-"\u1049" - ] - > -} - - TOKEN : /* PARAMETERS */ -{ - < UNKNOWN_PARAMETER: "?" > - { - int n = EJBQLTypes.UNKNOWN_TYPE; - try { - n = Integer.parseInt(matchedToken.image.substring(1, lengthOfMatch)); - } catch(Exception e) { /* Should never come here. */ } - - matchedToken.image = "" + n; - - // zero base the index - n--; - - if(n < argumentTypes.length) { - switch(EJBQLTypes.getEJBQLType(argumentTypes[n])) { - case EJBQLTypes.NUMERIC_TYPE: - matchedToken.kind = NUMERIC_VALUED_PARAMETER; - break; - case EJBQLTypes.STRING_TYPE: - matchedToken.kind = STRING_VALUED_PARAMETER; - break; - case EJBQLTypes.DATETIME_TYPE: - matchedToken.kind = DATETIME_VALUED_PARAMETER; - break; - case EJBQLTypes.BOOLEAN_TYPE: - matchedToken.kind = BOOLEAN_VALUED_PARAMETER; - break; - case EJBQLTypes.ENTITY_TYPE: - matchedToken.kind = ENTITY_VALUED_PARAMETER; - break; - case EJBQLTypes.VALUE_CLASS_TYPE: - matchedToken.kind = VALUE_CLASS_VALUED_PARAMETER; - break; - } - } - } -| < NUMERIC_VALUED_PARAMETER: [] > -| < STRING_VALUED_PARAMETER: [] > -| < DATETIME_VALUED_PARAMETER: [] > -| < BOOLEAN_VALUED_PARAMETER: [] > -| < ENTITY_VALUED_PARAMETER: [] > -| < VALUE_CLASS_VALUED_PARAMETER: [] > -} - -/** - * WARNING: Be careful here. If look ahead is to high in the from clause, it - * is possible that the identification varible is not registered before it - * is used here. - */ - SPECIAL_TOKEN : /* Navigation */ -{ - < > { - resetPath(); - addPath(matchedToken.image.toLowerCase()); - } : IN_NAVIGATION -} - - SPECIAL_TOKEN : -{ - < > { addPath(matchedToken.image); } : IN_NAVIGATION -} - - TOKEN : -{ - < PART: > { - String fieldName = matchedToken.image; - matchedToken.image = path + fieldName; - - FieldBridge field = getCurrentSchema().getFieldByName(fieldName); - if(field == null) { - throwUnknownPath("Unknown terminal field", fieldName); - } - if(field instanceof CMPFieldBridge) { - CMPFieldBridge cmpField = (CMPFieldBridge)field; - switch(EJBQLTypes.getEJBQLType(cmpField.getFieldType())) { - case EJBQLTypes.NUMERIC_TYPE: - matchedToken.kind = NUMERIC_VALUED_PATH; - break; - case EJBQLTypes.STRING_TYPE: - matchedToken.kind = STRING_VALUED_PATH; - break; - case EJBQLTypes.DATETIME_TYPE: - matchedToken.kind = DATETIME_VALUED_PATH; - break; - case EJBQLTypes.BOOLEAN_TYPE: - matchedToken.kind = BOOLEAN_VALUED_PATH; - break; - case EJBQLTypes.ENTITY_TYPE: - matchedToken.kind = ENTITY_VALUED_PATH; - break; - case EJBQLTypes.VALUE_CLASS_TYPE: - matchedToken.kind = VALUE_CLASS_VALUED_PATH; - break; - default: - throwUnknownPath("Unknown cmp field type", fieldName); - } - } else { - CMRFieldBridge cmrField = (CMRFieldBridge)field; - if(cmrField.isSingleValued()) { - matchedToken.kind = ENTITY_VALUED_PATH; - } else { - matchedToken.kind = COLLECTION_VALUED_PATH; - } - } - pathList.add(matchedToken.image); - fieldList.add(field); - idManager.registerPath(matchedToken.image, pathList, fieldList); - resetPath(); - } : DEFAULT -| < NUMERIC_VALUED_PATH: [] > -| < STRING_VALUED_PATH: [] > -| < DATETIME_VALUED_PATH: [] > -| < BOOLEAN_VALUED_PATH: [] > -| < ENTITY_VALUED_PATH: [] > -| < VALUE_CLASS_VALUED_PATH: [] > -| < UNKNOWN_PATH: [] > -| < COLLECTION_VALUED_PATH: [] > -} - - Index: org/jboss/ejb/plugins/MetricsInterceptor.java =================================================================== --- org/jboss/ejb/plugins/MetricsInterceptor.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/plugins/MetricsInterceptor.java (.../trunk/server/src/main/java) (revision 97312) @@ -255,7 +255,7 @@ */ public void run() { - + boolean intr = false; try { final boolean IS_TRANSACTED = true; @@ -335,6 +335,7 @@ catch (InterruptedException e) { // kill this thread + intr = true; running = false; } } @@ -364,6 +365,10 @@ { log.warn(e); } + finally + { + if (intr) Thread.currentThread().interrupt(); + } } } } Index: org/jboss/ejb/plugins/lock/QueuedPessimisticEJBLock.java =================================================================== --- org/jboss/ejb/plugins/lock/QueuedPessimisticEJBLock.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/plugins/lock/QueuedPessimisticEJBLock.java (.../trunk/server/src/main/java) (revision 97312) @@ -272,98 +272,107 @@ */ protected boolean waitForTx(Transaction miTx, boolean trace) throws Exception { - boolean wasScheduled = false; - // Do we have a running transaction with the context? - // We loop here until either until success or until transaction timeout - // If we get out of the loop successfully, we can successfully - // set the transaction on this puppy. - TxLock txLock = null; - Object deadlocker = miTx; - if (deadlocker == null) deadlocker = Thread.currentThread(); + boolean intr = false; + try + { + boolean wasScheduled = false; + // Do we have a running transaction with the context? + // We loop here until either until success or until transaction timeout + // If we get out of the loop successfully, we can successfully + // set the transaction on this puppy. + TxLock txLock = null; + Object deadlocker = miTx; + if (deadlocker == null) deadlocker = Thread.currentThread(); - while (getTransaction() != null && - // And are we trying to enter with another transaction? - !getTransaction().equals(miTx)) - { - // Check for a deadlock on every cycle - try + while (getTransaction() != null && + // And are we trying to enter with another transaction? + !getTransaction().equals(miTx)) { - if( deadlockDetection == true ) - DeadlockDetector.singleton.deadlockDetection(deadlocker, this); - } - catch (Exception e) - { - // We were queued, not any more - if (txLock != null && txLock.isQueued) + // Check for a deadlock on every cycle + try { - txLocks.remove(txLock); - txWaitQueue.remove(txLock); + if( deadlockDetection == true ) + DeadlockDetector.singleton.deadlockDetection(deadlocker, this); } - throw e; - } + catch (Exception e) + { + // We were queued, not any more + if (txLock != null && txLock.isQueued) + { + txLocks.remove(txLock); + txWaitQueue.remove(txLock); + } + throw e; + } - wasScheduled = true; - if (lockMonitor != null) lockMonitor.contending(); - // That's no good, only one transaction per context - // Let's put the thread to sleep the transaction demarcation will wake them up - if (trace) log.trace("Transactional contention on context" + id); + wasScheduled = true; + if (lockMonitor != null) lockMonitor.contending(); + // That's no good, only one transaction per context + // Let's put the thread to sleep the transaction demarcation will wake them up + if (trace) log.trace("Transactional contention on context" + id); - // Only queue the lock on the first iteration - if (txLock == null) - txLock = getTxLock(miTx); + // Only queue the lock on the first iteration + if (txLock == null) + txLock = getTxLock(miTx); - if (trace) log.trace("Begin wait on Tx=" + getTransaction()); + if (trace) log.trace("Begin wait on Tx=" + getTransaction()); - // And lock the threads on the lock corresponding to the Tx in MI - synchronized (txLock) - { - releaseSync(); - try + // And lock the threads on the lock corresponding to the Tx in MI + synchronized (txLock) { - txLock.wait(txTimeout); - } - catch (InterruptedException ignored) + releaseSync(); + try + { + txLock.wait(txTimeout); + } + catch (InterruptedException ignored) + { + intr = true; + } + } // end synchronized(txLock) + + this.sync(); + + if (trace) log.trace("End wait on TxLock=" + getTransaction()); + if (isTxExpired(miTx)) { + log.error(Thread.currentThread() + "Saw rolled back tx=" + miTx + " waiting for txLock" + // +" On method: " + mi.getMethod().getName() + // +" txWaitQueue size: " + txWaitQueue.size() + ); + if (txLock.isQueued) + { + // Remove the TxLock from the queue because this thread is exiting. + // Don't worry about notifying other threads that share the same transaction. + // They will timeout and throw the below RuntimeException + txLocks.remove(txLock); + txWaitQueue.remove(txLock); + } + else if (getTransaction() != null && getTransaction().equals(miTx)) + { + // We're not qu + nextTransaction(); + } + if (miTx != null) + { + if( deadlockDetection == true ) + DeadlockDetector.singleton.removeWaiting(deadlocker); + } + throw new RuntimeException("Transaction marked for rollback, possibly a timeout"); } - } // end synchronized(txLock) + } // end while(tx!=miTx) - this.sync(); - - if (trace) log.trace("End wait on TxLock=" + getTransaction()); - if (isTxExpired(miTx)) + // If we get here, this means that we have the txlock + if (!wasScheduled) { - log.error(Thread.currentThread() + "Saw rolled back tx=" + miTx + " waiting for txLock" - // +" On method: " + mi.getMethod().getName() - // +" txWaitQueue size: " + txWaitQueue.size() - ); - if (txLock.isQueued) - { - // Remove the TxLock from the queue because this thread is exiting. - // Don't worry about notifying other threads that share the same transaction. - // They will timeout and throw the below RuntimeException - txLocks.remove(txLock); - txWaitQueue.remove(txLock); - } - else if (getTransaction() != null && getTransaction().equals(miTx)) - { - // We're not qu - nextTransaction(); - } - if (miTx != null) - { - if( deadlockDetection == true ) - DeadlockDetector.singleton.removeWaiting(deadlocker); - } - throw new RuntimeException("Transaction marked for rollback, possibly a timeout"); + setTransaction(miTx); } - } // end while(tx!=miTx) - - // If we get here, this means that we have the txlock - if (!wasScheduled) + return wasScheduled; + } + finally { - setTransaction(miTx); + if (intr) Thread.currentThread().interrupt(); } - return wasScheduled; } /* Index: org/jboss/ejb/plugins/lock/SimpleReadWriteEJBLock.java =================================================================== --- org/jboss/ejb/plugins/lock/SimpleReadWriteEJBLock.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/plugins/lock/SimpleReadWriteEJBLock.java (.../trunk/server/src/main/java) (revision 97312) @@ -21,14 +21,10 @@ */ package org.jboss.ejb.plugins.lock; -import java.util.LinkedList; -import java.util.HashMap; import java.util.HashSet; import java.util.Stack; -import java.util.Collections; import java.lang.reflect.Method; -import javax.ejb.EJBObject; import javax.ejb.EJBException; import javax.transaction.Status; import javax.transaction.Transaction; @@ -63,7 +59,7 @@ int writersWaiting = 0; Transaction promotingReader = null; Transaction writer = null; - HashSet readers = new HashSet(); + final HashSet readers = new HashSet(); Object methodLock = new Object(); boolean trace = log.isTraceEnabled(); @@ -205,24 +201,26 @@ */ private void waitAWhile(Transaction tx) { - releaseSync(); - try - { - synchronized(readers) - { - try - { - readers.wait(txTimeout); - } - catch(InterruptedException e) - {} - checkTransaction(tx); - } - } - finally - { - sync(); - } + releaseSync(); + try + { + synchronized (readers) + { + try + { + readers.wait(txTimeout); + } + catch (InterruptedException e) + { + Thread.currentThread().interrupt(); + } + checkTransaction(tx); + } + } + finally + { + sync(); + } } /** Index: org/jboss/ejb/plugins/lock/BeanLockSupport.java =================================================================== --- org/jboss/ejb/plugins/lock/BeanLockSupport.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/plugins/lock/BeanLockSupport.java (.../trunk/server/src/main/java) (revision 97312) @@ -100,20 +100,31 @@ */ public void sync() { - synchronized(this) + boolean intr = false; + try { - Thread thread = Thread.currentThread(); - while(synched != null && synched.equals(thread) == false) + synchronized(this) { - try + Thread thread = Thread.currentThread(); + while(synched != null && synched.equals(thread) == false) { - this.wait(); + try + { + wait(); + } + catch (InterruptedException ex) + { + intr = true; + } } - catch (InterruptedException ex) { /* ignore */ } + synched = thread; + ++synchedDepth; } - synched = thread; - ++synchedDepth; } + finally + { + if (intr) Thread.currentThread().interrupt(); + } } public void releaseSync() Index: org/jboss/ejb/GlobalTxEntityMap.java =================================================================== --- org/jboss/ejb/GlobalTxEntityMap.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/GlobalTxEntityMap.java (.../trunk/server/src/main/java) (revision 97312) @@ -257,13 +257,12 @@ } return globalSync; } - + public Transaction getTransaction() { return txSynch.getTransaction(); } - /** * associate instance with transaction */ @@ -309,17 +308,17 @@ otherSync.add(sync); } } - + public void putTxLocal(Object key, Object value) { if(txLocals.isEmpty()) txLocals = Collections.singletonMap(key, value); else - { + { if(txLocals.size() == 1) txLocals = new HashMap(txLocals); txLocals.put(key, value); - } + } } public Object getTxLocal(Object key) Index: org/jboss/ejb/EJBDeployerMBean.java =================================================================== --- org/jboss/ejb/EJBDeployerMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/EJBDeployerMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -25,13 +25,12 @@ import javax.management.ObjectName; -import org.jboss.deployment.SubDeployerExtMBean; import org.jboss.mx.util.ObjectNameFactory; /** * EJBDeployer MBean interface. */ -public interface EJBDeployerMBean extends SubDeployerExtMBean +public interface EJBDeployerMBean { /** The default ObjectName */ ObjectName OBJECT_NAME = ObjectNameFactory.create("jboss.ejb:service=EJBDeployer"); Index: org/jboss/ejb/Container.java =================================================================== --- org/jboss/ejb/Container.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/Container.java (.../trunk/server/src/main/java) (revision 97312) @@ -56,7 +56,6 @@ import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit; import org.jboss.deployment.DeploymentException; -import org.jboss.deployment.DeploymentInfo; import org.jboss.ejb.plugins.local.BaseLocalProxyFactory; import org.jboss.ejb.txtimer.EJBTimerService; import org.jboss.ejb.txtimer.EJBTimerServiceImpl; @@ -89,10 +88,10 @@ import org.jboss.security.AnybodyPrincipal; import org.jboss.security.AuthenticationManager; import org.jboss.security.ISecurityManagement; -import org.jboss.security.SecurityConstants; -import org.jboss.security.authorization.PolicyRegistration; import org.jboss.security.RealmMapping; +import org.jboss.security.SecurityConstants; import org.jboss.security.SimplePrincipal; +import org.jboss.security.authorization.PolicyRegistration; import org.jboss.system.ServiceMBeanSupport; import org.jboss.util.NestedError; import org.jboss.util.NestedRuntimeException; @@ -190,7 +189,7 @@ /** SecurityManagement Instance - holder of all security managers */ protected ISecurityManagement securityManagement; - + /** PolicyRegistration - Holds Authorization Policies */ protected PolicyRegistration policyRegistration; @@ -242,8 +241,8 @@ /** The JACC context id for the container */ protected String jaccContextID; - /** - * Flag to denote whether a JACC configuration has been fitted for authorization + /** + * Flag to denote whether a JACC configuration has been fitted for authorization */ protected boolean isJaccEnabled = false; @@ -290,7 +289,7 @@ /** * Whether the bean is call by value - * + * * @return true for call by value */ public boolean isCallByValue() @@ -340,7 +339,7 @@ public void setSecurityManagement(ISecurityManagement securityManagement) { this.securityManagement = securityManagement; - } + } public PolicyRegistration getPolicyRegistration() { @@ -414,7 +413,7 @@ // There's no factory thread local which means this is probably // a local invocation. Just use the first (usually only) // proxy factory. - // TODO: define a default factory in the meta data or + // TODO: define a default factory in the meta data or // even better, let the return over the original transport // plugin the transport layer for the generated proxy if (factory == null && remoteInterface != null) @@ -436,25 +435,6 @@ return (EJBProxyFactory)proxyFactories.get(binding); } - /** - * Gets the DeploymentInfo for this Container - * @deprecated use DeploymentUnit accessors - * @return The DeploymentInfo for this Container - */ - public final DeploymentInfo getDeploymentInfo() - { - return null; - } - - /** - * Sets the DeploymentInfo of this Container - * @deprecated use DeploymentUnit accessors - * @param di The new DeploymentInfo to be used - */ - public final void setDeploymentInfo(DeploymentInfo di) - { - } - public final VFSDeploymentUnit getDeploymentUnit() { return unit; @@ -496,9 +476,9 @@ this.timerService = timerService; } - /** - * Get the flag whether JACC is enabled - * @return + /** + * Get the flag whether JACC is enabled + * @return */ public boolean isJaccEnabled() { @@ -506,9 +486,9 @@ } /** - * Set the flag that JACC is enabled - * - * @param isJaccEnabled + * Set the flag that JACC is enabled + * + * @param isJaccEnabled */ public void setJaccEnabled(boolean isJaccEnabled) { @@ -526,14 +506,6 @@ } /** - * Gets the deployment unit name that contains this container. - */ - public String getDeploymentName() - { - return ejbModule.name; - } - - /** * Gets the number of create invocations that have been made * @jmx.managed-attribute */ @@ -559,62 +531,7 @@ return invokeStats; } - /** - * Converts the method invocation stats into a detyped nested map structure. - * The format is: - * - * {methodName => {statisticTypeName => longValue}} - * - * @return A map indexed by method name with map values indexed by statistic type - */ - public Map> getDetypedInvocationStatistics() - { - return invokeStats.toDetypedMap(); - } - - /** - * Return the current instance pool associate with this container if - * supported by the underlying container implementation. - * - * @return instance pool - * @throws UnsupportedOperationException if the container does not support an instance pool - */ - protected InstancePool getInstancePool() - { - throw new UnsupportedOperationException(); - } - - /** - * Get current pool size of the pool associated with this container, - * also known as the method ready count - * - * @throws UnsupportedOperationException if the container type does not support an instance pool - */ - public int getCurrentPoolSize() - { - return getInstancePool().getCurrentSize(); - } - - /** - * Get current pool size of the pool associated with this container. - * - * @throws UnsupportedOperationException if the container type does not support an instance pool - */ - public int getMaxPoolSize() - { - return getInstancePool().getMaxSize(); - } - - /** - * Resets the current invocation stats - */ - public void resetInvocationStats() - { - invokeStats.resetStats(); - } - - /** * Sets the class loader for this container. All the classes and resources * used by the bean in this container will use this classloader. * @@ -726,7 +643,7 @@ } else if (m.equals(EJB_TIMEOUT)) { - // No role is required to access the ejbTimeout as this is + // No role is required to access the ejbTimeout as this is permissions = new HashSet(); permissions.add(AnybodyPrincipal.ANYBODY_PRINCIPAL); methodPermissionsCache.put(m, permissions); @@ -741,7 +658,7 @@ { for (String role : roles) permissions.add(new SimplePrincipal(role)); - } + } methodPermissionsCache.put(m, permissions); } @@ -1028,7 +945,7 @@ public abstract void addInterceptor(Interceptor in); /** The detached invoker operation. - * + * * @jmx.managed-operation * * @param mi - the method invocation context @@ -1514,11 +1431,11 @@ if (securityDomain == null) securityDomain = metaData.getApplicationMetaData().getSecurityDomain(); if (securityDomain != null) - { + { //JBAS-6060: Tolerate a Security Domain configuration without the java:/jaas prefix if(securityDomain.startsWith(SecurityConstants.JAAS_CONTEXT_ROOT) == false) securityDomain = SecurityConstants.JAAS_CONTEXT_ROOT + "/" + securityDomain; - + log.debug("Binding securityDomain: " + securityDomain + " to JDNI ENC as: security/security-domain"); Util.bind(envCtx, "security/security-domain", new LinkRef(securityDomain)); Index: org/jboss/ejb/StatefulSessionContainer.java =================================================================== --- org/jboss/ejb/StatefulSessionContainer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/ejb/StatefulSessionContainer.java (.../trunk/server/src/main/java) (revision 97312) @@ -38,7 +38,6 @@ import javax.ejb.Handle; import javax.management.ObjectName; -import org.jboss.ejb.plugins.StatefulSessionInstanceCache; import org.jboss.invocation.Invocation; import org.jboss.invocation.InvocationType; import org.jboss.security.SimplePrincipal; @@ -58,7 +57,7 @@ public class StatefulSessionContainer extends SessionContainer - implements EJBProxyFactoryContainer, InstancePoolContainer, StatefulSessionContainerMBean + implements EJBProxyFactoryContainer, InstancePoolContainer { /** * This is the persistence manager for this container @@ -83,14 +82,6 @@ return instanceCache; } - public long getPassivatedCount() - { - if (! (instanceCache instanceof StatefulSessionInstanceCache)) - throw new UnsupportedOperationException(); - - return ((StatefulSessionInstanceCache)instanceCache).getPassivatedCount(); - } - public StatefulSessionPersistenceManager getPersistenceManager() { return persistenceManager; Index: org/jboss/config/ServerConfigUtil.java =================================================================== --- org/jboss/config/ServerConfigUtil.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/config/ServerConfigUtil.java (.../trunk/server/src/main/java) (revision 97312) @@ -24,8 +24,8 @@ import java.net.InetAddress; import java.net.UnknownHostException; -import org.jboss.bootstrap.api.as.config.JBossASServerConfig; import org.jboss.bootstrap.spi.as.config.JBossASConfigurationInitializer; +import org.jboss.bootstrap.spi.as.config.JBossASServerConfig; /** * ServerConfigUtil Index: org/jboss/naming/NamingProviderURLWriter.java =================================================================== --- org/jboss/naming/NamingProviderURLWriter.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/naming/NamingProviderURLWriter.java (.../trunk/server/src/main/java) (revision 97312) @@ -32,8 +32,8 @@ import java.net.URI; import java.util.Enumeration; -import org.jboss.bootstrap.api.as.server.JBossASBasedServer; import org.jboss.logging.Logger; +import org.jboss.bootstrap.spi.as.server.JBossASServer; /** * @@ -51,7 +51,7 @@ private String bootstrapUrl; private String bindAddress; private int port; - private JBossASBasedServer server; + private JBossASServer server; private URI outputDir; private String filename = DEFAULT_PERSIST_FILE_NAME; private File outputFile; @@ -76,7 +76,7 @@ this.filename = name; } - public void setServer(JBossASBasedServer server) + public void setServer(JBossASServer server) { this.server = server; } @@ -122,7 +122,7 @@ { if (server != null) { - base = new File(server.getConfiguration().getServerDataLocation().toURI()); + base = new File(server.getConfiguration().getServerDataLocation().toURI()); outputDir = base.toURI(); } } Index: org/jboss/naming/NamingService.java =================================================================== --- org/jboss/naming/NamingService.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/naming/NamingService.java (.../trunk/server/src/main/java) (revision 97312) @@ -34,20 +34,18 @@ import java.util.HashMap; import java.util.Map; import java.util.Properties; - -import javax.net.ServerSocketFactory; - +import java.util.concurrent.Executor; import org.jboss.invocation.Invocation; import org.jboss.invocation.MarshalledInvocation; import org.jboss.invocation.jrmp.server.JRMPProxyFactoryMBean; import org.jboss.system.ServiceMBeanSupport; -import org.jboss.util.threadpool.BasicThreadPoolMBean; -import org.jboss.util.threadpool.ThreadPool; import org.jnp.interfaces.MarshalledValuePair; import org.jnp.interfaces.Naming; import org.jnp.server.Main; import org.jnp.server.NamingBean; +import javax.net.ServerSocketFactory; + /** * A JBoss service that starts the jnp JNDI server. * @@ -71,6 +69,8 @@ private Map marshalledInvocationMapping = new HashMap(); /** An optional proxy factory for externalizing the Naming proxy transport */ private JRMPProxyFactoryMBean proxyFactory; + /** A flag indicating if the namingMain should be started in our startService */ + private boolean startNamingBean = true; public NamingService() { @@ -115,16 +115,16 @@ return namingBean.getNamingInstance(); } - /** Set the thread pool used for the bootstrap lookups + /** + * Set the executor used for the bootstrap lookups * * @jmx:managed-attribute * - * @param poolMBean + * @param executor the executor */ - public void setLookupPool(BasicThreadPoolMBean poolMBean) + public void setLookupPool(Executor executor) { - ThreadPool lookupPool = poolMBean.getInstance(); - namingMain.setLookupPool(lookupPool); + namingMain.setLookupExector(executor); } /** Get the call by value flag for jndi lookups. @@ -285,6 +285,16 @@ return namingMain.getLookupListenerException(); } + + public boolean getStartNamingBean() + { + return startNamingBean; + } + public void setStartNamingBean(boolean startNamingBean) + { + this.startNamingBean = startNamingBean; + } + protected void startService() throws Exception { @@ -317,7 +327,8 @@ } if( proxyFactory != null ) namingMain.setNamingProxy(proxyFactory.getProxy()); - namingMain.start(); + if( startNamingBean ) + namingMain.start(); // Build the Naming interface method map HashMap tmpMap = new HashMap(13); @@ -334,8 +345,11 @@ protected void stopService() throws Exception { - namingMain.stop(); - log.debug("JNP server stopped"); + if(startNamingBean) + { + namingMain.stop(); + log.debug("JNP server stopped"); + } } /** Index: org/jboss/naming/NamingServiceMBean.java =================================================================== --- org/jboss/naming/NamingServiceMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/naming/NamingServiceMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -21,6 +21,8 @@ */ package org.jboss.naming; +import java.util.concurrent.Executor; + /** * MBean interface. */ @@ -30,9 +32,11 @@ public static final javax.management.ObjectName OBJECT_NAME = org.jboss.mx.util.ObjectNameFactory.create("jboss:service=Naming"); /** - * Set the thread pool used for the bootstrap lookups - * @param poolMBean */ - void setLookupPool(org.jboss.util.threadpool.BasicThreadPoolMBean poolMBean) ; + * Set the executor used for the bootstrap lookups. + * + * @param executor the executor + */ + void setLookupPool(Executor executor) ; /** * Get the call by value flag for jndi lookups. @@ -44,6 +48,9 @@ * @param flag - true if all lookups are unmarshalled using the caller's TCL, false if in VM lookups return the value by reference. */ void setCallByValue(boolean flag) ; + public boolean getStartNamingBean(); + public void setStartNamingBean(boolean startNamingBean); + /** * Expose the Naming service interface mapping as a read-only attribute * @return A Map of the Naming interface */ Index: org/jboss/invocation/http/server/HttpProxyFactory.java =================================================================== --- org/jboss/invocation/http/server/HttpProxyFactory.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/invocation/http/server/HttpProxyFactory.java (.../trunk/server/src/main/java) (revision 97312) @@ -25,21 +25,20 @@ import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Iterator; - import javax.management.ObjectName; import javax.naming.InitialContext; -import org.jboss.config.ServerConfigUtil; import org.jboss.invocation.Invoker; import org.jboss.invocation.InvokerInterceptor; -import org.jboss.invocation.http.interfaces.ClientMethodInterceptor; import org.jboss.invocation.http.interfaces.HttpInvokerProxy; -import org.jboss.metadata.MetaData; +import org.jboss.invocation.http.interfaces.ClientMethodInterceptor; import org.jboss.naming.Util; import org.jboss.proxy.GenericProxyFactory; import org.jboss.system.Registry; import org.jboss.system.ServiceMBeanSupport; import org.jboss.util.StringPropertyReplacer; +import org.jboss.metadata.MetaData; +import org.jboss.config.ServerConfigUtil; import org.w3c.dom.Element; /** Create an interface proxy that uses HTTP to communicate with the server Index: org/jboss/invocation/http/server/HttpInvoker.java =================================================================== --- org/jboss/invocation/http/server/HttpInvoker.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/invocation/http/server/HttpInvoker.java (.../trunk/server/src/main/java) (revision 97312) @@ -23,7 +23,6 @@ import java.net.InetAddress; import java.net.UnknownHostException; - import javax.management.MBeanException; import javax.management.ObjectName; import javax.management.RuntimeMBeanException; @@ -32,8 +31,6 @@ import javax.naming.NamingException; import javax.transaction.Transaction; -import org.jboss.bootstrap.api.as.config.JBossASServerConfig; -import org.jboss.bootstrap.spi.as.config.JBossASConfigurationInitializer; import org.jboss.invocation.Invocation; import org.jboss.invocation.Invoker; import org.jboss.invocation.MarshalledInvocation; @@ -41,6 +38,7 @@ import org.jboss.system.Registry; import org.jboss.system.ServiceMBeanSupport; import org.jboss.util.StringPropertyReplacer; +import org.jboss.config.ServerConfigUtil; /** * The HttpInvoker ... into the JMX base. @@ -205,7 +203,7 @@ { InetAddress addr = InetAddress.getLocalHost(); // First check for a global bind address - String host = getSpecificBindAddress(); + String host = ServerConfigUtil.getSpecificBindAddress(); if( host == null ) { host = useHostName ? addr.getHostName() : addr.getHostAddress(); @@ -214,18 +212,5 @@ setInvokerURL(url); } } - - /** - * Retrieve the default bind address, but only if it is specific - * - * @return the specific bind address - */ - protected static String getSpecificBindAddress() - { - String address = System.getProperty(JBossASServerConfig.PROP_KEY_JBOSSAS_BIND_ADDRESS); - if (address == null || address.equals(JBossASConfigurationInitializer.VALUE_BIND_ADDRESS_ANY)) - return null; - return address; - } } Index: org/jboss/invocation/pooled/server/PooledInvoker.java =================================================================== --- org/jboss/invocation/pooled/server/PooledInvoker.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/invocation/pooled/server/PooledInvoker.java (.../trunk/server/src/main/java) (revision 97312) @@ -21,38 +21,37 @@ */ package org.jboss.invocation.pooled.server; -import java.lang.reflect.Method; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; -import java.rmi.NoSuchObjectException; +import java.util.LinkedList; +import java.security.PrivilegedExceptionAction; import java.security.AccessController; import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.LinkedList; - +import java.lang.reflect.Method; +import java.rmi.NoSuchObjectException; import javax.management.ObjectName; import javax.naming.InitialContext; -import javax.net.ServerSocketFactory; -import javax.net.SocketFactory; import javax.transaction.Transaction; import javax.transaction.TransactionManager; +import javax.net.SocketFactory; +import javax.net.ServerSocketFactory; -import org.jboss.config.ServerConfigUtil; import org.jboss.invocation.Invocation; import org.jboss.invocation.pooled.interfaces.PooledInvokerProxy; -import org.jboss.invocation.pooled.interfaces.PooledMarshalledInvocation; import org.jboss.invocation.pooled.interfaces.ServerAddress; +import org.jboss.invocation.pooled.interfaces.PooledMarshalledInvocation; import org.jboss.logging.Logger; -import org.jboss.net.sockets.DefaultSocketFactory; import org.jboss.proxy.TransactionInterceptor; -import org.jboss.security.SecurityDomain; import org.jboss.system.Registry; import org.jboss.system.ServiceMBeanSupport; import org.jboss.tm.TransactionPropagationContextFactory; import org.jboss.tm.TransactionPropagationContextImporter; import org.jboss.tm.TransactionPropagationContextUtil; +import org.jboss.security.SecurityDomain; +import org.jboss.net.sockets.DefaultSocketFactory; +import org.jboss.config.ServerConfigUtil; /** * This invoker pools Threads and client connections to one server socket. Index: org/jboss/invocation/pooled/server/ServerThread.java =================================================================== --- org/jboss/invocation/pooled/server/ServerThread.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/invocation/pooled/server/ServerThread.java (.../trunk/server/src/main/java) (revision 97312) @@ -21,11 +21,7 @@ */ package org.jboss.invocation.pooled.server; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.InterruptedIOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; +import java.io.*; import java.net.Socket; import java.util.LinkedList; @@ -48,6 +44,9 @@ * *NOTES* ObjectStreams were found to be better performing than the Custom marshalling * done by the TrunkInvoker. * + * NOTE: The interrupt handling surrounding shutdown appears rather f**ked but I don't see an easy way to fix it, + * so I'm leaving it for now. + * * @author Bill Burke * @author Scott.Stark@jboss.org * @version $Revision$ @@ -221,31 +220,45 @@ protected void processInvocation() throws Exception { - handlingResponse = true; - // Ok, now read invocation and invoke - Invocation invocation = (Invocation)in.readObject(); - in.readObject(); // for stupid ObjectInputStream reset - Object response = null; + // this is a best-effort attempt to avoid being interrupted, but as interruption can happen at any + // time, this is not bullet-proof + boolean interrupted = Thread.interrupted(); try { - // Make absolutely sure thread interrupted is cleared. - boolean interrupted = Thread.interrupted(); - response = invoker.invoke(invocation); + handlingResponse = true; + // Ok, now read invocation and invoke + Invocation invocation = (Invocation)in.readObject(); + in.readObject(); // for stupid ObjectInputStream reset + Object response = null; + try + { + // Make absolutely sure thread interrupted is cleared. + response = invoker.invoke(invocation); + } + catch (InterruptedException ex) + { + interrupted = true; + response = new IllegalStateException("Thread was interrupted"); + } + catch (Exception ex) + { + response = ex; + } + interrupted |= Thread.interrupted(); // clear interrupted state so we don't fail on socket writes + out.writeObject(response); + out.reset(); + // to make sure stream gets reset + // Stupid ObjectInputStream holds object graph + // can only be set by the client/server sending a TC_RESET + out.writeObject(Boolean.TRUE); + out.flush(); + out.reset(); + handlingResponse = false; } - catch (Exception ex) + finally { - response = ex; + if (interrupted) Thread.currentThread().interrupt(); } - Thread.interrupted(); // clear interrupted state so we don't fail on socket writes - out.writeObject(response); - out.reset(); - // to make sure stream gets reset - // Stupid ObjectInputStream holds object graph - // can only be set by the client/server sending a TC_RESET - out.writeObject(Boolean.TRUE); - out.flush(); - out.reset(); - handlingResponse = false; } /** @@ -253,82 +266,97 @@ */ protected void dorun() { - log.debug("beginning dorun"); - running = true; - handlingResponse = true; + boolean intr = false; try { - BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); - out = new OptimizedObjectOutputStream(bos); - out.flush(); - BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); - in = new OptimizedObjectInputStream(bis); - } - catch (Exception e) - { - log.error("Failed to initialize", e); - } + log.debug("beginning dorun"); + running = true; + handlingResponse = true; + try + { + BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); + out = new OptimizedObjectOutputStream(bos); + out.flush(); + BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); + in = new OptimizedObjectInputStream(bis); + } + catch (Exception e) + { + log.error("Failed to initialize", e); + } - // Always do first one without an ACK because its not needed - try - { - processInvocation(); - } - catch (Exception e) - { - running = false; - if( trace ) - log.trace("invocation failed", e); - } - - // Re-use loop - while (running) - { + // Always do first one without an ACK because its not needed try { - acknowledge(); processInvocation(); } - catch (InterruptedIOException e) - { - log.debug("socket timed out", e); - running = false; - } catch (InterruptedException e) { + intr = true; log.debug("interrupted", e); } - catch (Exception ex) + catch (Exception e) { + running = false; if( trace ) - log.debug("invocation failed", ex); - running = false; + log.trace("invocation failed", e); } - // clear any interruption so that thread can be pooled. - Thread.interrupted(); - } - if( trace ) - log.trace("finished loop"); - // Ok, we've been shutdown. Do appropriate cleanups. - try - { - if (in != null) in.close(); - if (out != null) out.close(); + // Re-use loop + while (running) + { + try + { + acknowledge(); + processInvocation(); + } + catch (InterruptedIOException e) + { + log.debug("socket timed out", e); + running = false; + } + catch (InterruptedException e) + { + intr = true; + log.debug("interrupted", e); + } + catch (Exception ex) + { + if( trace ) + log.debug("invocation failed", ex); + running = false; + } + } + + if( trace ) + log.trace("finished loop"); + // Ok, we've been shutdown. Do appropriate cleanups. + safeClose(in); + safeClose(out); + safeClose(socket); + socket = null; + in = null; + out = null; } - catch (Exception ex) + finally { + if (intr) Thread.currentThread().interrupt(); } - try - { - socket.close(); + } + + private static void safeClose(Closeable c) { + if (c != null) try { + c.close(); + } catch (Throwable t) { + log.error("Failed to close resource " + c, t); } - catch (Exception ex) - { - log.debug("Failed cleanup", ex); + } + + private static void safeClose(Socket c) { + if (c != null) try { + c.close(); + } catch (Throwable t) { + log.error("Failed to close resource " + c, t); } - socket = null; - in = null; - out = null; } } Index: org/jboss/invocation/unified/interfaces/JavaSerializationManager.java =================================================================== --- org/jboss/invocation/unified/interfaces/JavaSerializationManager.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/invocation/unified/interfaces/JavaSerializationManager.java (.../trunk/server/src/main/java) (revision 97312) @@ -1,103 +1,103 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2008, Red Hat Middleware LLC, 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.invocation.unified.interfaces; - -import java.io.IOException; - -import org.jboss.invocation.MarshalledValueEX; -import org.jboss.logging.Logger; -import org.jboss.remoting.serialization.IMarshalledValue; -import org.jboss.remoting.serialization.SerializationStreamFactory; - -/** - * JavaSerializationmanager from JBossRemoting doesn't use the same - * MarshalledValue specified by org.jboss.invocation. As - * org.jboss.invocation.MarshalledValue could use caching features from JBossAS, - * we will need to use that MarshalledValue. - * - * @author Clebert Suconic - */ -public class JavaSerializationManager extends - org.jboss.remoting.serialization.impl.java.JavaSerializationManager -{ - protected static final Logger log = Logger.getLogger(JavaSerializationManager.class); - - static - { - register(); - } - - /** Register yourself as Java manager into SerializationStreamFactory */ - private static void register() - { - register("compatible"); - register(SerializationStreamFactory.JAVA); - - try - { - if (SerializationStreamFactory.getManagerInstance().getClass() - == org.jboss.remoting.serialization.impl.java.JavaSerializationManager.class) - { - register(SerializationStreamFactory.DEFAULT); - } - } catch (Exception e) - { - log.error(e); - } - } - - private static void register(String provider) - { - try - { - SerializationStreamFactory.setManagerClassName( - provider, JavaSerializationManager.class.getName()); - } - catch (ClassNotFoundException e) - { - log.error(e); - } - catch (IllegalAccessException e) - { - log.error(e); - } - catch (InstantiationException e) - { - log.error(e); - } - } - - /** - * Creates a MarshalledValue that does lazy serialization. - */ - public IMarshalledValue createdMarshalledValue(Object source) throws IOException - { - if (source instanceof IMarshalledValue) - { - return (IMarshalledValue) source; - } - else - { - return new MarshalledValueEX(source); - } - } -} +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, 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.invocation.unified.interfaces; + +import java.io.IOException; + +import org.jboss.invocation.MarshalledValueEX; +import org.jboss.logging.Logger; +import org.jboss.remoting.serialization.IMarshalledValue; +import org.jboss.remoting.serialization.SerializationStreamFactory; + +/** + * JavaSerializationmanager from JBossRemoting doesn't use the same + * MarshalledValue specified by org.jboss.invocation. As + * org.jboss.invocation.MarshalledValue could use caching features from JBossAS, + * we will need to use that MarshalledValue. + * + * @author Clebert Suconic + */ +public class JavaSerializationManager extends + org.jboss.remoting.serialization.impl.java.JavaSerializationManager +{ + protected static final Logger log = Logger.getLogger(JavaSerializationManager.class); + + static + { + register(); + } + + /** Register yourself as Java manager into SerializationStreamFactory */ + private static void register() + { + register("compatible"); + register(SerializationStreamFactory.JAVA); + + try + { + if (SerializationStreamFactory.getManagerInstance().getClass() + == org.jboss.remoting.serialization.impl.java.JavaSerializationManager.class) + { + register(SerializationStreamFactory.DEFAULT); + } + } catch (Exception e) + { + log.error(e); + } + } + + private static void register(String provider) + { + try + { + SerializationStreamFactory.setManagerClassName( + provider, JavaSerializationManager.class.getName()); + } + catch (ClassNotFoundException e) + { + log.error(e); + } + catch (IllegalAccessException e) + { + log.error(e); + } + catch (InstantiationException e) + { + log.error(e); + } + } + + /** + * Creates a MarshalledValue that does lazy serialization. + */ + public IMarshalledValue createdMarshalledValue(Object source) throws IOException + { + if (source instanceof IMarshalledValue) + { + return (IMarshalledValue) source; + } + else + { + return new MarshalledValueEX(source); + } + } +} Property changes on: org/jboss/invocation/unified/interfaces/JavaSerializationManager.java ___________________________________________________________________ Added: svn:eol-style + native Index: org/jboss/invocation/unified/server/UnifiedInvoker.java =================================================================== --- org/jboss/invocation/unified/server/UnifiedInvoker.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/invocation/unified/server/UnifiedInvoker.java (.../trunk/server/src/main/java) (revision 97312) @@ -253,7 +253,6 @@ finally { currentThread.setContextClassLoader(oldCl); - Thread.interrupted(); // clear interruption because this thread may be pooled. } } Index: org/jboss/invocation/MarshalledValueEX.java =================================================================== --- org/jboss/invocation/MarshalledValueEX.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/invocation/MarshalledValueEX.java (.../trunk/server/src/main/java) (revision 97312) @@ -1,48 +1,48 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2008, Red Hat Middleware LLC, 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.invocation; - -import java.io.IOException; - -import org.jboss.remoting.serialization.IMarshalledValue; - -/** - * This is a way to have MarshalledValue implementing IMarshalledValue without - * changing legacy Invokers (Pooled, RMI) - * - * @author Clebert Suconic - */ -public class MarshalledValueEX extends MarshalledValue - implements IMarshalledValue -{ - private static final long serialVersionUID = -1527598981234110322L; - - public MarshalledValueEX() - { - super(); - } - - public MarshalledValueEX(Object obj) throws IOException - { - super(obj); - } -} +/* + * JBoss, Home of Professional Open Source. + * Copyright 2008, Red Hat Middleware LLC, 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.invocation; + +import java.io.IOException; + +import org.jboss.remoting.serialization.IMarshalledValue; + +/** + * This is a way to have MarshalledValue implementing IMarshalledValue without + * changing legacy Invokers (Pooled, RMI) + * + * @author Clebert Suconic + */ +public class MarshalledValueEX extends MarshalledValue + implements IMarshalledValue +{ + private static final long serialVersionUID = -1527598981234110322L; + + public MarshalledValueEX() + { + super(); + } + + public MarshalledValueEX(Object obj) throws IOException + { + super(obj); + } +} Property changes on: org/jboss/invocation/MarshalledValueEX.java ___________________________________________________________________ Added: svn:eol-style + native Index: org/jboss/invocation/DataContainerMarshallingInvokerInterceptor.java =================================================================== --- org/jboss/invocation/DataContainerMarshallingInvokerInterceptor.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/invocation/DataContainerMarshallingInvokerInterceptor.java (.../trunk/server/src/main/java) (revision 97312) @@ -1,80 +1,80 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, Red Hat Middleware LLC, 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.invocation; - -import java.io.IOException; -import java.math.BigDecimal; -import java.math.BigInteger; - -import org.jboss.proxy.ClientContainer; -import org.jboss.remoting.serialization.IMarshalledValue; -import org.jboss.remoting.serialization.impl.jboss.LocalMarshalledValue; -import org.jboss.serial.objectmetamodel.safecloning.SafeClone; -import org.jboss.serial.objectmetamodel.safecloning.SafeCloningRepository; - - -/** - * This MarshallingInvokerInterceptor uses JbossSerialization DataContainer's doing a faster serialization over call-by-values than For Marshalling local call-by-values using JBossSerialization - * @author Clebert Suconic - * */ -public class DataContainerMarshallingInvokerInterceptor extends MarshallingInvokerInterceptor -{ - private static final long serialVersionUID = -1889397492156790576L; - - - /** These objects are safe to reuse in callByValue operations */ - static final SafeClone safeToReuse = new SafeClone(){ - public boolean isSafeToReuse(Object obj) { - if (obj==null) - { - return false; - } - - if (obj instanceof ClientContainer || - obj instanceof String || - obj instanceof Number || - obj instanceof BigDecimal || - obj instanceof BigInteger || - obj instanceof Byte || - obj instanceof Double || - obj instanceof Float || - obj instanceof Integer || - obj instanceof Long || - obj instanceof Short) - { - return true; - } - else - { - return false; - } - } - }; - - - protected IMarshalledValue createMarshalledValueForCallByValue(Object value) throws IOException - { - return new LocalMarshalledValue(value,new SafeCloningRepository(safeToReuse)); - - } - -} +/* + * JBoss, Home of Professional Open Source. + * Copyright 2006, Red Hat Middleware LLC, 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.invocation; + +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.jboss.proxy.ClientContainer; +import org.jboss.remoting.serialization.IMarshalledValue; +import org.jboss.remoting.serialization.impl.jboss.LocalMarshalledValue; +import org.jboss.serial.objectmetamodel.safecloning.SafeClone; +import org.jboss.serial.objectmetamodel.safecloning.SafeCloningRepository; + + +/** + * This MarshallingInvokerInterceptor uses JbossSerialization DataContainer's doing a faster serialization over call-by-values than For Marshalling local call-by-values using JBossSerialization + * @author Clebert Suconic + * */ +public class DataContainerMarshallingInvokerInterceptor extends MarshallingInvokerInterceptor +{ + private static final long serialVersionUID = -1889397492156790576L; + + + /** These objects are safe to reuse in callByValue operations */ + static final SafeClone safeToReuse = new SafeClone(){ + public boolean isSafeToReuse(Object obj) { + if (obj==null) + { + return false; + } + + if (obj instanceof ClientContainer || + obj instanceof String || + obj instanceof Number || + obj instanceof BigDecimal || + obj instanceof BigInteger || + obj instanceof Byte || + obj instanceof Double || + obj instanceof Float || + obj instanceof Integer || + obj instanceof Long || + obj instanceof Short) + { + return true; + } + else + { + return false; + } + } + }; + + + protected IMarshalledValue createMarshalledValueForCallByValue(Object value) throws IOException + { + return new LocalMarshalledValue(value,new SafeCloningRepository(safeToReuse)); + + } + +} Property changes on: org/jboss/invocation/DataContainerMarshallingInvokerInterceptor.java ___________________________________________________________________ Added: svn:eol-style + native Index: org/jboss/invocation/InvocationStatistics.java =================================================================== --- org/jboss/invocation/InvocationStatistics.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/invocation/InvocationStatistics.java (.../trunk/server/src/main/java) (revision 97312) @@ -41,7 +41,7 @@ private static final long serialVersionUID = -8031193044335393420L; /** A HashMap of the method invocations */ - private Map methodStats; + private Map methodStats; public long concurrentCalls = 0; public long maxConcurrentCalls = 0; @@ -52,7 +52,7 @@ { /** @since 4.2.0 */ private static final long serialVersionUID = -8689933338506854386L; - + public volatile long count; public volatile long minTime = Long.MAX_VALUE; public volatile long maxTime; @@ -80,7 +80,7 @@ */ public void updateStats(Method m, long elapsed) { - TimeStatistic stat = methodStats.get(m); + TimeStatistic stat = (TimeStatistic) methodStats.get(m); if (stat == null) { stat = new TimeStatistic(); @@ -147,10 +147,11 @@ tmp.append(concurrentCalls); tmp.append("' >\n"); - Iterator> iter = methodStats.entrySet().iterator(); + HashMap copy = new HashMap(methodStats); + Iterator iter = copy.entrySet().iterator(); while (iter.hasNext()) { - Map.Entry entry = iter.next(); + Map.Entry entry = (Map.Entry) iter.next(); TimeStatistic stat = (TimeStatistic) entry.getValue(); if (stat != null) { @@ -170,39 +171,4 @@ tmp.append(""); return tmp.toString(); } - - /** - * Converts the method invocation stats into a detyped nested map structure. - * The format is: - * - * {methodName => {statisticTypeName => longValue}} - * - * In addition some other global statistics are added under the fake - * method name #Global - * - * @return A map indexed by method name with map values indexed by statistic type - */ - public Map> toDetypedMap() - { - - Map> detyped = new HashMap>(); - for (Map.Entry entry : methodStats.entrySet()) - { - TimeStatistic stats = entry.getValue(); - Map detypedStats = new HashMap(methodStats.size()); - detypedStats.put("count", stats.count); - detypedStats.put("minTime", stats.minTime); - detypedStats.put("maxTime", stats.maxTime); - detypedStats.put("totalTime", stats.totalTime); - detyped.put(entry.getKey().getName(), detypedStats); - } - - Map global = new HashMap(); - global.put("concurrentCalls", concurrentCalls); - global.put("maxConcurrentCalls", maxConcurrentCalls); - global.put("lastResetTime", lastResetTime); - detyped.put("#Global", global); - - return detyped; - } } Index: org/jboss/invocation/ByValueInvokerInterceptor.java =================================================================== --- org/jboss/invocation/ByValueInvokerInterceptor.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/invocation/ByValueInvokerInterceptor.java (.../trunk/server/src/main/java) (revision 97312) @@ -1,101 +1,101 @@ -/* - * JBoss, Home of Professional Open Source. - * Copyright 2006, Red Hat Middleware LLC, 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.invocation; - -import java.io.Externalizable; -import java.io.IOException; -import java.io.ObjectInput; -import java.io.ObjectOutput; - -/** -* An InvokerInterceptor that does not optimize remote invocations.

-* -* This interceptor implements spec compliant behaviour.

-* -* @todo The performance could be improved by simulating marshalling -* for "local" remote, rather than going straight for the invoker -* -* @author Adrian Brock -* @version $Revision$ -*/ -public class ByValueInvokerInterceptor - extends InvokerInterceptor - implements Externalizable -{ - /** Serial Version Identifier. @since 1.1.4.1 */ - private static final long serialVersionUID = -6402069656713307195L; - - public ByValueInvokerInterceptor() - { - // For externalization to work - } - - // Public -------------------------------------------------------- - - /** - * Are you local? - */ - public boolean isLocal(Invocation invocation) - { - InvocationType type = invocation.getType(); - if (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME) - return true; - return false; - } - - /** - * Invoke using the invoker for remote invocations - */ - public Object invoke(Invocation invocation) - throws Exception - { - // local interface - if (isLocal(invocation)) - // The payload as is is good - return localInvoker.invoke(invocation); - else - // through the invoker - return invocation.getInvocationContext().getInvoker().invoke(invocation); - } - - /** - * Externalize this instance. - */ - public void writeExternal(final ObjectOutput out) - throws IOException - { - // We have no state - } - - /** - * Un-externalize this instance. - */ - public void readExternal(final ObjectInput in) - throws IOException, ClassNotFoundException - { - // We have no state - } - - // Private ------------------------------------------------------- - - // Inner classes ------------------------------------------------- -} +/* + * JBoss, Home of Professional Open Source. + * Copyright 2006, Red Hat Middleware LLC, 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.invocation; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +/** +* An InvokerInterceptor that does not optimize remote invocations.

+* +* This interceptor implements spec compliant behaviour.

+* +* @todo The performance could be improved by simulating marshalling +* for "local" remote, rather than going straight for the invoker +* +* @author Adrian Brock +* @version $Revision$ +*/ +public class ByValueInvokerInterceptor + extends InvokerInterceptor + implements Externalizable +{ + /** Serial Version Identifier. @since 1.1.4.1 */ + private static final long serialVersionUID = -6402069656713307195L; + + public ByValueInvokerInterceptor() + { + // For externalization to work + } + + // Public -------------------------------------------------------- + + /** + * Are you local? + */ + public boolean isLocal(Invocation invocation) + { + InvocationType type = invocation.getType(); + if (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME) + return true; + return false; + } + + /** + * Invoke using the invoker for remote invocations + */ + public Object invoke(Invocation invocation) + throws Exception + { + // local interface + if (isLocal(invocation)) + // The payload as is is good + return localInvoker.invoke(invocation); + else + // through the invoker + return invocation.getInvocationContext().getInvoker().invoke(invocation); + } + + /** + * Externalize this instance. + */ + public void writeExternal(final ObjectOutput out) + throws IOException + { + // We have no state + } + + /** + * Un-externalize this instance. + */ + public void readExternal(final ObjectInput in) + throws IOException, ClassNotFoundException + { + // We have no state + } + + // Private ------------------------------------------------------- + + // Inner classes ------------------------------------------------- +} Property changes on: org/jboss/invocation/ByValueInvokerInterceptor.java ___________________________________________________________________ Added: svn:eol-style + native Index: org/jboss/invocation/jrmp/server/JRMPInvoker.java =================================================================== --- org/jboss/invocation/jrmp/server/JRMPInvoker.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/invocation/jrmp/server/JRMPInvoker.java (.../trunk/server/src/main/java) (revision 97312) @@ -439,7 +439,6 @@ finally { TCLAction.UTIL.setContextClassLoader(oldCl); - Thread.interrupted(); // clear interruption because this thread may be pooled. } } Index: org/jboss/verifier/strategy/EJBVerifier21.java =================================================================== --- org/jboss/verifier/strategy/EJBVerifier21.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/verifier/strategy/EJBVerifier21.java (.../trunk/server/src/main/java) (revision 97312) @@ -2520,7 +2520,7 @@ // String messagingType = mdBean.getMessagingType(); if(messagingType == null) - messagingType = javax.jms.MessageListener.class.getName(); + messagingType = javax.jms.MessageListener.class.getName(); if (!isAssignableFrom(messagingType, bean)) { fireSpecViolationEvent(mdBean, new Section("15.7.2.b")); Index: org/jboss/web/WebServiceMBean.java =================================================================== --- org/jboss/web/WebServiceMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/web/WebServiceMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -23,13 +23,12 @@ import java.net.URL; import java.net.UnknownHostException; - -import javax.management.ObjectName; - +import java.util.concurrent.Executor; import org.jboss.mx.util.ObjectNameFactory; import org.jboss.system.ServiceMBean; -import org.jboss.util.threadpool.BasicThreadPoolMBean; +import javax.management.ObjectName; + /** * WebService MBean interface * @@ -68,7 +67,7 @@ boolean getDownloadResources(); /** The thread pool used for the WebServer class loading. */ - void setThreadPool(BasicThreadPoolMBean threadPool); + void setExecutor(Executor executor); /** The RMI codebase URL. */ String getCodebase(); @@ -78,5 +77,4 @@ URL addClassLoader(ClassLoader cl); void removeClassLoader(ClassLoader cl); - } Index: org/jboss/web/WebPermissionMapping.java =================================================================== --- org/jboss/web/WebPermissionMapping.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/web/WebPermissionMapping.java (.../trunk/server/src/main/java) (revision 97312) @@ -86,7 +86,7 @@ HashMap patternMap = qualifyURLPatterns(metaData); log.debug("Qualified url patterns: "+patternMap); - List constraints = metaData.getSecurityContraints(); + List constraints = metaData.getSecurityConstraints(); if(constraints != null) { for(SecurityConstraintMetaData sc : constraints) @@ -435,7 +435,7 @@ HashMap patternMap = new HashMap(); PatternInfo defaultInfo = null; - List constraints = metaData.getSecurityContraints(); + List constraints = metaData.getSecurityConstraints(); if(constraints != null) { for(SecurityConstraintMetaData sc : constraints) Index: org/jboss/web/WebServer.java =================================================================== --- org/jboss/web/WebServer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/web/WebServer.java (.../trunk/server/src/main/java) (revision 97312) @@ -21,6 +21,7 @@ */ package org.jboss.web; +import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; @@ -34,13 +35,9 @@ import java.net.Socket; import java.net.URL; import java.util.Properties; - +import java.util.concurrent.Executor; import org.jboss.logging.Logger; -import org.jboss.util.threadpool.BasicThreadPool; -import org.jboss.util.threadpool.BasicThreadPoolMBean; -import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap; - /** * A mini webserver that should be embedded in another application. It can * server any file that is available from classloaders that are registered with @@ -113,7 +110,7 @@ /** * The thread pool used to manage listening threads */ - private BasicThreadPoolMBean threadPool; + private Executor executor; // Public -------------------------------------------------------- @@ -193,14 +190,14 @@ downloadResources = flag; } - public BasicThreadPoolMBean getThreadPool() + public Executor getThreadPool() { - return threadPool; + return executor; } - public void setThreadPool(BasicThreadPoolMBean threadPool) + public void setThreadPool(Executor executor) { - this.threadPool = threadPool; + this.executor = executor; } /** @@ -218,8 +215,8 @@ */ public void start() throws Exception { - if (threadPool == null) - threadPool = new BasicThreadPool("ClassLoadingPool"); + if (executor == null) + throw new IllegalArgumentException("Required property 'executor' not specified"); try { @@ -492,7 +489,7 @@ protected void listen() { - threadPool.getInstance().run(this); + executor.execute(this); } /** Index: org/jboss/web/deployers/HandlesTypesClassFilter.java =================================================================== --- org/jboss/web/deployers/HandlesTypesClassFilter.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 0) +++ org/jboss/web/deployers/HandlesTypesClassFilter.java (.../trunk/server/src/main/java) (revision 97312) @@ -0,0 +1,190 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2007, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt 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.web.deployers; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.servlet.ServletContainerInitializer; + +import org.jboss.deployers.structure.spi.DeploymentUnit; +import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit; +import org.jboss.logging.Logger; +import org.jboss.virtual.VirtualFile; +import org.jboss.virtual.VirtualFileFilter; +import org.jboss.virtual.VirtualFileVisitor; +import org.jboss.virtual.VisitorAttributes; + +/** + * A VirtualFileVisitor that traverses unit root and determines the + * class files that extend, implement, or are annotated by HandlesTypes. + * + * @author Scott.Stark@jboss.org + * @author Remy Maucherat + * @version $Revision: 82920 $ + */ +public class HandlesTypesClassFilter implements VirtualFileVisitor +{ + private static Logger log = Logger.getLogger(HandlesTypesClassFilter.class); + private ClassLoader loader; + private int rootLength; + private HashSet childPaths = new HashSet(); + private Map>> handlesTypes; + private Class[] typesArray; + private Map, Set> typesMap; + + public HandlesTypesClassFilter(VFSDeploymentUnit unit, ClassLoader loader, + VirtualFile classpathRoot, Class[] typesArray, Map, Set> typesMap, + Map>> handlesTypes) + { + this.loader = loader; + this.handlesTypes = handlesTypes; + this.typesArray = typesArray; + this.typesMap = typesMap; + + // Work out the root length. If there is a root, we need to add one to jump across the next / + String rootName = classpathRoot.getPathName(); + rootLength = rootName.length(); + if (rootLength > 0) + rootLength += 1; + List children = unit.getChildren(); + if(children != null) + { + for(DeploymentUnit cu : children) + { + String path = cu.getName(); + childPaths.add(path); + } + } + } + + public VisitorAttributes getAttributes() + { + VisitorAttributes attributes = new VisitorAttributes(); + attributes.setIncludeRoot(true); + attributes.setRecurseFilter(new NoChildFilter()); + return attributes; + } + + public void visit(VirtualFile file) + { + try + { + if(file.isLeaf()) + { + accepts(file); + } + } + catch (IOException e) + { + throw new Error("Error visiting " + file, e); + } + } + + @SuppressWarnings("unchecked") + public boolean accepts(VirtualFile file) + { + boolean accepts = file.getPathName().endsWith(".class"); + if(accepts) + { + accepts = false; + String className = null; + try + { + className = getClassName(file); + Class c = loader.loadClass(className); + for (Class clazz : typesArray) + { + if ((clazz.isAnnotation() && c.isAnnotationPresent((Class) clazz)) + || clazz.isAssignableFrom(c)) + { + Set sciSet = typesMap.get(clazz); + for (ServletContainerInitializer sci : sciSet) + { + handlesTypes.get(sci).add(c); + } + } + } + } + catch(NoClassDefFoundError ignored) + { + log.debug("Incomplete class: "+className+", NCDFE: "+ignored); + } + catch(Exception ignored) + { + if(log.isTraceEnabled()) + log.trace("Failed to load class: "+className, ignored); + } + } + return accepts; + } + + protected String getFilePath(VirtualFile file) + { + String path = null; + try + { + path = file.toURI().toString(); + } + catch(Exception e) + { + } + return path; + } + + /** + * Search the classpaths for the root of this file. + * + * @param classFile the class file + * @return fqn class name + * @throws IOException for any error + */ + protected String getClassName(VirtualFile classFile) throws IOException + { + String pathName = classFile.getPathName(); + String name = pathName.substring(rootLength, pathName.length()-6); + name = name.replace('/', '.'); + return name; + } + + class NoChildFilter implements VirtualFileFilter + { + public boolean accepts(VirtualFile file) + { + String path = getFilePath(file); + boolean accepts = false; + try + { + accepts = file.isLeaf() == false && childPaths.contains(path) == false; + } + catch(Exception e) + { + } + return accepts; + } + + } +} Index: org/jboss/web/deployers/ServletContainerInitializerDeployer.java =================================================================== --- org/jboss/web/deployers/ServletContainerInitializerDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 0) +++ org/jboss/web/deployers/ServletContainerInitializerDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -0,0 +1,246 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2009, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt 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.web.deployers; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.Set; + +import javax.servlet.ServletContainerInitializer; +import javax.servlet.annotation.HandlesTypes; + +import org.jboss.deployers.spi.DeploymentException; +import org.jboss.deployers.spi.deployer.DeploymentStages; +import org.jboss.deployers.spi.deployer.helpers.AbstractDeployer; +import org.jboss.deployers.structure.spi.DeploymentUnit; +import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit; +import org.jboss.metadata.web.jboss.JBossWebMetaData; +import org.jboss.metadata.web.spec.WebMetaData; +import org.jboss.virtual.VFS; +import org.jboss.virtual.VirtualFile; + +/** + * A deployer that processes ServletContainerInitializer. + * + * @author Remy Maucherat + * @version $Revision: 93820 $ + */ +public class ServletContainerInitializerDeployer extends AbstractDeployer +{ + public static final String SCI_ATTACHMENT_NAME = "sci."+WebMetaData.class.getName(); + public static final String SCI_HANDLESTYPES_ATTACHMENT_NAME = "sci.handlestypes."+WebMetaData.class.getName(); + + private List sciJars = null; + + public List getSciJars() + { + return sciJars; + } + + public void setSciJars(List sciJars) + { + this.sciJars = sciJars; + } + + /** + * Create the SCI information. + */ + public ServletContainerInitializerDeployer() + { + setStage(DeploymentStages.POST_CLASSLOADER); + setInput(JBossWebMetaData.class); + addInput(MergedJBossWebMetaDataDeployer.WEB_ORDER_ATTACHMENT_NAME); + addInput(MergedJBossWebMetaDataDeployer.WEB_SCIS_ATTACHMENT_NAME); + addOutput(SCI_ATTACHMENT_NAME); + addOutput(SCI_HANDLESTYPES_ATTACHMENT_NAME); + } + + @SuppressWarnings("unchecked") + public void deploy(DeploymentUnit unit) throws DeploymentException + { + if (!unit.getSimpleName().endsWith(".war")) + { + return; + } + Set scis = new HashSet(); + // Load the shared ServletContainerInitializer services + if (sciJars == null) + { + ServiceLoader serviceLoader = + ServiceLoader.load(ServletContainerInitializer.class, this.getClass().getClassLoader()); + for (ServletContainerInitializer service : serviceLoader) + { + scis.add(service); + } + } + else + { + for (URL jarURL : sciJars) + { + try + { + VFS vfs = VFS.getVFS(jarURL); + VirtualFile sci = vfs.getChild("META-INF/services/javax.servlet.ServletContainerInitializer"); + if (sci != null) + { + ServletContainerInitializer service = loadSci(unit, sci, jarURL.getPath(), false); + if (service != null) + { + scis.add(service); + } + } + } + catch (IOException e) + { + DeploymentException.rethrowAsDeploymentException("Deployment error processing SCI for JAR: " + jarURL, e); + } + } + } + // Find local ServletContainerInitializer services + List order = + (List) unit.getAttachment(MergedJBossWebMetaDataDeployer.WEB_ORDER_ATTACHMENT_NAME); + Map localScis = (Map) + unit.getAttachment(MergedJBossWebMetaDataDeployer.WEB_SCIS_ATTACHMENT_NAME); + if (order != null && localScis != null) + { + for (String jar : order) + { + VirtualFile sci = localScis.get(jar); + if (sci != null) + { + ServletContainerInitializer service = loadSci(unit, sci, jar, true); + if (service != null) + { + scis.add(service); + } + } + } + } + // Process HandlesTypes for ServletContainerInitializer + Map, Set> typesMap = + new HashMap, Set>(); + Map>> handlesTypes = + new HashMap>>(); + for (ServletContainerInitializer service : scis) + { + if (service.getClass().isAnnotationPresent(HandlesTypes.class)) + { + HandlesTypes handlesTypesAnnotation = service.getClass().getAnnotation(HandlesTypes.class); + Class[] typesArray = handlesTypesAnnotation.value(); + if (typesArray != null) + { + for (Class type : typesArray) + { + Set servicesSet = typesMap.get(type); + if (servicesSet == null) + { + servicesSet = new HashSet(); + typesMap.put(type, servicesSet); + } + servicesSet.add(service); + handlesTypes.put(service, new HashSet>()); + } + } + } + } + + Class[] typesArray = typesMap.keySet().toArray(new Class[0]); + // Find classes which extend, implement, or are annotated by HandlesTypes + if (typesArray.length > 0 && unit instanceof VFSDeploymentUnit) + { + VFSDeploymentUnit vfsUnit = (VFSDeploymentUnit) unit; + List classpath = vfsUnit.getClassPath(); + try + { + for (VirtualFile classpathItem : classpath) + { + HandlesTypesClassFilter classVisitor = new HandlesTypesClassFilter(vfsUnit, unit.getClassLoader(), + classpathItem, typesArray, typesMap, handlesTypes); + classpathItem.visit(classVisitor); + } + } + catch (Exception e) + { + DeploymentException.rethrowAsDeploymentException("Deployment error scanning HandlesTypes", e); + } + } + + unit.addAttachment(SCI_ATTACHMENT_NAME, scis); + unit.addAttachment(SCI_HANDLESTYPES_ATTACHMENT_NAME, handlesTypes); + } + + + private ServletContainerInitializer loadSci(DeploymentUnit unit, VirtualFile sci, String jar, boolean error) + throws DeploymentException + { + ServletContainerInitializer service = null; + InputStream is = null; + try + { + // Get the ServletContainerInitializer class name + is = sci.openStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + String servletContainerInitializerClassName = reader.readLine(); + int pos = servletContainerInitializerClassName.indexOf('#'); + if (pos > 0) { + servletContainerInitializerClassName = servletContainerInitializerClassName.substring(0, pos); + } + servletContainerInitializerClassName = servletContainerInitializerClassName.trim(); + // Instantiate the ServletContainerInitializer + service = (ServletContainerInitializer) unit.getClassLoader() + .loadClass(servletContainerInitializerClassName).newInstance(); + } + catch (Exception e) + { + if (error) + { + DeploymentException.rethrowAsDeploymentException("Deployment error processing SCI for JAR: " + jar, e); + } + else + { + log.info("Skipped SCI for JAR: " + jar, e); + } + } + finally + { + try + { + if (is != null) + is.close(); + } + catch (IOException e) + { + ; + } + } + return service; + } + +} Index: org/jboss/web/deployers/AbstractWarDeployer.java =================================================================== --- org/jboss/web/deployers/AbstractWarDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/web/deployers/AbstractWarDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -67,13 +67,14 @@ import org.jboss.system.metadata.ServiceInjectionValueMetaData; import org.jboss.system.metadata.ServiceMetaData; import org.jboss.util.file.Files; +import org.jboss.virtual.VFS; import org.jboss.virtual.VFSUtils; import org.jboss.virtual.VirtualFile; import org.jboss.web.WebApplication; /** A template pattern class for web container integration into JBoss. This class * should be subclassed by web container providers wishing to integrate their - * container into a JBoss server. The sole method to implement is: + * container into a JBoss server. The sole method to implement is: * {@link #getDeployment(DeploymentUnit, WebMetaData)}. This is called from * within {@linkplain #deploy(DeploymentUnit, WebMetaData)} to translate the * WebMetaData into a AbstractWarDeployment bean that will be passed to the @@ -92,6 +93,7 @@ * @author Christoph.Jung@infor.de * @author Thomas.Diesler@arcor.de * @author adrian@jboss.org + * @author ales.justin@jboss.org * @version $Revision$ */ public abstract class AbstractWarDeployer extends AbstractSimpleRealDeployer @@ -108,7 +110,8 @@ protected boolean java2ClassLoadingCompliance = false; /** A flag indicating if war archives should be unpacked */ protected boolean unpackWars = true; - /** A flag indicating if local dirs with WEB-INF/web.xml should be treated as wars */ + /** A flag indicating if local dirs with WEB-INF/web.xml should be treated as wars + */ protected boolean acceptNonWarDirs = false; /** If true, ejb-links that don't resolve don't cause an error (fallback to jndi-name) */ @@ -157,7 +160,7 @@ /** Set the flag indicating if war archives should be unpacked. This may * need to be set to false as long extraction paths under deploy can * show up as deployment failures on some platforms. - * + * * @jmx:managed-attribute * @return true is war archives should be unpacked */ @@ -169,7 +172,7 @@ /** Get the flag indicating if war archives should be unpacked. This may * need to be set to false as long extraction paths under deploy can * show up as deployment failures on some platforms. - * + * * @jmx:managed-attribute * @param flag , true is war archives should be unpacked */ @@ -203,8 +206,8 @@ /** * Get the flag indicating if ejb-link errors should be ignored * in favour of trying the jndi-name in jboss-web.xml - * @return the LenientEjbLink flag - * + * @return the LenientEjbLink flag + * * @jmx:managed-attribute */ public boolean getLenientEjbLink() @@ -215,7 +218,7 @@ /** * Set the flag indicating if ejb-link errors should be ignored * in favour of trying the jndi-name in jboss-web.xml - * + * * @jmx:managed-attribute */ public void setLenientEjbLink(boolean flag) @@ -284,7 +287,7 @@ * override this method to provide a AbstractWarDeployment bean whose * start/stop will control the deployment/undeployment of the web * application. - * + * * @param unit - the deployment unit * @param metaData - the input web application metadata * @return the AbstractWarDeployment for the input WebMetaData @@ -297,13 +300,13 @@ * {@link #getDeployment(DeploymentUnit, WebMetaData)} to obtain an * AbstractWarDeployment bean that is wrapped in a ServiceMetaData by * deployWebModule. - * + * * This will set the WebMetaData.contextRoot if it has not been set based * on the war deployment name. - * + * * @see #deployWebModule(DeploymentUnit, WebMetaData, AbstractWarDeployment) * @see #buildWebContext(DeploymentUnit, String, String, WebMetaData) - * + * * @param unit - the war for the deployment * @param metaData - the metadata for the deployment */ @@ -342,11 +345,15 @@ try { - /* Unpack wars to the tmp directory for now until tomcat can use the vfs directly. */ + /* Unpack wars to the tmp directory for now until tomcat can use the vfs directly. Since + * the vfs deals with the distinction between a true directory, the only way we can tell from + * this level of the api is to look for a url that ends in '/'. Here we assume that the name is + * the root url. + */ String warName = unit.getName(); /** - * Ignore the jacc policy service bean + * Ignore the jacc policy service bean */ if (warName.startsWith("jboss:") && warName.contains("id=")) return; @@ -398,13 +405,11 @@ // Indicate that an expanded URL exists unit.addAttachment("org.jboss.web.expandedWarURL", expWarUrl, URL.class); - // add exploded VirtualFile directly - unit.addAttachment("org.jboss.web.expandedWarFile", unjared, VirtualFile.class); } else { - expWarUrl = VFSUtils.getRealURL(root); - } + expWarUrl = VFSUtils.getRealURL(root); + } // Resolve any ear relative alt-dd path to an expWarUrl/WEB-INF/alt-dd.xml file String altDDPath = metaData.getAlternativeDD(); @@ -437,13 +442,11 @@ ClassLoadingMetaData classLoading = metaData.getClassLoading(); if (classLoading == null) - { classLoading = new ClassLoadingMetaData(); - metaData.setClassLoading(classLoading); - } // pass in the java2ClassLoadingCompliance if it was not set at the war level if (classLoading.wasJava2ClassLoadingComplianceSet() == false) - classLoading.setJava2ClassLoadingCompliance(java2ClassLoadingCompliance); + classLoading.setJava2ClassLoadingCompliance(this.java2ClassLoadingCompliance); + metaData.setClassLoading(classLoading); // Build the context root if its not been set or is specified at the ear String webContext = metaData.getContextRoot(); @@ -471,10 +474,12 @@ try { // Delete any expanded war - VirtualFile warFile = unit.getAttachment("org.jboss.web.expandedWarFile", VirtualFile.class); - if (warFile != null) + URL warURL = unit.getAttachment("org.jboss.web.expandedWarURL", URL.class); + if (warURL != null) { - warFile.cleanup(); // it's temp, it will be deleted as well + // use vfs to cleanup/delete - since we created it with vfs + VirtualFile file = VFS.getRoot(warURL); + file.cleanup(); // it's temp, it will be deleted as well } } catch (Exception e) @@ -557,7 +562,7 @@ A war name of ROOT.war is handled as a special case of a war that should be installed as the default web context. @param ctxPath - war level context-root - @param warName - + @param warName - */ protected String buildWebContext(String ctxPath, String warName, JBossWebMetaData metaData, DeploymentUnit unit) { @@ -648,7 +653,7 @@ * AbstractWarDeployment bean and then attach it to the deployment unit. The * presence of the ServiceMetaData attachment makes the deployment unit * "relevant" to the deployers that handle mbean services. - * + * * @param unit - the deployment unit * @param metaData - the web app metadata passed to deploy * @param deployment - the web app deployment bean created by getDeployment @@ -722,7 +727,7 @@ throw DeploymentException.rethrowAsDeploymentException("Error creating rar deployment " + unit.getName(), e); } } - + @ManagementObject(name = "ContextMO", componentType = @ManagementComponent(type = "WAR", subtype="Context")) public static class ContextMO { Index: org/jboss/web/deployers/WebModule.java =================================================================== --- org/jboss/web/deployers/WebModule.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/web/deployers/WebModule.java (.../trunk/server/src/main/java) (revision 97312) @@ -21,8 +21,8 @@ */ package org.jboss.web.deployers; -import org.jboss.deployers.structure.spi.DeploymentUnit; -import org.jboss.deployment.DeploymentException; +import org.jboss.deployers.spi.DeploymentException; +import org.jboss.deployers.structure.spi.DeploymentUnit; import org.jboss.kernel.Kernel; import org.jboss.logging.Logger; import org.jboss.metadata.web.jboss.JBossWebMetaData; @@ -53,8 +53,6 @@ private AbstractWarDeployer container; private AbstractWarDeployment deployment; - private ISecurityManagement securityManagement; - public WebModule(DeploymentUnit unit, AbstractWarDeployer container, AbstractWarDeployment deployment) { this.unit = unit; Index: org/jboss/web/deployers/MergedJBossWebMetaDataDeployer.java =================================================================== --- org/jboss/web/deployers/MergedJBossWebMetaDataDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/web/deployers/MergedJBossWebMetaDataDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -1,6 +1,6 @@ /* * JBoss, Home of Professional Open Source - * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * Copyright 2009, Red Hat Middleware LLC, and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * @@ -21,17 +21,34 @@ */ package org.jboss.web.deployers; +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + import org.jboss.deployers.spi.DeploymentException; import org.jboss.deployers.spi.deployer.DeploymentStages; import org.jboss.deployers.spi.deployer.helpers.AbstractDeployer; import org.jboss.deployers.structure.spi.DeploymentUnit; +import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit; import org.jboss.deployment.AnnotationMetaDataDeployer; import org.jboss.metadata.ear.jboss.JBossAppMetaData; -import org.jboss.metadata.web.spec.AnnotationMergedView; +import org.jboss.metadata.javaee.spec.SecurityRolesMetaData; import org.jboss.metadata.web.jboss.JBossWebMetaData; +import org.jboss.metadata.web.spec.AbsoluteOrderingMetaData; +import org.jboss.metadata.web.spec.OrderingElementMetaData; import org.jboss.metadata.web.spec.Web25MetaData; +import org.jboss.metadata.web.spec.Web30MetaData; +import org.jboss.metadata.web.spec.WebCommonMetaData; +import org.jboss.metadata.web.spec.WebFragmentMetaData; import org.jboss.metadata.web.spec.WebMetaData; -import org.jboss.metadata.javaee.spec.SecurityRolesMetaData; +import org.jboss.virtual.VirtualFile; /** * A deployer that merges annotation metadata, xml metadata, and jboss metadata @@ -44,8 +61,21 @@ */ public class MergedJBossWebMetaDataDeployer extends AbstractDeployer { - public static final String WEB_MERGED_ATTACHMENT_NAME = "merged."+JBossWebMetaData.class.getName(); + public static final String WEB_ORDER_ATTACHMENT_NAME = "order."+WebMetaData.class.getName(); + public static final String WEB_OVERLAYS_ATTACHMENT_NAME = "overlays."+WebMetaData.class.getName(); + public static final String WEB_SCIS_ATTACHMENT_NAME = "localscis."+WebMetaData.class.getName(); + private boolean metaDataCompleteIsDefault = false; + + public boolean isMetaDataCompleteIsDefault() + { + return metaDataCompleteIsDefault; + } + public void setMetaDataCompleteIsDefault(boolean metaDataCompleteIsDefault) + { + this.metaDataCompleteIsDefault = metaDataCompleteIsDefault; + } + /** * Create a new MergedJBossWebMetaDataDeployer. */ @@ -60,8 +90,10 @@ addInput(AnnotationMetaDataDeployer.WEB_ANNOTATED_ATTACHMENT_NAME); // Output is the merge JBossWebMetaData view setOutput(JBossWebMetaData.class); - // - addOutput(WEB_MERGED_ATTACHMENT_NAME); + // Additional Webapp components + addOutput(WEB_ORDER_ATTACHMENT_NAME); + addOutput(WEB_OVERLAYS_ATTACHMENT_NAME); + addOutput(WEB_SCIS_ATTACHMENT_NAME); } public void deploy(DeploymentUnit unit) throws DeploymentException @@ -71,22 +103,337 @@ if(specMetaData == null && metaData == null) return; - // Check for an annotated view - String key = AnnotationMetaDataDeployer.WEB_ANNOTATED_ATTACHMENT_NAME; - Web25MetaData annotatedMetaData = unit.getAttachment(key, Web25MetaData.class); - if(annotatedMetaData != null) + // Check metadata-complete (see AnnotationMetaDataDeployer) + boolean isComplete = this.isMetaDataCompleteIsDefault(); + if(specMetaData != null) { - if(specMetaData != null) + if (specMetaData instanceof Web25MetaData) { - Web25MetaData specMerged = new Web25MetaData(); - // TODO: JBMETA-7 - AnnotationMergedView.merge(specMerged, specMetaData, annotatedMetaData); - specMetaData = specMerged; + isComplete |= ((Web25MetaData)specMetaData).isMetadataComplete(); } + else if (specMetaData instanceof Web30MetaData) + { + isComplete |= ((Web30MetaData)specMetaData).isMetadataComplete(); + } else - specMetaData = annotatedMetaData; + { + // Any web.xml 2.4 or earlier deployment is metadata complete + isComplete = true; + } } + // Find all fragments that have been processed by deployers, and place them in a map keyed by location + LinkedList order = new LinkedList(); + List orderings = new ArrayList(); + HashSet jarsSet = new HashSet(); + Set overlays = new HashSet(); + Map scis = new HashMap(); + VirtualFile webInfLib = null; + boolean fragmentFound = false; + HashMap webFragments = new HashMap(); + if (unit instanceof VFSDeploymentUnit) + { + VFSDeploymentUnit vfsUnit = (VFSDeploymentUnit) unit; + webInfLib = vfsUnit.getFile("WEB-INF/lib"); + if (webInfLib != null) + { + try + { + List jars = webInfLib.getChildren(); + for (VirtualFile jar : jars) + { + jarsSet.add(jar.getName()); + // Find overlays + VirtualFile overlay = jar.getChild("META-INF/resources"); + if (overlay != null) + { + overlays.add(overlay); + } + // Find ServletContainerInitializer services + VirtualFile sci = jar.getChild("META-INF/services/javax.servlet.ServletContainerInitializer"); + if (sci != null) + { + scis.put(jar.getName(), sci); + } + } + } + catch (IOException e) + { + } + } + + if (!isComplete) + { + + String base = unit.getName(); + int pos = base.indexOf(':'); + if (pos > 0) + { + base = base.substring(pos); + } + + Iterator attachementNames = unit.getAttachments().keySet().iterator(); + HashSet jarsWithoutFragmentsSet = new HashSet(); + jarsWithoutFragmentsSet.addAll(jarsSet); + while (attachementNames.hasNext()) + { + String location = attachementNames.next(); + Object attachement = unit.getAttachment(location); + if (attachement != null && attachement instanceof WebFragmentMetaData) + { + pos = location.indexOf(':'); + if (pos > 0) + { + location = location.substring(pos); + } + if (!location.startsWith(base)) + { + // If there is only one fragment, it will also get mapped as this attachement + continue; + } + String relativeLocation = "/" + location.substring(base.length()); + String jarName = null; + if (relativeLocation.startsWith("/WEB-INF/lib/")) + { + jarName = relativeLocation.substring("/WEB-INF/lib/".length()); + pos = jarName.indexOf('/'); + if (pos > 0) + jarName = jarName.substring(0, pos); + } + if (jarName == null) + { + continue; + } + fragmentFound = true; + WebFragmentMetaData fragmentMetaData = (WebFragmentMetaData) attachement; + webFragments.put(jarName, fragmentMetaData); + WebOrdering webOrdering = new WebOrdering(); + webOrdering.setName(fragmentMetaData.getName()); + webOrdering.setJar(jarName); + jarsWithoutFragmentsSet.remove(jarName); + if (fragmentMetaData.getOrdering() != null) + { + if (fragmentMetaData.getOrdering().getAfter() != null) + { + for (OrderingElementMetaData orderingElementMetaData : + fragmentMetaData.getOrdering().getAfter().getOrdering()) + { + if (orderingElementMetaData.isOthers()) + { + webOrdering.setAfterOthers(true); + } + else + { + webOrdering.addAfter(orderingElementMetaData.getName()); + } + } + } + if (fragmentMetaData.getOrdering().getBefore() != null) + { + for (OrderingElementMetaData orderingElementMetaData : + fragmentMetaData.getOrdering().getBefore().getOrdering()) + { + if (orderingElementMetaData.isOthers()) + { + webOrdering.setBeforeOthers(true); + } + else + { + webOrdering.addBefore(orderingElementMetaData.getName()); + } + } + } + } + orderings.add(webOrdering); + } + } + // If there is no fragment, still consider it for ordering as a + // fragment specifying no name and no order + for (String jarName : jarsWithoutFragmentsSet) + { + WebOrdering ordering = new WebOrdering(); + ordering.setJar(jarName); + orderings.add(ordering); + } + + } + } + + if (!fragmentFound) + { + // Drop the order as there is no fragment in the webapp + orderings.clear(); + } + + // Generate web fragments parsing order + AbsoluteOrderingMetaData absoluteOrderingMetaData = null; + if (!isComplete && specMetaData instanceof Web30MetaData) + { + absoluteOrderingMetaData = ((Web30MetaData) specMetaData).getAbsoluteOrdering(); + } + if (absoluteOrderingMetaData != null) { + // Absolute ordering from web.xml, any relative fragment ordering is ignored + int otherPos = -1; + int i = 0; + for (OrderingElementMetaData orderingElementMetaData : absoluteOrderingMetaData.getOrdering()) + { + if (orderingElementMetaData.isOthers()) + { + if (otherPos >= 0) { + throw new DeploymentException("Duplicate others in absolute ordering"); + } + otherPos = i; + } + else + { + boolean found = false; + for (WebOrdering ordering : orderings) + { + if (orderingElementMetaData.getName().equals(ordering.getName())) { + order.add(ordering.getJar()); + jarsSet.remove(ordering.getJar()); + found = true; + break; + } + } + if (!found) + throw new DeploymentException("Could not resolve name in absolute ordering: " + orderingElementMetaData.getName()); + } + i++; + } + if (otherPos >= 0) + { + order.addAll(otherPos, jarsSet); + jarsSet.clear(); + } + } + else if (orderings.size() > 0) + { + // Resolve relative ordering + try + { + resolveOrder(orderings, order); + } + catch (IllegalStateException e) + { + DeploymentException.rethrowAsDeploymentException("Invalid ordering", e); + } + jarsSet.clear(); + } + else + { + // No order specified + order.addAll(jarsSet); + jarsSet.clear(); + } + + if (log.isDebugEnabled()) + { + StringBuilder builder = new StringBuilder(); + builder.append("Resolved order: [ "); + for (String jar : order) + { + builder.append(jar).append(' '); + } + builder.append(']'); + log.debug(builder.toString()); + } + + unit.addAttachment(WEB_ORDER_ATTACHMENT_NAME, order); + unit.addAttachment(WEB_OVERLAYS_ATTACHMENT_NAME, overlays); + unit.addAttachment(WEB_SCIS_ATTACHMENT_NAME, scis); + + // The fragments and corresponding annotations will need to be merged in order + // For each JAR in the order: + // - Merge the annotation metadata into the fragment meta data + // (unless the fragment exists and is meta data complete) + // - Merge the fragment metadata into merged fragment meta data + WebCommonMetaData mergedFragmentMetaData = new WebCommonMetaData(); + if (specMetaData == null) + specMetaData = new WebMetaData(); + String key = AnnotationMetaDataDeployer.WEB_ANNOTATED_ATTACHMENT_NAME + ":classes"; + // Augment with meta data from annotations in /WEB-INF/classes + WebMetaData classesAnnotatedMetaData = unit.getAttachment(key, WebMetaData.class); + if (classesAnnotatedMetaData != null) + { + if (isComplete) + { + // Discard @WebFilter, @WebListener and @WebServlet + classesAnnotatedMetaData.setFilters(null); + classesAnnotatedMetaData.setFilterMappings(null); + classesAnnotatedMetaData.setListeners(null); + classesAnnotatedMetaData.setServlets(null); + classesAnnotatedMetaData.setServletMappings(null); + } + specMetaData.augment(classesAnnotatedMetaData, null, true); + } + // Augment with meta data from fragments and annotations from the corresponding JAR + for (String jar : order) + { + WebFragmentMetaData webFragmentMetaData = webFragments.get(jar); + if (webFragmentMetaData == null) + { + webFragmentMetaData = new WebFragmentMetaData(); + } + key = AnnotationMetaDataDeployer.WEB_ANNOTATED_ATTACHMENT_NAME + ":" + jar; + WebMetaData jarAnnotatedMetaData = unit.getAttachment(key, WebMetaData.class); + if ((isComplete || webFragmentMetaData.isMetadataComplete()) && jarAnnotatedMetaData != null) + { + // Discard @WebFilter, @WebListener and @WebServlet + jarAnnotatedMetaData.setFilters(null); + jarAnnotatedMetaData.setFilterMappings(null); + jarAnnotatedMetaData.setListeners(null); + jarAnnotatedMetaData.setServlets(null); + jarAnnotatedMetaData.setServletMappings(null); + } + if (jarAnnotatedMetaData != null) + { + // Merge annotations corresponding to the JAR + webFragmentMetaData.augment(jarAnnotatedMetaData, null, true); + } + // Merge fragment meta data according to the conflict rules + try + { + mergedFragmentMetaData.augment(webFragmentMetaData, specMetaData, false); + } + catch (Exception e) + { + DeploymentException.rethrowAsDeploymentException("Deployment error processing fragment for JAR: " + jar, e); + } + } + // Augment with meta data from annotations from JARs excluded from the order + for (String jar : jarsSet) + { + WebFragmentMetaData webFragmentMetaData = new WebFragmentMetaData(); + key = AnnotationMetaDataDeployer.WEB_ANNOTATED_ATTACHMENT_NAME + ":" + jar; + WebMetaData jarAnnotatedMetaData = unit.getAttachment(key, WebMetaData.class); + if (jarAnnotatedMetaData != null) + { + // Discard @WebFilter, @WebListener and @WebServlet + jarAnnotatedMetaData.setFilters(null); + jarAnnotatedMetaData.setFilterMappings(null); + jarAnnotatedMetaData.setListeners(null); + jarAnnotatedMetaData.setServlets(null); + jarAnnotatedMetaData.setServletMappings(null); + } + if (jarAnnotatedMetaData != null) + { + // Merge annotations corresponding to the JAR + webFragmentMetaData.augment(jarAnnotatedMetaData, null, true); + } + // Merge fragment meta data according to the conflict rules + try + { + mergedFragmentMetaData.augment(webFragmentMetaData, specMetaData, false); + } + catch (Exception e) + { + DeploymentException.rethrowAsDeploymentException("Deployment error processing fragment for JAR: " + jar, e); + } + } + specMetaData.augment(mergedFragmentMetaData, null, true); + + // Override with meta data (JBossWebMetaData) // Create a merged view JBossWebMetaData mergedMetaData = new JBossWebMetaData(); mergedMetaData.merge(metaData, specMetaData); @@ -120,4 +467,354 @@ unit.getTransientManagedObjects().addAttachment(JBossWebMetaData.class, mergedMetaData); } + + /** + * Utility class to associate the logical name with the JAR name, needed during the + * order resolving. + * @author remm + */ + protected class WebOrdering implements Serializable { + + private static final long serialVersionUID = 5603203103871892211L; + + protected String jar = null; + protected String name = null; + protected List after = new ArrayList(); + protected List before = new ArrayList(); + protected boolean afterOthers = false; + protected boolean beforeOthers = false; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getAfter() { + return after; + } + + public void addAfter(String name) { + after.add(name); + } + + public List getBefore() { + return before; + } + + public void addBefore(String name) { + before.add(name); + } + + public String getJar() { + return jar; + } + + public void setJar(String jar) { + this.jar = jar; + } + + public boolean isAfterOthers() { + return afterOthers; + } + + public void setAfterOthers(boolean afterOthers) { + this.afterOthers = afterOthers; + } + + public boolean isBeforeOthers() { + return beforeOthers; + } + + public void setBeforeOthers(boolean beforeOthers) { + this.beforeOthers = beforeOthers; + } + + } + + protected static class Ordering { + protected WebOrdering ordering; + protected Set after = new HashSet(); + protected Set before = new HashSet(); + protected boolean afterOthers = false; + protected boolean beforeOthers = false; + + public boolean addAfter(Ordering ordering) { + return after.add(ordering); + } + + public boolean addBefore(Ordering ordering) { + return before.add(ordering); + } + + public void validate() { + isBefore(new Ordering()); + isAfter(new Ordering()); + } + + /** + * Check (recursively) if a fragment is before the specified fragment. + * + * @param ordering + * @return + */ + public boolean isBefore(Ordering ordering) { + return isBeforeInternal(ordering, new HashSet()); + } + + protected boolean isBeforeInternal(Ordering ordering, Set checked) { + checked.add(this); + if (before.contains(ordering)) { + return true; + } + Iterator beforeIterator = before.iterator(); + while (beforeIterator.hasNext()) { + Ordering check = beforeIterator.next(); + if (checked.contains(check)) { + //throw new IllegalStateException(sm.getString("ordering.orderConflict", this.ordering.getJar())); + throw new IllegalStateException("Ordering conflict with JAR: " + this.ordering.getJar()); + } + if (check.isBeforeInternal(ordering, checked)) { + return false; + } + } + return false; + } + + /** + * Check (recursively) if a fragment is after the specified fragment. + * + * @param ordering + * @return + */ + public boolean isAfter(Ordering ordering) { + return isAfterInternal(ordering, new HashSet()); + } + + protected boolean isAfterInternal(Ordering ordering, Set checked) { + checked.add(this); + if (after.contains(ordering)) { + return true; + } + Iterator afterIterator = after.iterator(); + while (afterIterator.hasNext()) { + Ordering check = afterIterator.next(); + if (checked.contains(check)) { + //throw new IllegalStateException(sm.getString("ordering.orderConflict", this.ordering.getJar())); + throw new IllegalStateException("Ordering conflict with JAR: " + this.ordering.getJar()); + } + if (check.isAfterInternal(ordering, checked)) { + return false; + } + } + return false; + } + + /** + * Check is a fragment marked as before others is after a fragment that is not. + * + * @return true if a fragment marked as before others is after a fragment that is not + */ + public boolean isLastBeforeOthers() { + if (!beforeOthers) { + throw new IllegalStateException(); + } + Iterator beforeIterator = before.iterator(); + while (beforeIterator.hasNext()) { + Ordering check = beforeIterator.next(); + if (!check.beforeOthers) { + return true; + } else if (check.isLastBeforeOthers()) { + return true; + } + } + return false; + } + + /** + * Check is a fragment marked as after others is before a fragment that is not. + * + * @return true if a fragment marked as after others is before a fragment that is not + */ + public boolean isFirstAfterOthers() { + if (!afterOthers) { + throw new IllegalStateException(); + } + Iterator afterIterator = after.iterator(); + while (afterIterator.hasNext()) { + Ordering check = afterIterator.next(); + if (!check.afterOthers) { + return true; + } else if (check.isFirstAfterOthers()) { + return true; + } + } + return false; + } + + } + + /** + * Generate the Jar processing order. + * + * @param webOrderings The list of orderings, as parsed from the fragments + * @param order The generated order list + */ + protected static void resolveOrder(List webOrderings, List order) { + List work = new ArrayList(); + + // Populate the work Ordering list + Iterator webOrderingsIterator = webOrderings.iterator(); + while (webOrderingsIterator.hasNext()) { + WebOrdering webOrdering = webOrderingsIterator.next(); + Ordering ordering = new Ordering(); + ordering.ordering = webOrdering; + ordering.afterOthers = webOrdering.isAfterOthers(); + ordering.beforeOthers = webOrdering.isBeforeOthers(); + if (ordering.afterOthers && ordering.beforeOthers) { + // Cannot be both after and before others + //throw new IllegalStateException(sm.getString("ordering.afterAndBeforeOthers", webOrdering.getJar())); + throw new IllegalStateException("Ordering includes both before and after others in JAR: " + webOrdering.getJar()); + } + work.add(ordering); + } + + // Create double linked relationships between the orderings, + // and resolve names + Iterator workIterator = work.iterator(); + while (workIterator.hasNext()) { + Ordering ordering = workIterator.next(); + WebOrdering webOrdering = ordering.ordering; + Iterator after = webOrdering.getAfter().iterator(); + while (after.hasNext()) { + String name = after.next(); + Iterator workIterator2 = work.iterator(); + boolean found = false; + while (workIterator2.hasNext()) { + Ordering ordering2 = workIterator2.next(); + if (name.equals(ordering2.ordering.getName())) { + if (found) { + // Duplicate name + //throw new IllegalStateException(sm.getString("ordering.duplicateName", webOrdering.getJar())); + throw new IllegalStateException("Duplicate name declared in JAR: " + webOrdering.getJar()); + } + ordering.addAfter(ordering2); + ordering2.addBefore(ordering); + found = true; + } + } + if (!found) { + // Unknown name + //throw new IllegalStateException(sm.getString("ordering.unkonwnName", webOrdering.getJar())); + throw new IllegalStateException("Unknown name declared in JAR: " + webOrdering.getJar()); + } + } + Iterator before = webOrdering.getBefore().iterator(); + while (before.hasNext()) { + String name = before.next(); + Iterator workIterator2 = work.iterator(); + boolean found = false; + while (workIterator2.hasNext()) { + Ordering ordering2 = workIterator2.next(); + if (name.equals(ordering2.ordering.getName())) { + if (found) { + // Duplicate name + //throw new IllegalStateException(sm.getString("ordering.duplicateName", webOrdering.getJar())); + throw new IllegalStateException("Duplicate name declared in JAR: " + webOrdering.getJar()); + } + ordering.addBefore(ordering2); + ordering2.addAfter(ordering); + found = true; + } + } + if (!found) { + // Unknown name + //throw new IllegalStateException(sm.getString("ordering.unkonwnName", webOrdering.getJar())); + throw new IllegalStateException("Unknown name declared in JAR: " + webOrdering.getJar()); + } + } + } + + // Validate ordering + workIterator = work.iterator(); + while (workIterator.hasNext()) { + workIterator.next().validate(); + } + + // Create three ordered lists that will then be merged + List tempOrder = new ArrayList(); + + // Create the ordered list of fragments which are before others + workIterator = work.iterator(); + while (workIterator.hasNext()) { + Ordering ordering = workIterator.next(); + if (ordering.beforeOthers) { + // Insert at the first possible position + int insertAfter = -1; + boolean last = ordering.isLastBeforeOthers(); + int lastBeforeOthers = -1; + for (int i = 0; i < tempOrder.size(); i++) { + if (ordering.isAfter(tempOrder.get(i))) { + insertAfter = i; + } + if (tempOrder.get(i).beforeOthers) { + lastBeforeOthers = i; + } + } + int pos = insertAfter; + if (last && lastBeforeOthers > insertAfter) { + pos = lastBeforeOthers; + } + tempOrder.add(pos + 1, ordering); + } else if (ordering.afterOthers) { + // Insert at the last possible element + int insertBefore = tempOrder.size(); + boolean first = ordering.isFirstAfterOthers(); + int firstAfterOthers = tempOrder.size(); + for (int i = tempOrder.size() - 1; i >= 0; i--) { + if (ordering.isBefore(tempOrder.get(i))) { + insertBefore = i; + } + if (tempOrder.get(i).afterOthers) { + firstAfterOthers = i; + } + } + int pos = insertBefore; + if (first && firstAfterOthers < insertBefore) { + pos = firstAfterOthers; + } + tempOrder.add(pos, ordering); + } else { + // Insert according to other already inserted elements + int insertAfter = -1; + int insertBefore = tempOrder.size(); + for (int i = 0; i < tempOrder.size(); i++) { + if (ordering.isAfter(tempOrder.get(i)) || tempOrder.get(i).beforeOthers) { + insertAfter = i; + } + if (ordering.isBefore(tempOrder.get(i)) || tempOrder.get(i).afterOthers) { + insertBefore = i; + } + } + if (insertAfter > insertBefore) { + // Conflicting order (probably caught earlier) + //throw new IllegalStateException(sm.getString("ordering.orderConflict", ordering.ordering.getJar())); + throw new IllegalStateException("Fragment ordering conflict with JAR: " + ordering.ordering.getJar()); + } + // Insert somewhere in the range + tempOrder.add(insertAfter + 1, ordering); + } + } + + // Create the final ordered list + Iterator tempOrderIterator = tempOrder.iterator(); + while (tempOrderIterator.hasNext()) { + Ordering ordering = tempOrderIterator.next(); + order.add(ordering.ordering.getJar()); + } + + } + } Index: org/jboss/web/deployers/WarAnnotationMetaDataDeployer.java =================================================================== --- org/jboss/web/deployers/WarAnnotationMetaDataDeployer.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 0) +++ org/jboss/web/deployers/WarAnnotationMetaDataDeployer.java (.../trunk/server/src/main/java) (revision 97312) @@ -0,0 +1,223 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2007, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt 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.web.deployers; + +import java.io.IOException; +import java.lang.reflect.AnnotatedElement; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.jboss.deployers.spi.DeploymentException; +import org.jboss.deployers.spi.deployer.DeploymentStages; +import org.jboss.deployers.spi.deployer.helpers.AbstractDeployer; +import org.jboss.deployers.structure.spi.DeploymentUnit; +import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit; +import org.jboss.deployment.AnnotatedClassFilter; +import org.jboss.metadata.annotation.creator.web.Web30MetaDataCreator; +import org.jboss.metadata.annotation.finder.AnnotationFinder; +import org.jboss.metadata.annotation.finder.DefaultAnnotationFinder; +import org.jboss.metadata.web.spec.WebMetaData; +import org.jboss.virtual.VirtualFile; + +/** + * A POST_CLASSLOADER deployer which generates metadata from + * annotations + * + * @author Scott.Stark@jboss.org + * @version $Revision: 93949 $ + */ +public class WarAnnotationMetaDataDeployer extends AbstractDeployer +{ + public static final String WEB_ANNOTATED_ATTACHMENT_NAME = "annotated."+WebMetaData.class.getName(); + + private boolean metaDataCompleteIsDefault = false; + + public WarAnnotationMetaDataDeployer() + { + setStage(DeploymentStages.POST_CLASSLOADER); + addInput(WebMetaData.class); + addOutput(WEB_ANNOTATED_ATTACHMENT_NAME); + } + + public boolean isMetaDataCompleteIsDefault() + { + return metaDataCompleteIsDefault; + } + public void setMetaDataCompleteIsDefault(boolean metaDataCompleteIsDefault) + { + this.metaDataCompleteIsDefault = metaDataCompleteIsDefault; + } + + public void deploy(DeploymentUnit unit) throws DeploymentException + { + if (unit instanceof VFSDeploymentUnit == false) + return; + + VFSDeploymentUnit vfsDeploymentUnit = (VFSDeploymentUnit) unit; + deploy(vfsDeploymentUnit); + } + + public void undeploy(DeploymentUnit unit) + { + if (unit instanceof VFSDeploymentUnit == false) + return; + + VFSDeploymentUnit vfsDeploymentUnit = (VFSDeploymentUnit) unit; + undeploy(vfsDeploymentUnit); + } + + /** + * Process the + * + * @param unit the unit + * @throws DeploymentException for any error + */ + protected void deploy(VFSDeploymentUnit unit) + throws DeploymentException + { + if (!unit.getSimpleName().endsWith(".war")) + { + return; + } + + VirtualFile root = unit.getRoot(); + boolean isLeaf = true; + try + { + isLeaf = root.isLeaf(); + } + catch(IOException ignore) + { + } + if(isLeaf == true) + return; + + List classpath = unit.getClassPath(); + if(classpath == null || classpath.isEmpty()) + return; + + if (log.isTraceEnabled()) + log.trace("Deploying annotations for unit: " + unit + ", classpath: " + classpath); + + try + { + processMetaData(unit, classpath); + } + catch (Exception e) + { + throw DeploymentException.rethrowAsDeploymentException("Cannot process metadata", e); + } + } + + /** + * Process metadata. + * + * @param unit the deployment unit + * @param classpath the classpath + * @throws Exception for any error + */ + protected void processMetaData(VFSDeploymentUnit unit, List classpath) throws Exception + { + Map>> classesPerJar = new HashMap>>(); + boolean foundAnnotations = false; + for (VirtualFile path : classpath) + { + Collection> currentClasses = getClasses(unit, path); + classesPerJar.put(path, currentClasses); + if (currentClasses.size() > 0) + { + foundAnnotations = true; + } + } + if (foundAnnotations) + { + AnnotationFinder finder = new DefaultAnnotationFinder(); + processJBossWebMetaData(unit, finder, classesPerJar); + } + } + + /** + * Get the classes we want to scan. + * + * @param unit the deployment unit + * @param mainClassName the main class name + * @param classpath the classpath + * @return possible classes containing metadata annotations + * @throws IOException for any error + */ + protected Collection> getClasses(VFSDeploymentUnit unit, VirtualFile classpath) throws IOException + { + AnnotatedClassFilter classVisitor = new AnnotatedClassFilter(unit, unit.getClassLoader(), classpath, null); + classpath.visit(classVisitor); + Map> classes = classVisitor.getAnnotatedClasses(); + if (classes != null && classes.size() > 0) + { + if(log.isTraceEnabled()) + log.trace("Annotated classes: " + classes); + } + else + { + classes = new HashMap>(); + } + return classes.values(); + } + + /** + * Undeploy a vfs deployment + * + * @param unit the unit + */ + protected void undeploy(VFSDeploymentUnit unit) + { + // Nothing + } + + /** + * Process annotations. + * + * @param unit the deployment unit + * @param finder the annotation finder + * @param classes the candidate classes + */ + protected void processJBossWebMetaData(VFSDeploymentUnit unit, + AnnotationFinder finder, Map>> classes) + { + Web30MetaDataCreator creator = new Web30MetaDataCreator(finder); + boolean metaData = false; + for (VirtualFile path : classes.keySet()) + { + WebMetaData annotationMetaData = creator.create(classes.get(path)); + log.debug("Add annotations: " + WEB_ANNOTATED_ATTACHMENT_NAME + ":" + path.getName()); + if (annotationMetaData != null) + { + unit.addAttachment(WEB_ANNOTATED_ATTACHMENT_NAME + ":" + path.getName(), annotationMetaData, WebMetaData.class); + metaData = true; + } + } + if (metaData) + unit.addAttachment(WEB_ANNOTATED_ATTACHMENT_NAME, Boolean.TRUE); + } + +} + Index: org/jboss/web/deployers/WARStructure.java =================================================================== --- org/jboss/web/deployers/WARStructure.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/web/deployers/WARStructure.java (.../trunk/server/src/main/java) (revision 97312) @@ -161,6 +161,21 @@ List metaDataLocations = new ArrayList(); metaDataLocations.add("WEB-INF"); + + // Add all children as locations for TLDs (except classes and lib), recursively + webinf = file.getChild("WEB-INF"); + if (webinf != null) + { + List children = webinf.getChildren(); + for (VirtualFile child : children) + { + if (!isLeaf(child) && (!"lib".equals(child.getName())) && (!"classes".equals(child.getName()))) + { + metaDataLocations.add("WEB-INF/" + child.getName()); + addPathsRecursively(metaDataLocations, child, "WEB-INF/" + child.getName()); + } + } + } // Check for WEB-INF/classes VirtualFile classes = null; @@ -170,6 +185,7 @@ classes = file.getChild("WEB-INF/classes"); // Check for a META-INF for metadata + // FIXME: This is not spec legal, descriptors could be loaded from this location if (classes != null) metaDataLocations.add("WEB-INF/classes/META-INF"); } @@ -191,7 +207,23 @@ { // either same as plain lib filter, null or accepts the jar if (webInfLibMetaDataFilter == null || webInfLibMetaDataFilter == webInfLibFilter || webInfLibMetaDataFilter.accepts(jar)) - metaDataLocations.add("WEB-INF/lib/" + jar.getName() + "/META-INF"); + { + VirtualFile metaInf = jar.getChild("META-INF"); + if (metaInf != null && !isLeaf(metaInf)) + { + metaDataLocations.add("WEB-INF/lib/" + jar.getName() + "/META-INF"); + List children = metaInf.getChildren(); + for (VirtualFile child : children) + { + if (!isLeaf(child) && (!"resources".equals(child.getName()))) + { + metaDataLocations.add("WEB-INF/lib/" + jar.getName() + "/META-INF/" + child.getName()); + addPathsRecursively(metaDataLocations, child, + "WEB-INF/lib/" + jar.getName() + "/META-INF/" + child.getName()); + } + } + } + } } } } @@ -248,4 +280,19 @@ throw DeploymentException.rethrowAsDeploymentException("Error determining structure: " + file.getName(), e); } } + + protected void addPathsRecursively(List metaDataLocations, VirtualFile parent, String path) + throws IOException + { + List children = parent.getChildren(); + for (VirtualFile child : children) + { + if (!isLeaf(child)) + { + metaDataLocations.add(path + "/" + child.getName()); + addPathsRecursively(metaDataLocations, child, path + "/" + child.getName()); + } + } + } + } Index: org/jboss/web/deployers/AbstractWarDeployment.java =================================================================== --- org/jboss/web/deployers/AbstractWarDeployment.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/web/deployers/AbstractWarDeployment.java (.../trunk/server/src/main/java) (revision 97312) @@ -37,7 +37,6 @@ import javax.naming.NamingException; import org.jboss.beans.metadata.api.annotations.Inject; -import org.jboss.bootstrap.api.as.config.JBossASServerConfig; import org.jboss.deployers.structure.spi.DeploymentUnit; import org.jboss.deployers.structure.spi.main.MainDeployerStructure; import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit; @@ -69,9 +68,10 @@ import org.jboss.security.ISecurityManagement; import org.jboss.security.SecurityConstants; import org.jboss.security.authorization.PolicyRegistration; -import org.jboss.virtual.VFSUtils; import org.jboss.web.WebApplication; import org.jboss.wsf.spi.deployment.UnifiedVirtualFile; +import org.jboss.virtual.VFSUtils; +import org.jboss.bootstrap.spi.as.config.JBossASServerConfig; import org.omg.CORBA.ORB; /** @@ -85,7 +85,7 @@ - performUndeploy(WebApplication webApp, String warUrl) to remove the application corresponding to the WebApplication data. This is called when the AbstractWarDeployment is stopped. - + The one thing to be aware of is the relationship between the thread context class loader and the JNDI ENC context. Any method that attempts to access the JNDI ENC context must have the ClassLoader in the WebApplication returned @@ -169,7 +169,7 @@ */ public static String shortWarUrlFromServerHome(String warUrl) { - String serverHomeUrl = System.getProperty(JBossASServerConfig.PROP_KEY_JBOSSAS_SERVER_HOME_URL); + String serverHomeUrl = System.getProperty(JBossASServerConfig.PROP_KEY_JBOSSAS_HOME_URL); if (warUrl == null || serverHomeUrl == null) return warUrl; @@ -348,7 +348,7 @@ /** * Get the securityManagement. - * + * * @return the securityManagement. */ public String getSecurityManagementName() @@ -358,7 +358,7 @@ /** * Set the securityManagement. - * + * * @param securityManagement the securityManagement. */ public void setSecurityManagementName(String securityManagement) @@ -368,7 +368,7 @@ /** * Get the securityManagement. - * + * * @return the securityManagement. */ public ISecurityManagement getSecurityManagement() @@ -378,7 +378,7 @@ /** * Set the securityManagement. - * + * * @param securityManagement the securityManagement. */ public void setSecurityManagement(ISecurityManagement securityManagement) @@ -440,9 +440,9 @@ // Dynamic WebMetaData deployments might not provide an URL // We use the DEploymentUnit name as identifier instead. - // The JAXWS Endpoint API for example does this. + // The JAXWS Endpoint API for example does this. String warURLString = (warUrl != null ? warUrl.toExternalForm() : unit.getName()); - + // Strip any jar: url syntax. This should be be handled by the vfs if (warURLString.startsWith("jar:")) warURLString = warURLString.substring(4, warURLString.length() - 2); Index: org/jboss/web/AbstractWebContainerMBean.java =================================================================== --- org/jboss/web/AbstractWebContainerMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/web/AbstractWebContainerMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -25,7 +25,7 @@ * MBean interface. * @see org.jboss.web.AbstractWebDeployer */ -public interface AbstractWebContainerMBean extends org.jboss.deployment.SubDeployerMBean { +public interface AbstractWebContainerMBean { /** * Get the flag indicating if the normal Java2 parent first class loading model should be used over the servlet 2.3 web container first model. Index: org/jboss/web/AbstractWebDeployerMBean.java =================================================================== --- org/jboss/web/AbstractWebDeployerMBean.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/web/AbstractWebDeployerMBean.java (.../trunk/server/src/main/java) (revision 97312) @@ -31,7 +31,7 @@ * @see org.jboss.security.SimplePrincipal; * @see org.jboss.security.SecurityAssociation; */ -public interface AbstractWebDeployerMBean extends org.jboss.deployment.SubDeployerMBean { +public interface AbstractWebDeployerMBean { //default object name public static final javax.management.ObjectName OBJECT_NAME = org.jboss.mx.util.ObjectNameFactory.create("jboss.web:service=WebServer"); Index: org/jboss/web/WebService.java =================================================================== --- org/jboss/web/WebService.java (.../tags/JBoss_6_0_0_M1/server/src/main) (revision 97312) +++ org/jboss/web/WebService.java (.../trunk/server/src/main/java) (revision 97312) @@ -26,15 +26,14 @@ import java.net.UnknownHostException; import java.util.Enumeration; import java.util.Properties; +import java.util.concurrent.Executor; +import org.jboss.system.ServiceMBeanSupport; +import org.jboss.bootstrap.spi.as.config.JBossASServerConfig; +import org.jboss.config.ServerConfigUtil; import javax.management.MBeanServer; import javax.management.ObjectName; -import org.jboss.bootstrap.api.as.config.JBossASServerConfig; -import org.jboss.config.ServerConfigUtil; -import org.jboss.system.ServiceMBeanSupport; -import org.jboss.util.threadpool.BasicThreadPoolMBean; - /** * The WebService implementation. It configures a WebServer instance to * perform dynamic class and resource loading. @@ -209,9 +208,9 @@ * @jmx:managed-attribute * */ - public void setThreadPool(BasicThreadPoolMBean threadPool) + public void setExecutor(Executor executor) { - server.setThreadPool(threadPool); + server.setThreadPool(executor); } /** Property changes on: org ___________________________________________________________________ Added: svn:mergeinfo