/** * Check the deployment annotation index for all classes with the @PersistenceContext annotation. * For each class with the annotation, collect all the required information to create a managed * bean instance, and attach it to the context. * * @param phaseContext the deployment unit context * @throws org.jboss.as.server.deployment.DeploymentUnitProcessingException */ protected void processComponentConfig( final DeploymentUnit deploymentUnit, final DeploymentPhaseContext phaseContext, final CompositeIndex compositeIndex, final AbstractComponentDescription componentDescription) throws DeploymentUnitProcessingException { final ClassInfo classInfo = compositeIndex.getClassByName( DotName.createSimple(componentDescription.getComponentClassName())); if (classInfo == null) { return; // We can't continue without the annotation index info. } componentDescription .getBindings() .addAll(getConfigurations(deploymentUnit, classInfo, componentDescription, phaseContext)); final Collection<InterceptorDescription> interceptorConfigurations = componentDescription.getAllInterceptors().values(); for (InterceptorDescription interceptorConfiguration : interceptorConfigurations) { final ClassInfo interceptorClassInfo = compositeIndex.getClassByName( DotName.createSimple(interceptorConfiguration.getInterceptorClassName())); if (interceptorClassInfo == null) { continue; } interceptorConfiguration .getBindings() .addAll( getConfigurations( deploymentUnit, interceptorClassInfo, componentDescription, phaseContext)); } }
@Test public void testEntityMetadataComplete() { Index index = getMockedIndex("entity-metadata-complete.xml"); DotName authorName = DotName.createSimple(Author.class.getName()); ClassInfo authorClassInfo = index.getClassByName(authorName); assertHasAnnotation(index, authorName, JPADotNames.ENTITY); assertHasAnnotation(index, authorName, JPADotNames.ID_CLASS); assertEquals(2, authorClassInfo.annotations().size()); DotName bookName = DotName.createSimple(Book.class.getName()); assertHasAnnotation(index, bookName, JPADotNames.ENTITY); }
@Test public void testOverrideToMappedSuperClass() { Index index = getMockedIndex("override-to-mappedsuperclass.xml"); index.printAnnotations(); DotName authorName = DotName.createSimple(Author.class.getName()); assertHasAnnotation(index, authorName, JPADotNames.ENTITY); assertHasNoAnnotation(index, authorName, JPADotNames.TABLE); DotName bookName = DotName.createSimple(Book.class.getName()); assertHasAnnotation(index, bookName, JPADotNames.MAPPED_SUPERCLASS); assertHasNoAnnotation(index, bookName, JPADotNames.TABLE); }
private static ClassInfo getModuleInfo(final Index index, final String moduleName) { // we need to escape any java keyword from the package list String quotedModuleName = JVMModuleUtil.quoteJavaKeywords(moduleName); DotName moduleClassName = DotName.createSimple(quotedModuleName + ".$module_"); ClassInfo ret = index.getClassByName(moduleClassName); if (ret == null) { // read previous module descriptor name moduleClassName = DotName.createSimple(quotedModuleName + ".module_"); ret = index.getClassByName(moduleClassName); } return ret; }
@Test public void testDefaultCascadePersist() { Default defaults = new Default(); defaults.setCascadePersist(true); Index index = getIndex(); Map<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>(); annotations.putAll( index.getClassByName(DotName.createSimple(Parent.class.getName())).annotations()); assertEquals(4, annotations.size()); assertEquals(1, annotations.get(JPADotNames.ENTITY).size()); assertEquals(1, annotations.get(JPADotNames.ID).size()); assertEquals(1, annotations.get(JPADotNames.ONE_TO_MANY).size()); assertEquals(1, annotations.get(JPADotNames.MANY_TO_ONE).size()); DefaultConfigurationHelper.INSTANCE.applyDefaults(annotations, defaults); assertEquals(4, annotations.size()); assertEquals(1, annotations.get(JPADotNames.ENTITY).size()); assertEquals(1, annotations.get(JPADotNames.ID).size()); assertEquals(1, annotations.get(JPADotNames.ONE_TO_MANY).size()); assertEquals(1, annotations.get(JPADotNames.MANY_TO_ONE).size()); AnnotationInstance oneToMany = annotations.get(JPADotNames.ONE_TO_MANY).get(0); String[] cascadeTypes = oneToMany.value("cascade").asEnumArray(); assertArrayEquals(new String[] {"ALL", "DETACH", "PERSIST"}, cascadeTypes); AnnotationInstance manyToOne = annotations.get(JPADotNames.MANY_TO_ONE).get(0); cascadeTypes = manyToOne.value("cascade").asEnumArray(); assertArrayEquals(new String[] {"PERSIST"}, cascadeTypes); annotations.clear(); annotations.putAll( index.getClassByName(DotName.createSimple(Child.class.getName())).annotations()); assertEquals(3, annotations.size()); assertEquals(1, annotations.get(JPADotNames.ENTITY).size()); assertEquals(1, annotations.get(JPADotNames.ID).size()); assertEquals(1, annotations.get(JPADotNames.MANY_TO_ONE).size()); DefaultConfigurationHelper.INSTANCE.applyDefaults(annotations, defaults); assertEquals(3, annotations.size()); assertEquals(1, annotations.get(JPADotNames.ENTITY).size()); assertEquals(1, annotations.get(JPADotNames.ID).size()); assertEquals(1, annotations.get(JPADotNames.MANY_TO_ONE).size()); manyToOne = annotations.get(JPADotNames.MANY_TO_ONE).get(0); cascadeTypes = manyToOne.value("cascade").asEnumArray(); assertArrayEquals(new String[] {"PERSIST", "ALL", "DETACH"}, cascadeTypes); }
private DotName toJandexName(Name typeName) { if (DotNameAdapter.class.isInstance(typeName)) { return ((DotNameAdapter) typeName).jandexName(); } else { return DotName.createSimple(typeName.fullName()); } }
/** * Entity has a @AttributeOverride on property topic and this property also has a * <attribute-override> in orm.xml but with different name by jpa override rules, this two * attribute-override should be merged into one @AttributeOverrides */ @Test public void testAttributeOverride() { Index index = getMockedIndex("AttributeOverride.xml"); DotName className = DotName.createSimple(Book.class.getName()); index.printAnnotations(); assertHasNoAnnotation(index, className, JPADotNames.ATTRIBUTE_OVERRIDE); assertAnnotationValue( index, className, JPADotNames.ATTRIBUTE_OVERRIDES, new AnnotationValueChecker() { @Override public void check(AnnotationInstance annotationInstance) { AnnotationValue value = annotationInstance.value(); assertNotNull(value); AnnotationInstance[] annotationInstances = value.asNestedArray(); assertEquals(2, annotationInstances.length); AnnotationInstance ai = annotationInstances[0]; String name = ai.value("name").asString(); AnnotationValue columnValue = ai.value("column").asNested().value("name"); if (name.equals("title")) { assertEquals("TOC_TITLE", columnValue.asString()); } else if (name.equals("summary")) { assertEquals("TOPIC_SUMMARY", columnValue.asString()); } else { fail( "AttributeOverride's name is " + name + ", should be either 'title' or 'summary'"); } } }); }
@Test public void testDefaultSchemaToAnnotationInstance() { Default defaults = new Default(); defaults.setSchema("hib_schema"); defaults.setCatalog("hib_catalog"); Index index = getIndex(); Map<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>(); annotations.putAll( index.getClassByName(DotName.createSimple(Parent.class.getName())).annotations()); assertEquals(4, annotations.size()); assertEquals(1, annotations.get(JPADotNames.ENTITY).size()); assertEquals(1, annotations.get(JPADotNames.ID).size()); assertEquals(1, annotations.get(JPADotNames.ONE_TO_MANY).size()); assertEquals(1, annotations.get(JPADotNames.MANY_TO_ONE).size()); DefaultConfigurationHelper.INSTANCE.applyDefaults(annotations, defaults); assertEquals(5, annotations.size()); assertEquals(1, annotations.get(JPADotNames.ENTITY).size()); assertEquals(1, annotations.get(JPADotNames.ID).size()); assertEquals(1, annotations.get(JPADotNames.ONE_TO_MANY).size()); assertEquals(1, annotations.get(JPADotNames.MANY_TO_ONE).size()); assertEquals(1, annotations.get(JPADotNames.TABLE).size()); AnnotationInstance table = annotations.get(JPADotNames.TABLE).get(0); assertEquals("hib_schema", table.value("schema").asString()); assertEquals("hib_catalog", table.value("catalog").asString()); annotations.clear(); annotations.putAll( index.getClassByName(DotName.createSimple(Name.class.getName())).annotations()); DefaultConfigurationHelper.INSTANCE.applyDefaults(annotations, defaults); assertEquals(1, annotations.size()); assertEquals(1, annotations.get(JPADotNames.SECONDARY_TABLES).size()); AnnotationInstance[] secondaryTables = annotations.get(JPADotNames.SECONDARY_TABLES).get(0).value().asNestedArray(); assertEquals(2, secondaryTables.length); AnnotationInstance secondaryTable = secondaryTables[0]; String name = secondaryTable.value("name").asString(); if (name.equals("sec1")) { assertSt1(secondaryTable); assertSt2(secondaryTables[1]); } else { assertSt1(secondaryTables[1]); assertSt2(secondaryTable); } }
@Test public void testSingleEntity() { Index index = JandexHelper.indexForClass( service, Paper.class, Stuff.class, Item.class, PricedStuff.class); Set<ConfiguredClassHierarchy> hierarchies = ConfiguredClassHierarchyBuilder.createEntityHierarchies(index, serviceRegistry); assertEquals("There should be only one hierarchy", 1, hierarchies.size()); Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator(); ConfiguredClass configuredClass = iter.next(); ClassInfo info = configuredClass.getClassInfo(); assertEquals("wrong class", DotName.createSimple(Stuff.class.getName()), info.name()); MappedAttribute property = configuredClass.getMappedProperty("value"); assertEquals(Price.class, property.getType()); assertTrue(iter.hasNext()); configuredClass = iter.next(); info = configuredClass.getClassInfo(); assertEquals("wrong class", DotName.createSimple(PricedStuff.class.getName()), info.name()); assertFalse( "PricedStuff should not mapped properties", configuredClass.getMappedAttributes().iterator().hasNext()); assertTrue(iter.hasNext()); configuredClass = iter.next(); info = configuredClass.getClassInfo(); assertEquals("wrong class", DotName.createSimple(Item.class.getName()), info.name()); // properties are alphabetically ordered! property = configuredClass.getMappedProperty("owner"); assertEquals(SomeGuy.class, property.getType()); property = configuredClass.getMappedProperty("type"); assertEquals(PaperType.class, property.getType()); assertTrue(iter.hasNext()); configuredClass = iter.next(); info = configuredClass.getClassInfo(); assertEquals("wrong class", DotName.createSimple(Paper.class.getName()), info.name()); assertFalse( "Paper should not mapped properties", configuredClass.getMappedAttributes().iterator().hasNext()); assertFalse(iter.hasNext()); }
@Test public void testPersistenceUnitDefaultsCascadePersistInXML() { Index index = getMockedIndex("AttributeOverride.xml"); DotName className = DotName.createSimple(Author.class.getName()); assertAnnotationValue( index, className, JPADotNames.ONE_TO_MANY, new CascadeAnnotationValueChecker(new String[] {"PERSIST", "ALL"})); }
ClassInfo createClassInfo(String className) { if (StringHelper.isEmpty(className)) { throw new AssertionFailure("Class Name used to create ClassInfo is empty."); } DotName classDotName = DotName.createSimple(className); if (classes.containsKey(classDotName)) { // classInfoAnnotationsMap.put( classDotName, new HashMap<DotName, // List<AnnotationInstance>>(classes.get( classDotName ).annotations()) ); return classes.get(classDotName); } Class clazz = serviceRegistry.getService(ClassLoaderService.class).classForName(className); DotName superName = null; DotName[] interfaces = null; short access_flag; ClassInfo annClassInfo = index.getClassByName(classDotName); if (annClassInfo != null) { superName = annClassInfo.superName(); interfaces = annClassInfo.interfaces(); access_flag = annClassInfo.flags(); } else { Class superClass = clazz.getSuperclass(); if (superClass != null) { superName = DotName.createSimple(superClass.getName()); } Class[] classInterfaces = clazz.getInterfaces(); if (classInterfaces != null && classInterfaces.length > 0) { interfaces = new DotName[classInterfaces.length]; for (int i = 0; i < classInterfaces.length; i++) { interfaces[i] = DotName.createSimple(classInterfaces[i].getName()); } } access_flag = (short) (clazz.getModifiers() | 0x20); // (modifiers | ACC_SUPER) } Map<DotName, List<AnnotationInstance>> map = new HashMap<DotName, List<AnnotationInstance>>(); classInfoAnnotationsMap.put(classDotName, map); ClassInfo classInfo = ClassInfo.create(classDotName, superName, access_flag, interfaces, map); classes.put(classDotName, classInfo); addSubClasses(superName, classInfo); addImplementors(interfaces, classInfo); return classInfo; }
@Test public void testTablePerClassDefaultTableName() { @Entity @Inheritance(strategy = javax.persistence.InheritanceType.TABLE_PER_CLASS) class A { @Id @GeneratedValue private int id; } @Entity class B extends A {} Index index = JandexHelper.indexForClass(service, A.class, B.class); AnnotationBindingContext context = new AnnotationBindingContext(index, serviceRegistry); Set<ConfiguredClassHierarchy<EntityClass>> hierarchies = ConfiguredClassHierarchyBuilder.createEntityHierarchies(context); assertEquals("There should be only one hierarchy", 1, hierarchies.size()); Iterator<EntityClass> iter = hierarchies.iterator().next().iterator(); EntityClass entityClass = iter.next(); ClassInfo info = entityClass.getClassInfo(); assertEquals("wrong class", DotName.createSimple(A.class.getName()), info.name()); assertTrue(entityClass.hasOwnTable()); Assert.assertEquals( "wrong inheritance type", InheritanceType.TABLE_PER_CLASS, entityClass.getInheritanceType()); Assert.assertEquals("wrong table name", "A", entityClass.getPrimaryTableName()); assertTrue(iter.hasNext()); entityClass = iter.next(); info = entityClass.getClassInfo(); assertEquals("wrong class", DotName.createSimple(B.class.getName()), info.name()); assertTrue(entityClass.hasOwnTable()); Assert.assertEquals( "wrong inheritance type", InheritanceType.TABLE_PER_CLASS, entityClass.getInheritanceType()); Assert.assertEquals("wrong table name", "B", entityClass.getPrimaryTableName()); assertFalse(iter.hasNext()); }
public WeldSEClassFileInfo( String className, IndexView index, LoadingCache<DotName, Set<String>> annotationClassAnnotationsCache, ClassLoader classLoader) { this.index = index; this.annotationClassAnnotationsCache = annotationClassAnnotationsCache; this.classInfo = index.getClassByName(DotName.createSimple(className)); if (this.classInfo == null) { throw new IllegalStateException("Index for name: " + className + " not found"); } this.isVetoed = isVetoedTypeOrPackage(); this.hasCdiConstructor = this.classInfo.hasNoArgsConstructor() || hasInjectConstructor(); this.classLoader = classLoader; }
@Test public void testPersistenceUnitMetadataMetadataComplete() { JaxbEntity author = new JaxbEntity(); author.setClazz(Author.class.getName()); IndexBuilder indexBuilder = getIndexBuilder(); EntityMappingsMocker.Default defaults = new EntityMappingsMocker.Default(); defaults.setMetadataComplete(true); EntityMocker entityMocker = new EntityMocker(indexBuilder, author, defaults); entityMocker.preProcess(); entityMocker.process(); Index index = indexBuilder.build(new EntityMappingsMocker.Default()); DotName className = DotName.createSimple(Author.class.getName()); ClassInfo classInfo = index.getClassByName(className); assertEquals(1, classInfo.annotations().size()); assertHasAnnotation(index, className, JPADotNames.ENTITY); }
private boolean isVetoedTypeOrPackage() { if (isAnnotationDeclared(classInfo, DOT_NAME_VETOED)) { return true; } ClassInfo packageInfo = index.getClassByName( DotName.createSimple( getPackageName(classInfo.name()) + DOT_SEPARATOR + PACKAGE_INFO_NAME)); if (packageInfo != null && isAnnotationDeclared(packageInfo, DOT_NAME_VETOED)) { return true; } return false; }
@Test public void testPersistenceUnitDefaultsCascadePersistInAnnotation() { JaxbEntity author = new JaxbEntity(); author.setClazz(Author.class.getName()); IndexBuilder indexBuilder = getIndexBuilder(); EntityMappingsMocker.Default defaults = new EntityMappingsMocker.Default(); defaults.setCascadePersist(true); EntityMocker entityMocker = new EntityMocker(indexBuilder, author, defaults); entityMocker.preProcess(); entityMocker.process(); Index index = indexBuilder.build(new EntityMappingsMocker.Default()); DotName className = DotName.createSimple(Author.class.getName()); assertAnnotationValue( index, className, JPADotNames.ONE_TO_MANY, new CascadeAnnotationValueChecker("PERSIST", "MERGE")); }
private static boolean isWebserviceEndpoint( final ServletMetaData servletMD, final List<Index> annotationIndexes) { final String endpointClassName = ASHelper.getEndpointName(servletMD); if (isJSP(endpointClassName)) return false; final DotName endpointDN = DotName.createSimple(endpointClassName); ClassInfo endpointClassInfo = null; for (final Index index : annotationIndexes) { endpointClassInfo = index.getClassByName(endpointDN); if (endpointClassInfo != null) { if (endpointClassInfo.annotations().containsKey(WEB_SERVICE_ANNOTATION)) return true; if (endpointClassInfo.annotations().containsKey(WEB_SERVICE_PROVIDER_ANNOTATION)) return true; } } return false; }
private SessionType determineSessionType( final String ejbClass, final CompositeIndex compositeIndex) { if (ejbClass == null) { return null; } final ClassInfo info = compositeIndex.getClassByName(DotName.createSimple(ejbClass)); if (info == null) { return null; } if (info.annotations().get(STATEFUL_ANNOTATION) != null) { return SessionType.Stateful; } else if (info.annotations().get(STATELESS_ANNOTATION) != null) { return SessionType.Stateless; } else if (info.annotations().get(SINGLETON_ANNOTATION) != null) { return SessionType.Singleton; } return null; }
@Override public Collection<Annotation> getAnnotation(Class<?> annotationClass) { List<AnnotationInstance> instances = backingRepository.getAnnotations(DotName.createSimple(annotationClass.getName())); ArrayList<Annotation> annotations = new ArrayList<Annotation>(instances.size()); for (AnnotationInstance instance : instances) { AnnotationTarget target = instance.target(); Annotation annotation = null; if (target instanceof MethodInfo) { MethodInfo m = (MethodInfo) target; List<String> parameterTypes = new ArrayList<String>(m.args().length); for (Type type : m.args()) { parameterTypes.add(type.toString()); } String declaringClass = m.declaringClass().name().toString(); annotation = new AnnotationImpl( declaringClass, cl, parameterTypes, m.name(), true, false, annotationClass); } if (target instanceof FieldInfo) { FieldInfo f = (FieldInfo) target; String declaringClass = f.declaringClass().name().toString(); annotation = new AnnotationImpl(declaringClass, cl, null, f.name(), false, true, annotationClass); } if (target instanceof ClassInfo) { ClassInfo c = (ClassInfo) target; annotation = new AnnotationImpl(c.name().toString(), cl, null, null, false, false, annotationClass); } if (annotation != null) { annotations.add(annotation); } } annotations.trimToSize(); if (annotations.size() == 0) { return null; } else { return Collections.unmodifiableList(annotations); } }
/** @author Lance Ball */ public class IndexFactory { public static final DotName IMPLICIT_META = DotName.createSimple(Implicit.class.getCanonicalName()); public static final DotName BINDING_META = DotName.createSimple(ModelNodeBinding.class.getCanonicalName()); public static final DotName ADDRESS_META = DotName.createSimple(Address.class.getCanonicalName()); public static final DotName ADDRESSES_META = DotName.createSimple(Addresses.class.getCanonicalName()); public static final DotName RESOURCE_TYPE = DotName.createSimple(ResourceType.class.getCanonicalName()); public static final DotName SUBRESOURCE_META = DotName.createSimple(Subresource.class.getCanonicalName()); /** Creates an annotation index for the given entity type */ public static synchronized Index createIndex(Class<?> type) { Index index = indices.get(type); if (index == null) { try { Indexer indexer = new Indexer(); Class<?> currentType = type; while (currentType != null) { String className = currentType.getName().replace(".", "/") + ".class"; InputStream stream = type.getClassLoader().getResourceAsStream(className); indexer.index(stream); currentType = currentType.getSuperclass(); } index = indexer.complete(); indices.put(type, index); } catch (IOException e) { throw new RuntimeException("Failed to initialize Indexer", e); } } return index; } private static final HashMap<Class<?>, Index> indices = new HashMap<>(); }
/** * Handle PersistenceContext and PersistenceUnit annotations. * * @author Scott Marlow (based on ResourceInjectionAnnotationParsingProcessor) */ public class JPAAnnotationParseProcessor implements DeploymentUnitProcessor { private static final DotName PERSISTENCE_CONTEXT_ANNOTATION_NAME = DotName.createSimple(PersistenceContext.class.getName()); private static final DotName PERSISTENCE_UNIT_ANNOTATION_NAME = DotName.createSimple(PersistenceUnit.class.getName()); private static final String ENTITY_MANAGER_CLASS = "javax.persistence.EntityManager"; private static final String ENTITY_MANAGERFACTORY_CLASS = "javax.persistence.EntityManagerFactory"; @Override public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); final EEModuleDescription eeModuleDescription = deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION); final CompositeIndex index = deploymentUnit.getAttachment( org.jboss.as.server.deployment.Attachments.COMPOSITE_ANNOTATION_INDEX); final EEApplicationClasses applicationClasses = deploymentUnit.getAttachment(Attachments.EE_APPLICATION_CLASSES_DESCRIPTION); // @PersistenceContext List<AnnotationInstance> persistenceContexts = index.getAnnotations(PERSISTENCE_CONTEXT_ANNOTATION_NAME); // create binding and injection configurations out of the @PersistenceContext annotations this.processPersistenceAnnotations( deploymentUnit, eeModuleDescription, persistenceContexts, applicationClasses); // @PersistenceUnit List<AnnotationInstance> persistenceUnits = index.getAnnotations(PERSISTENCE_UNIT_ANNOTATION_NAME); // create binding and injection configurations out of the @PersistenceUnit annotaitons this.processPersistenceAnnotations( deploymentUnit, eeModuleDescription, persistenceUnits, applicationClasses); // if we found any @PersistenceContext or @PersistenceUnit annotations then mark this as a JPA // deployment if (!persistenceContexts.isEmpty() || !persistenceUnits.isEmpty()) { JPADeploymentMarker.mark(deploymentUnit); } } @Override public void undeploy(DeploymentUnit context) {} private void processPersistenceAnnotations( final DeploymentUnit deploymentUnit, final EEModuleDescription eeModuleDescription, List<AnnotationInstance> persistenceContexts, final EEApplicationClasses applicationClasses) throws DeploymentUnitProcessingException { for (AnnotationInstance annotation : persistenceContexts) { ClassInfo declaringClass = null; final AnnotationTarget annotationTarget = annotation.target(); if (annotationTarget instanceof FieldInfo) { FieldInfo fieldInfo = (FieldInfo) annotationTarget; declaringClass = fieldInfo.declaringClass(); EEModuleClassDescription eeModuleClassDescription = eeModuleDescription.addOrGetLocalClassDescription(declaringClass.name().toString()); this.processField(deploymentUnit, annotation, fieldInfo, eeModuleClassDescription); } else if (annotationTarget instanceof MethodInfo) { MethodInfo methodInfo = (MethodInfo) annotationTarget; declaringClass = methodInfo.declaringClass(); EEModuleClassDescription eeModuleClassDescription = eeModuleDescription.addOrGetLocalClassDescription(declaringClass.name().toString()); this.processMethod(deploymentUnit, annotation, methodInfo, eeModuleClassDescription); } else if (annotationTarget instanceof ClassInfo) { declaringClass = (ClassInfo) annotationTarget; EEModuleClassDescription eeModuleClassDescription = eeModuleDescription.addOrGetLocalClassDescription(declaringClass.name().toString()); this.processClass(deploymentUnit, annotation, eeModuleClassDescription); } } } private void processField( final DeploymentUnit deploymentUnit, final AnnotationInstance annotation, final FieldInfo fieldInfo, final EEModuleClassDescription eeModuleClassDescription) throws DeploymentUnitProcessingException { final String fieldName = fieldInfo.name(); final AnnotationValue declaredNameValue = annotation.value("name"); final String declaredName = declaredNameValue != null ? declaredNameValue.asString() : null; final String localContextName; if (declaredName == null || declaredName.isEmpty()) { localContextName = fieldInfo.declaringClass().name().toString() + "/" + fieldName; } else { localContextName = declaredName; } // final AnnotationValue declaredTypeValue = annotation.value("type"); final DotName declaredTypeDotName = fieldInfo.type().name(); final DotName injectionTypeDotName = declaredTypeDotName == null || declaredTypeDotName.toString().equals(Object.class.getName()) ? fieldInfo.type().name() : declaredTypeDotName; final String injectionType = injectionTypeDotName.toString(); final InjectionSource bindingSource = this.getBindingSource(deploymentUnit, annotation, injectionType, eeModuleClassDescription); if (bindingSource != null) { final BindingConfiguration bindingConfiguration = new BindingConfiguration(localContextName, bindingSource); eeModuleClassDescription.getBindingConfigurations().add(bindingConfiguration); // setup the injection target final InjectionTarget injectionTarget = new FieldInjectionTarget( fieldInfo.declaringClass().name().toString(), fieldName, fieldInfo.type().name().toString()); // source is always local ENC jndi final InjectionSource injectionSource = new LookupInjectionSource(localContextName); final ResourceInjectionConfiguration injectionConfiguration = new ResourceInjectionConfiguration(injectionTarget, injectionSource); eeModuleClassDescription.addResourceInjection(injectionConfiguration); } } private void processMethod( final DeploymentUnit deploymentUnit, final AnnotationInstance annotation, final MethodInfo methodInfo, final EEModuleClassDescription eeModuleClassDescription) throws DeploymentUnitProcessingException { final String methodName = methodInfo.name(); if (!methodName.startsWith("set") || methodInfo.args().length != 1) { eeModuleClassDescription.setInvalid( MESSAGES.setterMethodOnlyAnnotation(annotation.name().toString(), methodInfo)); return; } final String contextNameSuffix = methodName.substring(3, 4).toLowerCase() + methodName.substring(4); final AnnotationValue declaredNameValue = annotation.value("name"); final String declaredName = declaredNameValue != null ? declaredNameValue.asString() : null; final String localContextName; if (declaredName == null || declaredName.isEmpty()) { localContextName = methodInfo.declaringClass().name().toString() + "/" + contextNameSuffix; } else { localContextName = declaredName; } final String injectionType = methodInfo.args()[0].name().toString(); final InjectionSource bindingSource = this.getBindingSource(deploymentUnit, annotation, injectionType, eeModuleClassDescription); if (bindingSource != null) { final BindingConfiguration bindingConfiguration = new BindingConfiguration(localContextName, bindingSource); eeModuleClassDescription.getBindingConfigurations().add(bindingConfiguration); // setup the injection configuration final InjectionTarget injectionTarget = new MethodInjectionTarget( methodInfo.declaringClass().name().toString(), methodName, methodInfo.args()[0].name().toString()); // source is always local ENC jndi name final InjectionSource injectionSource = new LookupInjectionSource(localContextName); final ResourceInjectionConfiguration injectionConfiguration = new ResourceInjectionConfiguration(injectionTarget, injectionSource); eeModuleClassDescription.addResourceInjection(injectionConfiguration); } } private void processClass( final DeploymentUnit deploymentUnit, final AnnotationInstance annotation, final EEModuleClassDescription eeModuleClassDescription) throws DeploymentUnitProcessingException { final AnnotationValue nameValue = annotation.value("name"); if (nameValue == null || nameValue.asString().isEmpty()) { throw MESSAGES.classLevelAnnotationParameterRequired(annotation.name().toString(), "name"); } final String name = nameValue.asString(); String type = getClassLevelInjectionType(annotation); InjectionSource bindingSource = this.getBindingSource(deploymentUnit, annotation, type, eeModuleClassDescription); if (bindingSource != null) { final BindingConfiguration bindingConfiguration = new BindingConfiguration(name, bindingSource); eeModuleClassDescription.getBindingConfigurations().add(bindingConfiguration); } } private InjectionSource getBindingSource( final DeploymentUnit deploymentUnit, final AnnotationInstance annotation, String injectionTypeName, final EEModuleClassDescription classDescription) throws DeploymentUnitProcessingException { PersistenceUnitMetadata pu = getPersistenceUnit(deploymentUnit, annotation, classDescription); if (pu == null) { return null; } String scopedPuName = pu.getScopedPersistenceUnitName(); ServiceName puServiceName = getPuServiceName(scopedPuName); if (isPersistenceContext(annotation)) { if (pu.getTransactionType() == PersistenceUnitTransactionType.RESOURCE_LOCAL) { classDescription.setInvalid(MESSAGES.cannotInjectResourceLocalEntityManager()); return null; } AnnotationValue pcType = annotation.value("type"); PersistenceContextType type = (pcType == null || PersistenceContextType.TRANSACTION.name().equals(pcType.asString())) ? PersistenceContextType.TRANSACTION : PersistenceContextType.EXTENDED; Map properties; AnnotationValue value = annotation.value("properties"); AnnotationInstance[] props = value != null ? value.asNestedArray() : null; if (props != null) { properties = new HashMap(); for (int source = 0; source < props.length; source++) { properties.put(props[source].value("name"), props[source].value("value")); } } else { properties = null; } return new PersistenceContextInjectionSource( type, properties, puServiceName, deploymentUnit, scopedPuName, injectionTypeName, pu); } else { return new PersistenceUnitInjectionSource( puServiceName, deploymentUnit, injectionTypeName, pu); } } private boolean isExtendedPersistenceContext(final AnnotationInstance annotation) { AnnotationValue value = annotation.value("type"); return annotation.name().local().equals("PersistenceContext") && (value != null && PersistenceContextType.EXTENDED.name().equals(value.asString())); } private boolean isPersistenceContext(final AnnotationInstance annotation) { return annotation.name().local().equals("PersistenceContext"); } /** * Based on the the annotation type, its either entitymanager or entitymanagerfactory * * @param annotation * @return */ private String getClassLevelInjectionType(final AnnotationInstance annotation) { boolean isPC = annotation.name().local().equals("PersistenceContext"); return isPC ? ENTITY_MANAGER_CLASS : ENTITY_MANAGERFACTORY_CLASS; } private PersistenceUnitMetadata getPersistenceUnit( final DeploymentUnit deploymentUnit, final AnnotationInstance annotation, EEModuleClassDescription classDescription) throws DeploymentUnitProcessingException { final AnnotationValue puName = annotation.value("unitName"); String searchName = null; // note: a null searchName will match the first PU definition found if (puName != null) { searchName = puName.asString(); } PersistenceUnitMetadata pu = PersistenceUnitSearch.resolvePersistenceUnitSupplier(deploymentUnit, searchName); if (null == pu) { classDescription.setInvalid(MESSAGES.persistenceUnitNotFound(searchName, deploymentUnit)); return null; } return pu; } private ServiceName getPuServiceName(String scopedPuName) throws DeploymentUnitProcessingException { return PersistenceUnitServiceImpl.getPUServiceName(scopedPuName); } }
/** Process SCIs. */ public void deploy(final DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); final ModuleSpecification moduleSpecification = deploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION); final ServiceModuleLoader loader = deploymentUnit.getAttachment(Attachments.SERVICE_MODULE_LOADER); if (!DeploymentTypeMarker.isType(DeploymentType.WAR, deploymentUnit)) { return; // Skip non web deployments } WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY); assert warMetaData != null; final Module module = deploymentUnit.getAttachment(Attachments.MODULE); if (module == null) { throw MESSAGES.failedToResolveModule(deploymentUnit); } final ClassLoader classLoader = module.getClassLoader(); ScisMetaData scisMetaData = deploymentUnit.getAttachment(ScisMetaData.ATTACHMENT_KEY); if (scisMetaData == null) { scisMetaData = new ScisMetaData(); deploymentUnit.putAttachment(ScisMetaData.ATTACHMENT_KEY, scisMetaData); } Set<ServletContainerInitializer> scis = scisMetaData.getScis(); if (scis == null) { scis = new HashSet<ServletContainerInitializer>(); scisMetaData.setScis(scis); } Map<ServletContainerInitializer, Set<Class<?>>> handlesTypes = scisMetaData.getHandlesTypes(); if (handlesTypes == null) { handlesTypes = new HashMap<ServletContainerInitializer, Set<Class<?>>>(); scisMetaData.setHandlesTypes(handlesTypes); } // Find the SCIs from shared modules for (ModuleDependency dependency : moduleSpecification.getSystemDependencies()) { try { Module depModule = loader.loadModule(dependency.getIdentifier()); ServiceLoader<ServletContainerInitializer> serviceLoader = depModule.loadService(ServletContainerInitializer.class); for (ServletContainerInitializer service : serviceLoader) { scis.add(service); } } catch (ModuleLoadException e) { if (dependency.isOptional() == false) { throw MESSAGES.errorLoadingSCIFromModule(dependency.getIdentifier(), e); } } } // Find local ServletContainerInitializer services List<String> order = warMetaData.getOrder(); Map<String, VirtualFile> localScis = warMetaData.getScis(); if (order != null && localScis != null) { for (String jar : order) { VirtualFile sci = localScis.get(jar); if (sci != null) { ServletContainerInitializer service = loadSci(classLoader, sci, jar, true); if (service != null) { scis.add(service); } } } } // Process HandlesTypes for ServletContainerInitializer Map<Class<?>, Set<ServletContainerInitializer>> typesMap = new HashMap<Class<?>, Set<ServletContainerInitializer>>(); 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<ServletContainerInitializer> servicesSet = typesMap.get(type); if (servicesSet == null) { servicesSet = new HashSet<ServletContainerInitializer>(); typesMap.put(type, servicesSet); } servicesSet.add(service); handlesTypes.put(service, new HashSet<Class<?>>()); } } } } Class<?>[] typesArray = typesMap.keySet().toArray(new Class<?>[0]); final CompositeIndex index = deploymentUnit.getAttachment(Attachments.COMPOSITE_ANNOTATION_INDEX); if (index == null) { throw MESSAGES.unableToResolveAnnotationIndex(deploymentUnit); } // Find classes which extend, implement, or are annotated by HandlesTypes for (Class<?> type : typesArray) { DotName className = DotName.createSimple(type.getName()); Set<ClassInfo> classInfos = processHandlesType(className, type, index); Set<Class<?>> classes = loadClassInfoSet(classInfos, classLoader); Set<ServletContainerInitializer> sciSet = typesMap.get(type); for (ServletContainerInitializer sci : sciSet) { handlesTypes.get(sci).addAll(classes); } } }
/** * Handle PersistenceContext and PersistenceUnit annotations. * * @author Scott Marlow (based on ResourceInjectionAnnotationParsingProcessor) */ public class JPAAnnotationParseProcessor extends AbstractComponentConfigProcessor { private static final DotName PERSISTENCE_CONTEXT_ANNOTATION_NAME = DotName.createSimple(PersistenceContext.class.getName()); private static final DotName PERSISTENCE_UNIT_ANNOTATION_NAME = DotName.createSimple(PersistenceUnit.class.getName()); /** * Check the deployment annotation index for all classes with the @PersistenceContext annotation. * For each class with the annotation, collect all the required information to create a managed * bean instance, and attach it to the context. * * @param phaseContext the deployment unit context * @throws org.jboss.as.server.deployment.DeploymentUnitProcessingException */ protected void processComponentConfig( final DeploymentUnit deploymentUnit, final DeploymentPhaseContext phaseContext, final CompositeIndex compositeIndex, final AbstractComponentDescription componentDescription) throws DeploymentUnitProcessingException { final ClassInfo classInfo = compositeIndex.getClassByName( DotName.createSimple(componentDescription.getComponentClassName())); if (classInfo == null) { return; // We can't continue without the annotation index info. } componentDescription .getBindings() .addAll(getConfigurations(deploymentUnit, classInfo, componentDescription, phaseContext)); final Collection<InterceptorDescription> interceptorConfigurations = componentDescription.getAllInterceptors().values(); for (InterceptorDescription interceptorConfiguration : interceptorConfigurations) { final ClassInfo interceptorClassInfo = compositeIndex.getClassByName( DotName.createSimple(interceptorConfiguration.getInterceptorClassName())); if (interceptorClassInfo == null) { continue; } interceptorConfiguration .getBindings() .addAll( getConfigurations( deploymentUnit, interceptorClassInfo, componentDescription, phaseContext)); } } private List<BindingDescription> getConfigurations( final DeploymentUnit deploymentUnit, final ClassInfo classInfo, final AbstractComponentDescription componentDescription, final DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final List<BindingDescription> configurations = new ArrayList<BindingDescription>(); boolean isJPADeploymentMarker = false; final Map<DotName, List<AnnotationInstance>> classAnnotations = classInfo.annotations(); if (classAnnotations != null) { List<AnnotationInstance> resourceAnnotations = classAnnotations.get(PERSISTENCE_UNIT_ANNOTATION_NAME); if (resourceAnnotations != null && resourceAnnotations.size() > 0) { isJPADeploymentMarker = true; for (AnnotationInstance annotation : resourceAnnotations) { configurations.add( getConfiguration(deploymentUnit, annotation, componentDescription, phaseContext)); } } resourceAnnotations = classAnnotations.get(PERSISTENCE_CONTEXT_ANNOTATION_NAME); if (resourceAnnotations != null && resourceAnnotations.size() > 0) { isJPADeploymentMarker = true; for (AnnotationInstance annotation : resourceAnnotations) { configurations.add( getConfiguration(deploymentUnit, annotation, componentDescription, phaseContext)); } } } if (isJPADeploymentMarker) { JPADeploymentMarker.mark(deploymentUnit); } return configurations; } private BindingDescription getConfiguration( final DeploymentUnit deploymentUnit, final AnnotationInstance annotation, final AbstractComponentDescription componentDescription, final DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final AnnotationTarget annotationTarget = annotation.target(); final BindingDescription resourceConfiguration; if (annotationTarget instanceof FieldInfo) { resourceConfiguration = processField( deploymentUnit, annotation, FieldInfo.class.cast(annotationTarget), componentDescription, phaseContext); } else if (annotationTarget instanceof MethodInfo) { resourceConfiguration = processMethod( deploymentUnit, annotation, MethodInfo.class.cast(annotationTarget), componentDescription, phaseContext); } else if (annotationTarget instanceof ClassInfo) { resourceConfiguration = processClassResource( deploymentUnit, annotation, ClassInfo.class.cast(annotationTarget), componentDescription, phaseContext); } else { resourceConfiguration = null; } return resourceConfiguration; } private BindingDescription processField( final DeploymentUnit deploymentUnit, final AnnotationInstance annotation, final FieldInfo fieldInfo, final AbstractComponentDescription componentDescription, final DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final String fieldName = fieldInfo.name(); final AnnotationValue declaredNameValue = annotation.value("name"); final String declaredName = declaredNameValue != null ? declaredNameValue.asString() : null; final String localContextName; if (declaredName == null || declaredName.isEmpty()) { localContextName = "java:comp/env/persistence" + "/" + fieldName; } else { localContextName = declaredName; } // final AnnotationValue declaredTypeValue = annotation.value("type"); final DotName declaredType = fieldInfo.type().name(); final DotName injectionType = declaredType == null || declaredType.toString().equals(Object.class.getName()) ? fieldInfo.type().name() : declaredType; BindingDescription bindingDescription = new BindingDescription(); bindingDescription.setDependency(true); bindingDescription.setBindingName(localContextName); final String injectionTypeName = injectionType.toString(); bindingDescription.setBindingType(injectionTypeName); ServiceName injectorName = getInjectorServiceName( deploymentUnit, annotation, componentDescription, phaseContext, fieldName, injectionTypeName); bindingDescription.setReferenceSourceDescription( new ServiceBindingSourceDescription(injectorName)); // setup the injection target final InjectionTargetDescription targetDescription = new InjectionTargetDescription(); targetDescription.setName(fieldName); targetDescription.setClassName(fieldInfo.declaringClass().name().toString()); targetDescription.setType(InjectionTargetDescription.Type.FIELD); targetDescription.setValueClassName(injectionTypeName); bindingDescription.getInjectionTargetDescriptions().add(targetDescription); return bindingDescription; } private BindingDescription processMethod( final DeploymentUnit deploymentUnit, final AnnotationInstance annotation, final MethodInfo methodInfo, final AbstractComponentDescription componentDescription, final DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final String methodName = methodInfo.name(); if (!methodName.startsWith("set") || methodInfo.args().length != 1) { throw new IllegalArgumentException( "injection target is invalid. Only setter methods are allowed: " + methodInfo); } final String contextNameSuffix = methodName.substring(3, 4).toLowerCase() + methodName.substring(4); final AnnotationValue declaredNameValue = annotation.value("name"); final String declaredName = declaredNameValue != null ? declaredNameValue.asString() : null; final String localContextName; if (declaredName == null || declaredName.isEmpty()) { localContextName = methodInfo.declaringClass().name().toString() + "/" + contextNameSuffix; } else { localContextName = declaredName; } final DotName declaredType = methodInfo.returnType().name(); final DotName injectionType = declaredType == null || declaredType.toString().equals(Object.class.getName()) ? methodInfo.returnType().name() : declaredType; final BindingDescription bindingDescription = new BindingDescription(); bindingDescription.setDependency(true); bindingDescription.setBindingName(localContextName); final String injectionTypeName = injectionType.toString(); bindingDescription.setBindingType(injectionTypeName); ServiceName injectorName = getInjectorServiceName( deploymentUnit, annotation, componentDescription, phaseContext, methodName, injectionTypeName); bindingDescription.setReferenceSourceDescription( new ServiceBindingSourceDescription(injectorName)); // setup the injection target final InjectionTargetDescription targetDescription = new InjectionTargetDescription(); targetDescription.setName(methodName); targetDescription.setClassName(methodInfo.declaringClass().name().toString()); targetDescription.setType(InjectionTargetDescription.Type.METHOD); targetDescription.setValueClassName(injectionTypeName); bindingDescription.getInjectionTargetDescriptions().add(targetDescription); return bindingDescription; } private BindingDescription processClassResource( final DeploymentUnit deploymentUnit, final AnnotationInstance annotation, final ClassInfo classInfo, final AbstractComponentDescription componentDescription, final DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final AnnotationValue nameValue = annotation.value("name"); if (nameValue == null || nameValue.asString().isEmpty()) { throw new IllegalArgumentException("Class level annotations must provide a name."); } final String name = nameValue.asString(); final String type = classInfo.name().toString(); final BindingDescription bindingDescription = new BindingDescription(); bindingDescription.setDependency(true); bindingDescription.setBindingName(name); bindingDescription.setBindingType(type); ServiceName injectorName = getInjectorServiceName( deploymentUnit, annotation, componentDescription, phaseContext, name, type); bindingDescription.setReferenceSourceDescription( new ServiceBindingSourceDescription(injectorName)); return bindingDescription; } private ServiceName getInjectorServiceName( final DeploymentUnit deploymentUnit, final AnnotationInstance annotation, final AbstractComponentDescription componentDescription, final DeploymentPhaseContext phaseContext, final String targetName, String injectionTypeName) throws DeploymentUnitProcessingException { String scopedPuName = getScopedPuName(deploymentUnit, annotation); ServiceName puServiceName = getPuServiceName(scopedPuName); ServiceName injectorName = ServiceName.of( componentDescription.getModuleName(), componentDescription.getComponentClassName(), targetName); if (isPersistenceContext(annotation)) { phaseContext .getServiceTarget() .addService( injectorName, new PersistenceContextInjectorService( annotation, puServiceName, deploymentUnit, scopedPuName, injectionTypeName)) .addDependency(puServiceName) .setInitialMode(ServiceController.Mode.ACTIVE) .install(); } else { phaseContext .getServiceTarget() .addService( injectorName, new PersistenceUnitInjectorService( annotation, puServiceName, deploymentUnit, scopedPuName, injectionTypeName)) .addDependency(puServiceName) .setInitialMode(ServiceController.Mode.ACTIVE) .install(); } return injectorName; } private boolean isPersistenceContext(final AnnotationInstance annotation) { return annotation.name().local().equals("PersistenceContext"); } private String getScopedPuName( final DeploymentUnit deploymentUnit, final AnnotationInstance annotation) throws DeploymentUnitProcessingException { final AnnotationValue puName = annotation.value("unitName"); String scopedPuName; String searchName = null; // note: a null searchName will match the first PU definition found if (puName != null) { searchName = puName.asString(); } scopedPuName = PersistenceUnitSearch.resolvePersistenceUnitSupplier(deploymentUnit, searchName); if (null == scopedPuName) { throw new DeploymentUnitProcessingException( "Can't find a deployment unit named " + puName.asString() + " at " + deploymentUnit); } return scopedPuName; } private ServiceName getPuServiceName(String scopedPuName) throws DeploymentUnitProcessingException { return PersistenceUnitService.getPUServiceName(scopedPuName); } }
/** * JBoss AS integration helper class. * * @author <a href="*****@*****.**">Richard Opalka</a> * @author <a href="*****@*****.**">Alessio Soldano</a> */ public final class ASHelper { /** EJB invocation property. */ public static final String CONTAINER_NAME = "org.jboss.wsf.spi.invocation.ContainerName"; /** Logger. */ private static final Logger LOGGER = Logger.getLogger(ASHelper.class); /** @WebService jandex annotation. */ public static final DotName WEB_SERVICE_ANNOTATION = DotName.createSimple(WebService.class.getName()); /** @WebServiceProvider jandex annotation. */ public static final DotName WEB_SERVICE_PROVIDER_ANNOTATION = DotName.createSimple(WebServiceProvider.class.getName()); /** Forbidden constructor. */ private ASHelper() { super(); } /** * Returns true if unit contains JAXWS JSE, JAXRPC JSE, JAXWS EJB or JAXRPC EJB deployment. * * @param unit deployment unit * @return true if JAXWS JSE, JAXRPC JSE, JAXWS EJB or JAXRPC EJB deployment, false otherwise. */ public static boolean isWebServiceDeployment(final DeploymentUnit unit) { return ASHelper.getOptionalAttachment(unit, WSAttachmentKeys.DEPLOYMENT_TYPE_KEY) != null; } /** * Returns true if unit contains JAXRPC EJB deployment. * * @param unit deployment unit * @return true if JAXRPC EJB deployment, false otherwise */ public static boolean isJaxrpcEjbDeployment(final DeploymentUnit unit) { final DeploymentType deploymentType = ASHelper.getOptionalAttachment(unit, WSAttachmentKeys.DEPLOYMENT_TYPE_KEY); return DeploymentType.JAXRPC_EJB21.equals(deploymentType); } /** * Returns true if unit contains JAXRPC JSE deployment. * * @param unit deployment unit * @return true if JAXRPC JSE deployment, false otherwise */ public static boolean isJaxrpcJseDeployment(final DeploymentUnit unit) { final DeploymentType deploymentType = ASHelper.getOptionalAttachment(unit, WSAttachmentKeys.DEPLOYMENT_TYPE_KEY); return DeploymentType.JAXRPC_JSE.equals(deploymentType); } /** * Returns true if unit contains JAXWS EJB deployment. * * @param unit deployment unit * @return true if JAXWS EJB deployment, false otherwise */ public static boolean isJaxwsEjbDeployment(final DeploymentUnit unit) { final DeploymentType deploymentType = ASHelper.getOptionalAttachment(unit, WSAttachmentKeys.DEPLOYMENT_TYPE_KEY); return DeploymentType.JAXWS_EJB3.equals(deploymentType); } /** * Returns true if unit contains JAXWS JSE deployment. * * @param unit deployment unit * @return true if JAXWS JSE deployment, false otherwise */ public static boolean isJaxwsJseDeployment(final DeploymentUnit unit) { final DeploymentType deploymentType = ASHelper.getOptionalAttachment(unit, WSAttachmentKeys.DEPLOYMENT_TYPE_KEY); return DeploymentType.JAXWS_JSE.equals(deploymentType); } /** * Returns true if unit contains either JAXWS JSE or JAXRPC JSE deployment. * * @param unit deployment unit * @return true if either JAXWS JSE or JAXRPC JSE deployment, false otherwise. */ public static boolean isJseDeployment(final DeploymentUnit unit) { final boolean isJaxwsJse = ASHelper.isJaxwsJseDeployment(unit); final boolean isJaxrpcJse = ASHelper.isJaxrpcJseDeployment(unit); return isJaxwsJse || isJaxrpcJse; } /** * Returns true if unit contains either JAXWS EJB or JAXRPC EJB deployment. * * @param unit deployment unit * @return true if either JAXWS EJB or JAXRPC EJB deployment, false otherwise */ public static boolean isEjbDeployment(final DeploymentUnit unit) { final boolean isJaxwsEjb = ASHelper.isJaxwsEjbDeployment(unit); final boolean isJaxrpcEjb = ASHelper.isJaxrpcEjbDeployment(unit); return isJaxwsEjb || isJaxrpcEjb; } /** * Returns true if unit contains either JAXWS EJB or JAXWS JSE deployment. * * @param unit deployment unit * @return true if either JAXWS EJB or JAXWS JSE deployment, false otherwise */ public static boolean isJaxwsDeployment(final DeploymentUnit unit) { final boolean isJaxwsEjb = ASHelper.isJaxwsEjbDeployment(unit); final boolean isJaxwsJse = ASHelper.isJaxwsJseDeployment(unit); return isJaxwsEjb || isJaxwsJse; } /** * Returns true if unit contains either JAXRPC EJB or JAXRPC JSE deployment. * * @param unit deployment unit * @return true if either JAXRPC EJB or JAXRPC JSE deployment, false otherwise */ public static boolean isJaxrpcDeployment(final DeploymentUnit unit) { final boolean isJaxrpcEjb = ASHelper.isJaxrpcEjbDeployment(unit); final boolean isJaxrpcJse = ASHelper.isJaxrpcJseDeployment(unit); return isJaxrpcEjb || isJaxrpcJse; } /** * Gets list of JAXWS servlets meta data. * * @param unit deployment unit * @return list of JAXWS servlets meta data */ public static List<ServletMetaData> getJaxwsServlets(final DeploymentUnit unit) { return ASHelper.getWebServiceServlets(unit, true); } /** * Gets list of JAXRPC servlets meta data. * * @param unit deployment unit * @return list of JAXRPC servlets meta data */ public static List<ServletMetaData> getJaxrpcServlets(final DeploymentUnit unit) { return ASHelper.getWebServiceServlets(unit, false); } /** * Gets list of JAXWS EJBs meta data. * * @param unit deployment unit * @return list of JAXWS EJBs meta data */ public static List<WebServiceDeclaration> getJaxwsEjbs(final DeploymentUnit unit) { final WebServiceDeployment wsDeployment = ASHelper.getRequiredAttachment(unit, WSAttachmentKeys.WEBSERVICE_DEPLOYMENT_KEY); return Collections.unmodifiableList(wsDeployment.getServiceEndpoints()); } /** * Returns endpoint class name. * * @param servletMD servlet meta data * @return endpoint class name */ public static String getEndpointName(final ServletMetaData servletMD) { final String endpointClass = servletMD.getServletClass(); return endpointClass != null ? endpointClass.trim() : null; } /** * Returns servlet meta data for requested servlet name. * * @param jbossWebMD jboss web meta data * @param servletName servlet name * @return servlet meta data */ public static ServletMetaData getServletForName( final JBossWebMetaData jbossWebMD, final String servletName) { for (JBossServletMetaData servlet : jbossWebMD.getServlets()) { if (servlet.getName().equals(servletName)) { return servlet; } } throw new IllegalStateException("Cannot find servlet for link: " + servletName); } /** * Returns required attachment value from deployment unit. * * @param <A> expected value * @param unit deployment unit * @param key attachment key * @return required attachment * @throws IllegalStateException if attachment value is null */ public static <A> A getRequiredAttachment(final DeploymentUnit unit, final AttachmentKey<A> key) { final A value = unit.getAttachment(key); if (value == null) { ASHelper.LOGGER.error("Cannot find attachment in deployment unit: " + key); throw new IllegalStateException(); } return value; } /** * Returns optional attachment value from deployment unit or null if not bound. * * @param <A> expected value * @param unit deployment unit * @param key attachment key * @return optional attachment value or null */ public static <A> A getOptionalAttachment(final DeploymentUnit unit, final AttachmentKey<A> key) { return unit.getAttachment(key); } /** * Returns true if deployment unit have attachment value associated with the <b>key</b>. * * @param unit deployment unit * @param key attachment key * @return true if contains attachment, false otherwise */ public static boolean hasAttachment(final DeploymentUnit unit, final AttachmentKey<?> key) { return ASHelper.getOptionalAttachment(unit, key) != null; } /** * Returns first webservice description meta data or null if not found. * * @param wsDescriptionsMD webservice descriptions * @return webservice description */ public static WebserviceDescriptionMetaData getWebserviceDescriptionMetaData( final WebserviceDescriptionsMetaData wsDescriptionsMD) { if (wsDescriptionsMD != null) { if (wsDescriptionsMD.size() > 1) { ASHelper.LOGGER.warn("Multiple <webservice-description> elements not supported"); } if (wsDescriptionsMD.size() > 0) { return wsDescriptionsMD.iterator().next(); } } return null; } /** * Gets list of JAXRPC or JAXWS servlets meta data. * * @param unit deployment unit * @param jaxws if passed value is <b>true</b> JAXWS servlets list will be returned, otherwise * JAXRPC servlets list * @return either JAXRPC or JAXWS servlets list */ private static List<ServletMetaData> getWebServiceServlets( final DeploymentUnit unit, final boolean jaxws) { final JBossWebMetaData jbossWebMD = getJBossWebMetaData(unit); final List<Index> annotationIndexes = getRootAnnotationIndexes(unit); return selectWebServiceServlets(annotationIndexes, jbossWebMD.getServlets(), jaxws); } /** * Return a new sublist of the provided ServletMetaData list including the WS servlet data only * * @param annotationIndex the annotation index to use for scanning for annotations * @param smd the initial servlet metadata collection * @param jaxws if passed value is <b>true</b> JAXWS servlets list will be returned, otherwise * JAXRPC servlets list * @return either JAXRPC or JAXWS servlets list */ public static <T extends ServletMetaData> List<ServletMetaData> selectWebServiceServlets( final List<Index> indexes, final Collection<T> smd, final boolean jaxws) { if (smd == null) return Collections.emptyList(); final List<ServletMetaData> endpoints = new ArrayList<ServletMetaData>(); for (final ServletMetaData servletMD : smd) { final boolean isWebServiceEndpoint = isWebserviceEndpoint(servletMD, indexes); final boolean isJaxwsEndpoint = jaxws && isWebServiceEndpoint; final boolean isJaxrpcEndpoint = !jaxws && isWebServiceEndpoint; if (isJaxwsEndpoint || isJaxrpcEndpoint) { endpoints.add(servletMD); } } return endpoints; } private static boolean isWebserviceEndpoint( final ServletMetaData servletMD, final List<Index> annotationIndexes) { final String endpointClassName = ASHelper.getEndpointName(servletMD); if (isJSP(endpointClassName)) return false; final DotName endpointDN = DotName.createSimple(endpointClassName); ClassInfo endpointClassInfo = null; for (final Index index : annotationIndexes) { endpointClassInfo = index.getClassByName(endpointDN); if (endpointClassInfo != null) { if (endpointClassInfo.annotations().containsKey(WEB_SERVICE_ANNOTATION)) return true; if (endpointClassInfo.annotations().containsKey(WEB_SERVICE_PROVIDER_ANNOTATION)) return true; } } return false; } private static boolean isJSP(final String endpointClassName) { return endpointClassName == null || endpointClassName.length() == 0; } /** * Gets the JBossWebMetaData from the WarMetaData attached to the provided deployment unit, if * any. * * @param unit * @return the JBossWebMetaData or null if either that or the parent WarMetaData are not found. */ public static JBossWebMetaData getJBossWebMetaData(final DeploymentUnit unit) { final WarMetaData warMetaData = ASHelper.getOptionalAttachment(unit, WarMetaData.ATTACHMENT_KEY); JBossWebMetaData result = null; if (warMetaData != null) { result = warMetaData.getMergedJBossWebMetaData(); if (result == null) { result = warMetaData.getJbossWebMetaData(); } } return result; } public static List<Index> getRootAnnotationIndexes(final DeploymentUnit unit) { final Map<ResourceRoot, Index> indexes = AnnotationIndexUtils.getAnnotationIndexes(unit); final List<Index> retVal = new LinkedList<Index>(); for (final ResourceRoot rr : indexes.keySet()) { if (ModuleRootMarker.isModuleRoot(rr)) { retVal.add(indexes.get(rr)); } } return retVal; } }
/** User: jpai */ public class SessionBeanComponentDescriptionFactory extends EJBComponentDescriptionFactory { private static final DotName STATELESS_ANNOTATION = DotName.createSimple(Stateless.class.getName()); private static final DotName STATEFUL_ANNOTATION = DotName.createSimple(Stateful.class.getName()); private static final DotName SINGLETON_ANNOTATION = DotName.createSimple(Singleton.class.getName()); public SessionBeanComponentDescriptionFactory(final boolean appclient) { super(appclient); } /** Process annotations and merge any available metadata at the same time. */ @Override protected void processAnnotations( final DeploymentUnit deploymentUnit, final CompositeIndex compositeIndex) throws DeploymentUnitProcessingException { if (MetadataCompleteMarker.isMetadataComplete(deploymentUnit)) { return; } // Find and process any @Stateless bean annotations final List<AnnotationInstance> slsbAnnotations = compositeIndex.getAnnotations(STATELESS_ANNOTATION); if (!slsbAnnotations.isEmpty()) { processSessionBeans( deploymentUnit, slsbAnnotations, SessionBeanComponentDescription.SessionBeanType.STATELESS); } // Find and process any @Stateful bean annotations final List<AnnotationInstance> sfsbAnnotations = compositeIndex.getAnnotations(STATEFUL_ANNOTATION); if (!sfsbAnnotations.isEmpty()) { processSessionBeans( deploymentUnit, sfsbAnnotations, SessionBeanComponentDescription.SessionBeanType.STATEFUL); } // Find and process any @Singleton bean annotations final List<AnnotationInstance> sbAnnotations = compositeIndex.getAnnotations(SINGLETON_ANNOTATION); if (!sbAnnotations.isEmpty()) { processSessionBeans( deploymentUnit, sbAnnotations, SessionBeanComponentDescription.SessionBeanType.SINGLETON); } } @Override protected void processBeanMetaData( final DeploymentUnit deploymentUnit, final EnterpriseBeanMetaData enterpriseBeanMetaData) throws DeploymentUnitProcessingException { if (enterpriseBeanMetaData.isSession()) { assert enterpriseBeanMetaData instanceof SessionBeanMetaData : enterpriseBeanMetaData + " is not a SessionBeanMetaData"; processSessionBeanMetaData(deploymentUnit, (SessionBeanMetaData) enterpriseBeanMetaData); } } private void processSessionBeans( final DeploymentUnit deploymentUnit, final List<AnnotationInstance> sessionBeanAnnotations, final SessionBeanComponentDescription.SessionBeanType annotatedSessionBeanType) { final EjbJarDescription ejbJarDescription = getEjbJarDescription(deploymentUnit); final ServiceName deploymentUnitServiceName = deploymentUnit.getServiceName(); // process these session bean annotations and create component descriptions out of it for (final AnnotationInstance sessionBeanAnnotation : sessionBeanAnnotations) { final AnnotationTarget target = sessionBeanAnnotation.target(); if (!(target instanceof ClassInfo)) { // Let's just WARN and move on. No need to throw an error EjbMessages.MESSAGES.annotationOnlyAllowedOnClass( sessionBeanAnnotation.name().toString(), target); continue; } final ClassInfo sessionBeanClassInfo = (ClassInfo) target; // skip if it's not a valid class for session bean if (!assertSessionBeanClassValidity(sessionBeanClassInfo)) { continue; } final String ejbName = sessionBeanClassInfo.name().local(); final AnnotationValue nameValue = sessionBeanAnnotation.value("name"); final String beanName = nameValue == null || nameValue.asString().isEmpty() ? ejbName : nameValue.asString(); final SessionBeanMetaData beanMetaData = getEnterpriseBeanMetaData(deploymentUnit, beanName, SessionBeanMetaData.class); final SessionBeanComponentDescription.SessionBeanType sessionBeanType; final String beanClassName; if (beanMetaData != null) { beanClassName = override(sessionBeanClassInfo.name().toString(), beanMetaData.getEjbClass()); sessionBeanType = override( annotatedSessionBeanType, descriptionOf(((SessionBeanMetaData) beanMetaData).getSessionType())); } else { beanClassName = sessionBeanClassInfo.name().toString(); sessionBeanType = annotatedSessionBeanType; } final SessionBeanComponentDescription sessionBeanDescription; switch (sessionBeanType) { case STATELESS: sessionBeanDescription = new StatelessComponentDescription( beanName, beanClassName, ejbJarDescription, deploymentUnitServiceName, beanMetaData); break; case STATEFUL: sessionBeanDescription = new StatefulComponentDescription( beanName, beanClassName, ejbJarDescription, deploymentUnitServiceName, beanMetaData); // If passivation is disabled for the SFSB, either via annotation or via DD, then setup // the component // description appropriately final boolean passivationCapableAnnotationValue = sessionBeanAnnotation.value("passivationCapable") == null ? true : sessionBeanAnnotation.value("passivationCapable").asBoolean(); // TODO: Pass the DD value as first param for override final boolean passivationApplicable = override(null, passivationCapableAnnotationValue); ((StatefulComponentDescription) sessionBeanDescription) .setPassivationApplicable(passivationApplicable); break; case SINGLETON: sessionBeanDescription = new SingletonComponentDescription( beanName, beanClassName, ejbJarDescription, deploymentUnitServiceName, beanMetaData); break; default: throw EjbMessages.MESSAGES.unknownSessionBeanType(sessionBeanType.name()); } addComponent(deploymentUnit, sessionBeanDescription); } EjbDeploymentMarker.mark(deploymentUnit); } private static SessionBeanComponentDescription.SessionBeanType descriptionOf( final SessionType sessionType) { if (sessionType == null) return null; switch (sessionType) { case Stateless: return SessionBeanComponentDescription.SessionBeanType.STATELESS; case Stateful: return SessionBeanComponentDescription.SessionBeanType.STATEFUL; case Singleton: return SessionBeanComponentDescription.SessionBeanType.SINGLETON; default: throw EjbMessages.MESSAGES.unknownSessionBeanType(sessionType.name()); } } /** * Returns true if the passed <code>sessionBeanClass</code> meets the requirements set by the EJB3 * spec about bean implementation classes. The passed <code>sessionBeanClass</code> must not be an * interface and must be public and not final and not abstract. If it passes these requirements * then this method returns true. Else it returns false. * * @param sessionBeanClass The session bean class * @return */ private static boolean assertSessionBeanClassValidity(final ClassInfo sessionBeanClass) { final short flags = sessionBeanClass.flags(); final String className = sessionBeanClass.name().toString(); // must *not* be a interface if (Modifier.isInterface(flags)) { EjbLogger.EJB3_LOGGER.sessionBeanClassCannotBeAnInterface(className); return false; } // bean class must be public, must *not* be abstract or final if (!Modifier.isPublic(flags) || Modifier.isAbstract(flags) || Modifier.isFinal(flags)) { EjbLogger.EJB3_LOGGER.sessionBeanClassMustBePublicNonAbstractNonFinal(className); return false; } // valid class return true; } private void processSessionBeanMetaData( final DeploymentUnit deploymentUnit, final SessionBeanMetaData sessionBean) throws DeploymentUnitProcessingException { final EjbJarDescription ejbJarDescription = getEjbJarDescription(deploymentUnit); final CompositeIndex compositeIndex = deploymentUnit.getAttachment( org.jboss.as.server.deployment.Attachments.COMPOSITE_ANNOTATION_INDEX); final String beanName = sessionBean.getName(); SessionType sessionType = sessionBean.getSessionType(); if (sessionType == null && sessionBean instanceof GenericBeanMetaData) { final GenericBeanMetaData bean = (GenericBeanMetaData) sessionBean; if (bean.getEjbType() == EjbType.SESSION) { sessionType = determineSessionType(sessionBean.getEjbClass(), compositeIndex); if (sessionType == null) { throw EjbMessages.MESSAGES.sessionTypeNotSpecified(beanName); } } else { // it is not a session bean, so we ignore it return; } } else if (sessionType == null) { sessionType = determineSessionType(sessionBean.getEjbClass(), compositeIndex); if (sessionType == null) { throw EjbMessages.MESSAGES.sessionTypeNotSpecified(beanName); } } final String beanClassName = sessionBean.getEjbClass(); final SessionBeanComponentDescription sessionBeanDescription; switch (sessionType) { case Stateless: sessionBeanDescription = new StatelessComponentDescription( beanName, beanClassName, ejbJarDescription, deploymentUnit.getServiceName(), sessionBean); break; case Stateful: sessionBeanDescription = new StatefulComponentDescription( beanName, beanClassName, ejbJarDescription, deploymentUnit.getServiceName(), sessionBean); // TODO: Handle passivation capable for stateful beans in EJB3.2 break; case Singleton: sessionBeanDescription = new SingletonComponentDescription( beanName, beanClassName, ejbJarDescription, deploymentUnit.getServiceName(), sessionBean); break; default: throw EjbMessages.MESSAGES.unknownSessionBeanType(sessionType.name()); } addComponent(deploymentUnit, sessionBeanDescription); } private SessionType determineSessionType( final String ejbClass, final CompositeIndex compositeIndex) { if (ejbClass == null) { return null; } final ClassInfo info = compositeIndex.getClassByName(DotName.createSimple(ejbClass)); if (info == null) { return null; } if (info.annotations().get(STATEFUL_ANNOTATION) != null) { return SessionType.Stateful; } else if (info.annotations().get(STATELESS_ANNOTATION) != null) { return SessionType.Stateless; } else if (info.annotations().get(SINGLETON_ANNOTATION) != null) { return SessionType.Singleton; } return null; } }
/** User: jpai */ public class MessageDrivenComponentDescriptionFactory extends EJBComponentDescriptionFactory { private static final DotName MESSAGE_DRIVEN_ANNOTATION_NAME = DotName.createSimple(MessageDriven.class.getName()); public MessageDrivenComponentDescriptionFactory(final boolean appclient) { super(appclient); } @Override protected void processAnnotations(DeploymentUnit deploymentUnit, CompositeIndex compositeIndex) throws DeploymentUnitProcessingException { if (MetadataCompleteMarker.isMetadataComplete(deploymentUnit)) { return; } processMessageBeans( deploymentUnit, compositeIndex.getAnnotations(MESSAGE_DRIVEN_ANNOTATION_NAME), compositeIndex); } @Override protected void processBeanMetaData( final DeploymentUnit deploymentUnit, final EnterpriseBeanMetaData enterpriseBeanMetaData) throws DeploymentUnitProcessingException { if (enterpriseBeanMetaData.isMessageDriven()) { assert enterpriseBeanMetaData instanceof MessageDrivenBeanMetaData : enterpriseBeanMetaData + " is not a MessageDrivenBeanMetaData"; processMessageDrivenBeanMetaData( deploymentUnit, (MessageDrivenBeanMetaData) enterpriseBeanMetaData); } } private void processMessageBeans( final DeploymentUnit deploymentUnit, final Collection<AnnotationInstance> messageBeanAnnotations, final CompositeIndex compositeIndex) throws DeploymentUnitProcessingException { if (messageBeanAnnotations.isEmpty()) return; final EjbJarDescription ejbJarDescription = getEjbJarDescription(deploymentUnit); final ServiceName deploymentUnitServiceName = deploymentUnit.getServiceName(); DeploymentDescriptorEnvironment deploymentDescriptorEnvironment = null; for (final AnnotationInstance messageBeanAnnotation : messageBeanAnnotations) { final AnnotationTarget target = messageBeanAnnotation.target(); final ClassInfo beanClassInfo = (ClassInfo) target; if (!assertMDBClassValidity(beanClassInfo)) { continue; } final String ejbName = beanClassInfo.name().local(); final AnnotationValue nameValue = messageBeanAnnotation.value("name"); final String beanName = nameValue == null || nameValue.asString().isEmpty() ? ejbName : nameValue.asString(); final MessageDrivenBeanMetaData beanMetaData = getEnterpriseBeanMetaData(deploymentUnit, beanName, MessageDrivenBeanMetaData.class); final String beanClassName; final String messageListenerInterfaceName; boolean replacement = deploymentUnit.getAttachment(Attachments.EJB_ANNOTATION_PROPERTY_REPLACEMENT); final Properties activationConfigProperties = getActivationConfigProperties(messageBeanAnnotation, replacement); final String messagingType; if (beanMetaData != null) { beanClassName = override(beanClassInfo.name().toString(), beanMetaData.getEjbClass()); deploymentDescriptorEnvironment = new DeploymentDescriptorEnvironment("java:comp/env/", beanMetaData); if (beanMetaData instanceof MessageDrivenBeanMetaData) { // It may actually be GenericBeanMetadata instance final MessageDrivenBeanMetaData mdb = (MessageDrivenBeanMetaData) beanMetaData; messagingType = mdb.getMessagingType(); final ActivationConfigMetaData activationConfigMetaData = mdb.getActivationConfig(); if (activationConfigMetaData != null) { final ActivationConfigPropertiesMetaData propertiesMetaData = activationConfigMetaData.getActivationConfigProperties(); if (propertiesMetaData != null) { for (final ActivationConfigPropertyMetaData propertyMetaData : propertiesMetaData) { activationConfigProperties.put( propertyMetaData.getKey(), propertyMetaData.getValue()); } } } } else if (beanMetaData instanceof JBossGenericBeanMetaData) { // TODO: fix the hierarchy so this is not needed final JBossGenericBeanMetaData mdb = (JBossGenericBeanMetaData) beanMetaData; messagingType = mdb.getMessagingType(); final ActivationConfigMetaData activationConfigMetaData = mdb.getActivationConfig(); if (activationConfigMetaData != null) { final ActivationConfigPropertiesMetaData propertiesMetaData = activationConfigMetaData.getActivationConfigProperties(); if (propertiesMetaData != null) { for (final ActivationConfigPropertyMetaData propertyMetaData : propertiesMetaData) { activationConfigProperties.put( propertyMetaData.getKey(), propertyMetaData.getValue()); } } } } else { messagingType = null; } messageListenerInterfaceName = messagingType != null ? messagingType : getMessageListenerInterface(compositeIndex, messageBeanAnnotation); } else { beanClassName = beanClassInfo.name().toString(); messageListenerInterfaceName = getMessageListenerInterface(compositeIndex, messageBeanAnnotation); } final String defaultResourceAdapterName = this.getDefaultResourceAdapterName(deploymentUnit.getServiceRegistry()); final MessageDrivenComponentDescription beanDescription = new MessageDrivenComponentDescription( beanName, beanClassName, ejbJarDescription, deploymentUnitServiceName, messageListenerInterfaceName, activationConfigProperties, defaultResourceAdapterName, beanMetaData); beanDescription.setDeploymentDescriptorEnvironment(deploymentDescriptorEnvironment); addComponent(deploymentUnit, beanDescription); } EjbDeploymentMarker.mark(deploymentUnit); } private String getMessageListenerInterface( final CompositeIndex compositeIndex, final AnnotationInstance messageBeanAnnotation) throws DeploymentUnitProcessingException { final AnnotationValue value = messageBeanAnnotation.value("messageListenerInterface"); if (value != null) return value.asClass().name().toString(); final ClassInfo beanClass = (ClassInfo) messageBeanAnnotation.target(); final Set<DotName> interfaces = new HashSet<DotName>(getPotentialViewInterfaces(beanClass)); // check super class(es) of the bean DotName superClassDotName = beanClass.superName(); while (interfaces.isEmpty() && superClassDotName != null && !superClassDotName.toString().equals(Object.class.getName())) { final ClassInfo superClass = compositeIndex.getClassByName(superClassDotName); if (superClass == null) { break; } interfaces.addAll(getPotentialViewInterfaces(superClass)); // move to next super class superClassDotName = superClass.superName(); } if (interfaces.size() != 1) throw MESSAGES.mdbDoesNotImplementNorSpecifyMessageListener(beanClass); return interfaces.iterator().next().toString(); } /** * Returns true if the passed <code>mdbClass</code> meets the requirements set by the EJB3 spec * about bean implementation classes. The passed <code>mdbClass</code> must not be an interface * and must be public and not final and not abstract. If it passes these requirements then this * method returns true. Else it returns false. * * @param mdbClass The MDB class * @return */ private boolean assertMDBClassValidity(final ClassInfo mdbClass) { final short flags = mdbClass.flags(); final String className = mdbClass.name().toString(); // must *not* be a interface if (Modifier.isInterface(flags)) { EjbLogger.EJB3_LOGGER.mdbClassCannotBeAnInterface(className); return false; } // bean class must be public, must *not* be abstract or final if (!Modifier.isPublic(flags) || Modifier.isAbstract(flags) || Modifier.isFinal(flags)) { EjbLogger.EJB3_LOGGER.mdbClassMustBePublicNonAbstractNonFinal(className); return false; } // valid class return true; } private Properties getActivationConfigProperties( final ActivationConfigMetaData activationConfig) { final Properties activationConfigProps = new Properties(); if (activationConfig == null || activationConfig.getActivationConfigProperties() == null) { return activationConfigProps; } final ActivationConfigPropertiesMetaData activationConfigPropertiesMetaData = activationConfig.getActivationConfigProperties(); for (ActivationConfigPropertyMetaData activationConfigProp : activationConfigPropertiesMetaData) { if (activationConfigProp == null) { continue; } final String propName = activationConfigProp.getActivationConfigPropertyName(); final String propValue = activationConfigProp.getValue(); if (propName != null) { activationConfigProps.put(propName, propValue); } } return activationConfigProps; } private void processMessageDrivenBeanMetaData( final DeploymentUnit deploymentUnit, final MessageDrivenBeanMetaData mdb) throws DeploymentUnitProcessingException { final EjbJarDescription ejbJarDescription = getEjbJarDescription(deploymentUnit); final String beanName = mdb.getName(); final String beanClassName = mdb.getEjbClass(); String messageListenerInterface = mdb.getMessagingType(); if (messageListenerInterface == null || messageListenerInterface.trim().isEmpty()) { // TODO: This isn't really correct to default to MessageListener messageListenerInterface = MessageListener.class.getName(); } final Properties activationConfigProps = getActivationConfigProperties(mdb.getActivationConfig()); final String defaultResourceAdapterName = this.getDefaultResourceAdapterName(deploymentUnit.getServiceRegistry()); final MessageDrivenComponentDescription mdbComponentDescription = new MessageDrivenComponentDescription( beanName, beanClassName, ejbJarDescription, deploymentUnit.getServiceName(), messageListenerInterface, activationConfigProps, defaultResourceAdapterName, mdb); mdbComponentDescription.setDeploymentDescriptorEnvironment( new DeploymentDescriptorEnvironment("java:comp/env/", mdb)); addComponent(deploymentUnit, mdbComponentDescription); } private Properties getActivationConfigProperties( final AnnotationInstance messageBeanAnnotation, boolean replacement) { final Properties props = new Properties(); final AnnotationValue activationConfig = messageBeanAnnotation.value("activationConfig"); if (activationConfig == null) return props; for (final AnnotationInstance propAnnotation : activationConfig.asNestedArray()) { String propertyName = propAnnotation.value("propertyName").asString(); String propertyValue = propAnnotation.value("propertyValue").asString(); if (replacement) props.put(propertyName, PropertiesValueResolver.replaceProperties(propertyValue)); else props.put(propertyName, propertyValue); } return props; } /** * Returns the name of the resource adapter which will be used as the default RA for MDBs (unless * overridden by the MDBs). * * @param serviceRegistry * @return */ private String getDefaultResourceAdapterName(final ServiceRegistry serviceRegistry) { if (appclient) { // we must report the MDB, but we can't use any MDB/JCA facilities return "n/a"; } final ServiceController<DefaultResourceAdapterService> serviceController = (ServiceController<DefaultResourceAdapterService>) serviceRegistry.getRequiredService( DefaultResourceAdapterService.DEFAULT_RA_NAME_SERVICE_NAME); return serviceController.getValue().getDefaultResourceAdapterName(); } }
/** * Byte hacks / utils. * * @author <a href="mailto:[email protected]">Ales Justin</a> */ public final class BytecodeUtils extends AbstractDependencyResolver implements ModuleInfoReader { public static BytecodeUtils INSTANCE = new BytecodeUtils(); private BytecodeUtils() {} private static final DotName MODULE_ANNOTATION = DotName.createSimple("com.redhat.ceylon.compiler.java.metadata.Module"); private static final DotName PACKAGE_ANNOTATION = DotName.createSimple("com.redhat.ceylon.compiler.java.metadata.Package"); private static final DotName CEYLON_ANNOTATION = DotName.createSimple("com.redhat.ceylon.compiler.java.metadata.Ceylon"); private static final DotName IGNORE_ANNOTATION = DotName.createSimple("com.redhat.ceylon.compiler.java.metadata.Ignore"); private static final DotName LOCAL_CONTAINER_ANNOTATION = DotName.createSimple("com.redhat.ceylon.compiler.java.metadata.LocalContainer"); @Override public ModuleInfo resolve(DependencyContext context, Overrides overrides) { if (context.ignoreInner()) { return null; } final ArtifactResult result = context.result(); return readModuleInformation(result.name(), result.artifact(), overrides); } @Override public ModuleInfo resolveFromFile(File file, String name, String version, Overrides overrides) { throw new UnsupportedOperationException("Operation not supported for .car files"); } @Override public ModuleInfo resolveFromInputStream( InputStream stream, String name, String version, Overrides overrides) { throw new UnsupportedOperationException("Operation not supported for .car files"); } @Override public Node descriptor(Node artifact) { return null; // artifact is a descriptor } /** * Read module info from bytecode. * * @param moduleName the module name * @param jarFile the module jar file * @return module info list */ private static ModuleInfo readModuleInformation( final String moduleName, final File jarFile, Overrides overrides) { Index index = readModuleIndex(jarFile, false); final AnnotationInstance ai = getAnnotation(index, moduleName, MODULE_ANNOTATION); if (ai == null) return null; final AnnotationValue version = ai.value("version"); if (version == null) return null; final AnnotationValue dependencies = ai.value("dependencies"); if (dependencies == null) return new ModuleInfo(null, Collections.<ModuleDependencyInfo>emptySet()); final Set<ModuleDependencyInfo> infos = new LinkedHashSet<ModuleDependencyInfo>(); final AnnotationInstance[] imports = dependencies.asNestedArray(); if (imports != null) { for (AnnotationInstance im : imports) { final String name = asString(im, "name"); final ModuleDependencyInfo mi = new ModuleDependencyInfo( name, asString(im, "version"), asBoolean(im, "optional"), asBoolean(im, "export")); infos.add(mi); } } ModuleInfo ret = new ModuleInfo(null, infos); if (overrides != null) ret = overrides.applyOverrides(moduleName, version.asString(), ret); return ret; } private static Index readModuleIndex(final File jarFile, boolean everything) { try { try (JarFile jar = new JarFile(jarFile)) { Enumeration<JarEntry> entries = jar.entries(); Indexer indexer = new Indexer(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String name = entry.getName().toLowerCase(); if (everything && name.endsWith(".class") || name.endsWith("/module_.class") || name.endsWith("/$module_.class")) { try (InputStream stream = jar.getInputStream(entry)) { indexer.index(stream); } } } return indexer.complete(); } } catch (IOException e) { throw new RuntimeException("Failed to read index for module " + jarFile.getPath(), e); } } private static ClassInfo getModuleInfo(final Index index, final String moduleName) { // we need to escape any java keyword from the package list String quotedModuleName = JVMModuleUtil.quoteJavaKeywords(moduleName); DotName moduleClassName = DotName.createSimple(quotedModuleName + ".$module_"); ClassInfo ret = index.getClassByName(moduleClassName); if (ret == null) { // read previous module descriptor name moduleClassName = DotName.createSimple(quotedModuleName + ".module_"); ret = index.getClassByName(moduleClassName); } return ret; } @Override public int[] getBinaryVersions(String moduleName, String moduleVersion, File moduleArchive) { Index index = readModuleIndex(moduleArchive, false); final AnnotationInstance ceylonAnnotation = getAnnotation(index, moduleName, CEYLON_ANNOTATION); if (ceylonAnnotation == null) return null; AnnotationValue majorAnnotation = ceylonAnnotation.value("major"); AnnotationValue minorAnnotation = ceylonAnnotation.value("minor"); int major = majorAnnotation != null ? majorAnnotation.asInt() : 0; int minor = minorAnnotation != null ? minorAnnotation.asInt() : 0; return new int[] {major, minor}; } @Override public ModuleVersionDetails readModuleInfo( String moduleName, String moduleVersion, File moduleArchive, boolean includeMembers, Overrides overrides) { Index index = readModuleIndex(moduleArchive, true); final AnnotationInstance moduleAnnotation = getAnnotation(index, moduleName, MODULE_ANNOTATION); if (moduleAnnotation == null) return null; AnnotationValue doc = moduleAnnotation.value("doc"); AnnotationValue license = moduleAnnotation.value("license"); AnnotationValue by = moduleAnnotation.value("by"); AnnotationValue dependencies = moduleAnnotation.value("dependencies"); String type = ArtifactContext.getSuffixFromFilename(moduleArchive.getName()); final AnnotationInstance ceylonAnnotation = getAnnotation(index, moduleName, CEYLON_ANNOTATION); if (ceylonAnnotation == null) return null; AnnotationValue majorVer = ceylonAnnotation.value("major"); AnnotationValue minorVer = ceylonAnnotation.value("minor"); ModuleVersionDetails mvd = new ModuleVersionDetails( moduleName, getVersionFromFilename(moduleName, moduleArchive.getName())); mvd.setDoc(doc != null ? doc.asString() : null); mvd.setLicense(license != null ? license.asString() : null); if (by != null) { mvd.getAuthors().addAll(Arrays.asList(by.asStringArray())); } mvd.getDependencies() .addAll(getDependencies(dependencies, moduleName, mvd.getVersion(), overrides)); ModuleVersionArtifact mva = new ModuleVersionArtifact( type, majorVer != null ? majorVer.asInt() : 0, minorVer != null ? minorVer.asInt() : 0); mvd.getArtifactTypes().add(mva); if (includeMembers) { mvd.setMembers(getMembers(index)); } return mvd; } private Set<String> getMembers(Index index) { HashSet<String> members = new HashSet<>(); for (ClassInfo cls : index.getKnownClasses()) { if (shouldAddMember(cls)) { members.add(classNameToDeclName(cls.name().toString())); } } return members; } private boolean shouldAddMember(ClassInfo cls) { // ignore what we must ignore if (getClassAnnotation(cls, IGNORE_ANNOTATION) != null) { return false; } // ignore module and package descriptors if (getClassAnnotation(cls, MODULE_ANNOTATION) != null || getClassAnnotation(cls, PACKAGE_ANNOTATION) != null) { return false; } // ignore local types if (getClassAnnotation(cls, LOCAL_CONTAINER_ANNOTATION) != null) { return false; } return true; } private AnnotationInstance getClassAnnotation(ClassInfo cls, DotName annoName) { List<AnnotationInstance> annos = cls.annotations().get(annoName); if (annos != null) { // Just return the first one we can find on the class itself for (AnnotationInstance anno : annos) { if (anno.target() == cls) { return anno; } } } return null; } // Returns a fully qualified declaration name making sure that // package name and member name are separated by "::" private static String classNameToDeclName(String clsName) { int lastDot = clsName.lastIndexOf('.'); String packageName = lastDot != -1 ? clsName.substring(0, lastDot) : ""; String simpleName = lastDot != -1 ? clsName.substring(lastDot + 1) : clsName; // ceylon names have mangling for interface members that we pull to toplevel simpleName = simpleName.replace("$impl$", "."); // turn any dollar sep into a dot simpleName = simpleName.replace('$', '.'); // remove any dollar prefixes and trailing underscores return unquotedDeclName(packageName, simpleName); } // Given a fully qualified package and member name returns the full and // unquoted declaration name stripped of all special symbols like '$' and '_' private static String unquotedDeclName(String pkg, String member) { if (pkg != null && !pkg.isEmpty()) { return unquoteName(pkg, false) + "::" + unquoteName(member, true); } else { return unquoteName(member, true); } } // Given a name consisting of parts separated by dots returns the unquoted // version stripped of all special symbols like '$' and '_' private static String unquoteName(String s, boolean stripTrailingUnderscore) { if (s != null) { String[] parts = JVMModuleUtil.unquoteJavaKeywords(s.split("\\.")); String name = parts[parts.length - 1]; if (stripTrailingUnderscore && !name.isEmpty() && Character.isLowerCase(name.charAt(0)) && name.charAt(name.length() - 1) == '_') { name = name.substring(0, name.length() - 1); } parts[parts.length - 1] = name; s = JVMModuleUtil.join(".", parts); } return s; } private static String getVersionFromFilename(String moduleName, String name) { if (!ModuleUtil.isDefaultModule(moduleName)) { String type = ArtifactContext.getSuffixFromFilename(name); return name.substring(moduleName.length() + 1, name.length() - type.length()); } else { return ""; } } private static Set<ModuleDependencyInfo> getDependencies( AnnotationValue dependencies, String module, String version, Overrides overrides) { AnnotationInstance[] deps = dependencies.asNestedArray(); Set<ModuleDependencyInfo> result = new HashSet<ModuleDependencyInfo>(deps.length); for (AnnotationInstance dep : deps) { AnnotationValue depName = dep.value("name"); AnnotationValue depVersion = dep.value("version"); AnnotationValue export = dep.value("export"); AnnotationValue optional = dep.value("optional"); result.add( new ModuleDependencyInfo( depName.asString(), depVersion.asString(), (optional != null) && optional.asBoolean(), (export != null) && export.asBoolean())); } if (overrides != null) return overrides .applyOverrides(module, version, new ModuleInfo(null, result)) .getDependencies(); return result; } public boolean matchesModuleInfo( String moduleName, String moduleVersion, File moduleArchive, String query, Overrides overrides) { Index index = readModuleIndex(moduleArchive, false); final AnnotationInstance moduleAnnotation = getAnnotation(index, moduleName, MODULE_ANNOTATION); if (moduleAnnotation == null) return false; AnnotationValue version = moduleAnnotation.value("version"); if (version == null) return false; AnnotationValue doc = moduleAnnotation.value("doc"); if (doc != null && matches(doc.asString(), query)) return true; AnnotationValue license = moduleAnnotation.value("license"); if (license != null && matches(license.asString(), query)) return true; AnnotationValue by = moduleAnnotation.value("by"); if (by != null) { for (String author : by.asStringArray()) { if (matches(author, query)) return true; } } AnnotationValue dependencies = moduleAnnotation.value("dependencies"); if (dependencies != null) { for (ModuleDependencyInfo dep : getDependencies(dependencies, moduleName, version.asString(), overrides)) { if (matches(dep.getModuleName(), query)) return true; } } return false; } private static boolean matches(String string, String query) { return string.toLowerCase().contains(query); } private static String asString(AnnotationInstance ai, String name) { final AnnotationValue av = ai.value(name); if (av == null) throw new IllegalArgumentException("Missing required annotation attribute: " + name); return av.asString(); } private static boolean asBoolean(AnnotationInstance ai, String name) { final AnnotationValue av = ai.value(name); return (av != null) && av.asBoolean(); } private static AnnotationInstance getAnnotation( Index index, String moduleName, DotName annotationName) { final ClassInfo moduleClass = getModuleInfo(index, moduleName); if (moduleClass == null) return null; List<AnnotationInstance> annotations = moduleClass.annotations().get(annotationName); if (annotations == null || annotations.isEmpty()) return null; return annotations.get(0); } }
private static Type getType(Class clazz) { return Type.create(DotName.createSimple(clazz.getName()), getTypeKind(clazz)); }
/** * Processor that finds jax-rs classes in the deployment * * @author Stuart Douglas */ public class JaxrsScanningProcessor implements DeploymentUnitProcessor { public static final DotName APPLICATION = DotName.createSimple(Application.class.getName()); @Override public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); if (!JaxrsDeploymentMarker.isJaxrsDeployment(deploymentUnit)) { return; } final DeploymentUnit parent = deploymentUnit.getParent() == null ? deploymentUnit : deploymentUnit.getParent(); final Map<ModuleIdentifier, ResteasyDeploymentData> deploymentData; if (deploymentUnit.getParent() == null) { deploymentData = Collections.synchronizedMap(new HashMap<ModuleIdentifier, ResteasyDeploymentData>()); deploymentUnit.putAttachment( JaxrsAttachments.ADDITIONAL_RESTEASY_DEPLOYMENT_DATA, deploymentData); } else { deploymentData = parent.getAttachment(JaxrsAttachments.ADDITIONAL_RESTEASY_DEPLOYMENT_DATA); } final ModuleIdentifier moduleIdentifier = deploymentUnit.getAttachment(Attachments.MODULE_IDENTIFIER); ResteasyDeploymentData resteasyDeploymentData = new ResteasyDeploymentData(); final WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY); final Module module = deploymentUnit.getAttachment(Attachments.MODULE); try { if (warMetaData == null) { resteasyDeploymentData.setScanAll(true); scan(deploymentUnit, module.getClassLoader(), resteasyDeploymentData); deploymentData.put(moduleIdentifier, resteasyDeploymentData); } else { scanWebDeployment( deploymentUnit, warMetaData.getMergedJBossWebMetaData(), module.getClassLoader(), resteasyDeploymentData); scan(deploymentUnit, module.getClassLoader(), resteasyDeploymentData); } deploymentUnit.putAttachment( JaxrsAttachments.RESTEASY_DEPLOYMENT_DATA, resteasyDeploymentData); } catch (ModuleLoadException e) { throw new DeploymentUnitProcessingException(e); } } @Override public void undeploy(DeploymentUnit context) {} public static final Set<String> BOOT_CLASSES = new HashSet<String>(); static { Collections.addAll(BOOT_CLASSES, ResteasyBootstrapClasses.BOOTSTRAP_CLASSES); } /** If any servlet/filter classes are declared, then we probably don't want to scan. */ protected boolean hasBootClasses(JBossWebMetaData webdata) throws DeploymentUnitProcessingException { if (webdata.getServlets() != null) { for (ServletMetaData servlet : webdata.getServlets()) { String servletClass = servlet.getServletClass(); if (BOOT_CLASSES.contains(servletClass)) return true; } } if (webdata.getFilters() != null) { for (FilterMetaData filter : webdata.getFilters()) { if (BOOT_CLASSES.contains(filter.getFilterClass())) return true; } } return false; } protected void scanWebDeployment( final DeploymentUnit du, final JBossWebMetaData webdata, final ClassLoader classLoader, final ResteasyDeploymentData resteasyDeploymentData) throws DeploymentUnitProcessingException { // If there is a resteasy boot class in web.xml, then the default should be to not scan // make sure this call happens before checkDeclaredApplicationClassAsServlet!!! boolean hasBoot = hasBootClasses(webdata); resteasyDeploymentData.setBootClasses(hasBoot); Class<?> declaredApplicationClass = checkDeclaredApplicationClassAsServlet(webdata, classLoader); // Assume that checkDeclaredApplicationClassAsServlet created the dispatcher if (declaredApplicationClass != null) { resteasyDeploymentData.setDispatcherCreated(true); } // set scanning on only if there are no boot classes if (!hasBoot && !webdata.isMetadataComplete()) { resteasyDeploymentData.setScanAll(true); resteasyDeploymentData.setScanProviders(true); resteasyDeploymentData.setScanResources(true); } // check resteasy configuration flags List<ParamValueMetaData> contextParams = webdata.getContextParams(); if (contextParams != null) { for (ParamValueMetaData param : contextParams) { if (param.getParamName().equals(RESTEASY_SCAN)) { resteasyDeploymentData.setScanAll(valueOf(RESTEASY_SCAN, param.getParamValue())); } else if (param.getParamName().equals(ResteasyContextParameters.RESTEASY_SCAN_PROVIDERS)) { resteasyDeploymentData.setScanProviders( valueOf(RESTEASY_SCAN_PROVIDERS, param.getParamValue())); } else if (param.getParamName().equals(RESTEASY_SCAN_RESOURCES)) { resteasyDeploymentData.setScanResources( valueOf(RESTEASY_SCAN_RESOURCES, param.getParamValue())); } else if (param .getParamName() .equals(ResteasyContextParameters.RESTEASY_UNWRAPPED_EXCEPTIONS)) { resteasyDeploymentData.setUnwrappedExceptionsParameterSet(true); } } } } protected void scan( final DeploymentUnit du, final ClassLoader classLoader, final ResteasyDeploymentData resteasyDeploymentData) throws DeploymentUnitProcessingException, ModuleLoadException { final CompositeIndex index = du.getAttachment(Attachments.COMPOSITE_ANNOTATION_INDEX); if (!resteasyDeploymentData.shouldScan()) { return; } final Set<ClassInfo> applicationClass = index.getAllKnownSubclasses(APPLICATION); try { if (applicationClass.size() > 1) { StringBuilder builder = new StringBuilder(); Set<ClassInfo> aClasses = new HashSet<ClassInfo>(); for (ClassInfo c : applicationClass) { if (!Modifier.isAbstract(c.flags())) { aClasses.add(c); } builder.append(" ").append(c.name().toString()); } if (aClasses.size() > 1) { throw new DeploymentUnitProcessingException( MESSAGES.onlyOneApplicationClassAllowed(builder)); } else if (aClasses.size() == 1) { ClassInfo aClass = applicationClass.iterator().next(); resteasyDeploymentData.setScannedApplicationClass( (Class<? extends Application>) classLoader.loadClass(aClass.name().toString())); } } else if (applicationClass.size() == 1) { ClassInfo aClass = applicationClass.iterator().next(); resteasyDeploymentData.setScannedApplicationClass( (Class<? extends Application>) classLoader.loadClass(aClass.name().toString())); } } catch (ClassNotFoundException e) { throw MESSAGES.cannotLoadApplicationClass(e); } List<AnnotationInstance> resources = null; List<AnnotationInstance> providers = null; if (resteasyDeploymentData.isScanResources()) { resources = index.getAnnotations(JaxrsAnnotations.PATH.getDotName()); } if (resteasyDeploymentData.isScanProviders()) { providers = index.getAnnotations(JaxrsAnnotations.PROVIDER.getDotName()); } if ((resources == null || resources.isEmpty()) && (providers == null || providers.isEmpty())) return; final Set<ClassInfo> pathInterfaces = new HashSet<ClassInfo>(); if (resources != null) { for (AnnotationInstance e : resources) { final ClassInfo info; if (e.target() instanceof ClassInfo) { info = (ClassInfo) e.target(); } else if (e.target() instanceof MethodInfo) { // ignore continue; } else { JAXRS_LOGGER.classOrMethodAnnotationNotFound("@Path", e.target()); continue; } if (!Modifier.isInterface(info.flags())) { resteasyDeploymentData.getScannedResourceClasses().add(info.name().toString()); } else { pathInterfaces.add(info); } } } if (providers != null) { for (AnnotationInstance e : providers) { if (e.target() instanceof ClassInfo) { ClassInfo info = (ClassInfo) e.target(); if (!Modifier.isInterface(info.flags())) { resteasyDeploymentData.getScannedProviderClasses().add(info.name().toString()); } } else { JAXRS_LOGGER.classAnnotationNotFound("@Provider", e.target()); } } } // look for all implementations of interfaces annotated @Path for (final ClassInfo iface : pathInterfaces) { final Set<ClassInfo> implementors = index.getAllKnownImplementors(iface.name()); for (final ClassInfo implementor : implementors) { resteasyDeploymentData.getScannedResourceClasses().add(implementor.name().toString()); } } } protected Class<?> checkDeclaredApplicationClassAsServlet( JBossWebMetaData webData, ClassLoader classLoader) throws DeploymentUnitProcessingException { if (webData.getServlets() == null) return null; for (ServletMetaData servlet : webData.getServlets()) { String servletClass = servlet.getServletClass(); if (servletClass == null) continue; Class<?> clazz = null; try { clazz = classLoader.loadClass(servletClass); } catch (ClassNotFoundException e) { throw new DeploymentUnitProcessingException(e); } if (Application.class.isAssignableFrom(clazz)) { servlet.setServletClass(HttpServlet30Dispatcher.class.getName()); servlet.setAsyncSupported(true); ParamValueMetaData param = new ParamValueMetaData(); param.setParamName("javax.ws.rs.Application"); param.setParamValue(servletClass); List<ParamValueMetaData> params = servlet.getInitParam(); if (params == null) { params = new ArrayList<ParamValueMetaData>(); servlet.setInitParam(params); } params.add(param); return clazz; } } return null; } private boolean valueOf(String paramName, String value) throws DeploymentUnitProcessingException { if (value == null) { throw JaxrsMessages.MESSAGES.invalidParamValue(paramName, value); } if (value.toLowerCase(Locale.ENGLISH).equals("true")) { return true; } else if (value.toLowerCase(Locale.ENGLISH).equals("false")) { return false; } else { throw JaxrsMessages.MESSAGES.invalidParamValue(paramName, value); } } }
/** * Deployment processor responsible for processing @EJB annotations within components. Each @EJB * annotation will be registered as an injection binding for the component. * * @author John Bailey * @author <a href="mailto:[email protected]">Richard Opalka</a> */ public class EjbResourceInjectionAnnotationProcessor implements DeploymentUnitProcessor { private static final DotName EJB_ANNOTATION_NAME = DotName.createSimple(EJB.class.getName()); private static final DotName EJBS_ANNOTATION_NAME = DotName.createSimple(EJBs.class.getName()); private final boolean appclient; private static final Logger logger = Logger.getLogger(EjbResourceInjectionAnnotationProcessor.class); public EjbResourceInjectionAnnotationProcessor(final boolean appclient) { this.appclient = appclient; } public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); final EEModuleDescription moduleDescription = deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION); final CompositeIndex index = deploymentUnit.getAttachment( org.jboss.as.server.deployment.Attachments.COMPOSITE_ANNOTATION_INDEX); final List<AnnotationInstance> resourceAnnotations = index.getAnnotations(EJB_ANNOTATION_NAME); for (AnnotationInstance annotation : resourceAnnotations) { final AnnotationTarget annotationTarget = annotation.target(); final EJBResourceWrapper annotationWrapper = new EJBResourceWrapper(annotation); if (annotationTarget instanceof FieldInfo) { processField( deploymentUnit, annotationWrapper, (FieldInfo) annotationTarget, moduleDescription); } else if (annotationTarget instanceof MethodInfo) { processMethod( deploymentUnit, annotationWrapper, (MethodInfo) annotationTarget, moduleDescription); } else if (annotationTarget instanceof ClassInfo) { processClass( deploymentUnit, annotationWrapper, (ClassInfo) annotationTarget, moduleDescription); } } final List<AnnotationInstance> ejbsAnnotations = index.getAnnotations(EJBS_ANNOTATION_NAME); for (AnnotationInstance annotation : ejbsAnnotations) { final AnnotationTarget annotationTarget = annotation.target(); if (annotationTarget instanceof ClassInfo) { final AnnotationValue annotationValue = annotation.value(); final AnnotationInstance[] ejbAnnotations = annotationValue.asNestedArray(); for (AnnotationInstance ejbAnnotation : ejbAnnotations) { final EJBResourceWrapper annotationWrapper = new EJBResourceWrapper(ejbAnnotation); processClass( deploymentUnit, annotationWrapper, (ClassInfo) annotationTarget, moduleDescription); } } else { throw MESSAGES.annotationOnlyAllowedOnClass(EJBs.class.getName(), annotation.target()); } } } public void undeploy(DeploymentUnit context) {} private void processField( final DeploymentUnit deploymentUnit, final EJBResourceWrapper annotation, final FieldInfo fieldInfo, final EEModuleDescription eeModuleDescription) { final String fieldName = fieldInfo.name(); final String fieldType = fieldInfo.type().name().toString(); final InjectionTarget targetDescription = new FieldInjectionTarget( fieldInfo.declaringClass().name().toString(), fieldName, fieldType); final String localContextName = isEmpty(annotation.name()) ? fieldInfo.declaringClass().name().toString() + "/" + fieldInfo.name() : annotation.name(); final String beanInterfaceType = isEmpty(annotation.beanInterface()) || annotation.beanInterface().equals(Object.class.getName()) ? fieldType : annotation.beanInterface(); process( deploymentUnit, beanInterfaceType, annotation.beanName(), annotation.lookup(), fieldInfo.declaringClass(), targetDescription, localContextName, eeModuleDescription); } private void processMethod( final DeploymentUnit deploymentUnit, final EJBResourceWrapper annotation, final MethodInfo methodInfo, final EEModuleDescription eeModuleDescription) { final String methodName = methodInfo.name(); if (!methodName.startsWith("set") || methodInfo.args().length != 1) { throw MESSAGES.onlySetterMethodsAllowedToHaveEJBAnnotation(methodInfo); } final String methodParamType = methodInfo.args()[0].name().toString(); final InjectionTarget targetDescription = new MethodInjectionTarget( methodInfo.declaringClass().name().toString(), methodName, methodParamType); final String localContextName = isEmpty(annotation.name()) ? methodInfo.declaringClass().name().toString() + "/" + methodName.substring(3, 4).toLowerCase(Locale.ENGLISH) + methodName.substring(4) : annotation.name(); final String beanInterfaceType = isEmpty(annotation.beanInterface()) || annotation.beanInterface().equals(Object.class.getName()) ? methodParamType : annotation.beanInterface(); process( deploymentUnit, beanInterfaceType, annotation.beanName(), annotation.lookup(), methodInfo.declaringClass(), targetDescription, localContextName, eeModuleDescription); } private void processClass( final DeploymentUnit deploymentUnit, final EJBResourceWrapper annotation, final ClassInfo classInfo, final EEModuleDescription eeModuleDescription) throws DeploymentUnitProcessingException { if (isEmpty(annotation.name())) { throw MESSAGES.nameAttributeRequiredForEJBAnnotationOnClass(classInfo.toString()); } if (isEmpty(annotation.beanInterface())) { throw MESSAGES.beanInterfaceAttributeRequiredForEJBAnnotationOnClass(classInfo.toString()); } process( deploymentUnit, annotation.beanInterface(), annotation.beanName(), annotation.lookup(), classInfo, null, annotation.name(), eeModuleDescription); } private void process( final DeploymentUnit deploymentUnit, final String beanInterface, final String beanName, final String lookup, final ClassInfo classInfo, final InjectionTarget targetDescription, final String localContextName, final EEModuleDescription eeModuleDescription) { if (!isEmpty(lookup) && !isEmpty(beanName)) { logger.debug( "Both beanName = " + beanName + " and lookup = " + lookup + " have been specified in @EJB annotation." + " lookup will be given preference. Class: " + classInfo.name()); } final EEModuleClassDescription classDescription = eeModuleDescription.addOrGetLocalClassDescription(classInfo.name().toString()); final InjectionSource valueSource; EjbInjectionSource ejbInjectionSource = null; // give preference to lookup if (!isEmpty(lookup)) { if (!lookup.startsWith("java:")) { valueSource = new EjbLookupInjectionSource(lookup, targetDescription.getDeclaredValueClassName()); } else { valueSource = createLookup(lookup, appclient); } } else if (!isEmpty(beanName)) { valueSource = ejbInjectionSource = new EjbInjectionSource( beanName, beanInterface, localContextName, deploymentUnit, appclient); } else { valueSource = ejbInjectionSource = new EjbInjectionSource(beanInterface, localContextName, deploymentUnit, appclient); } if (ejbInjectionSource != null) { deploymentUnit.addToAttachmentList( EjbDeploymentAttachmentKeys.EJB_INJECTIONS, ejbInjectionSource); } // our injection comes from the local lookup, no matter what. final ResourceInjectionConfiguration injectionConfiguration = targetDescription != null ? new ResourceInjectionConfiguration( targetDescription, createLookup(localContextName, appclient)) : null; // Create the binding from whence our injection comes. final BindingConfiguration bindingConfiguration = new BindingConfiguration(localContextName, valueSource); classDescription.getBindingConfigurations().add(bindingConfiguration); if (injectionConfiguration != null) { classDescription.addResourceInjection(injectionConfiguration); } } private InjectionSource createLookup(final String localContextName, final boolean appclient) { // appclient lookups are always optional // as they could reference local interfaces that are not present if (appclient) { return new OptionalLookupInjectionSource(localContextName); } else { return new LookupInjectionSource(localContextName); } } private boolean isEmpty(final String string) { return string == null || string.isEmpty(); } private class EJBResourceWrapper { private final String name; private final String beanInterface; private final String beanName; private final String lookup; private final String description; private EJBResourceWrapper(final AnnotationInstance annotation) { name = stringValueOrNull(annotation, "name"); beanInterface = classValueOrNull(annotation, "beanInterface"); beanName = stringValueOrNull(annotation, "beanName"); String lookupValue = stringValueOrNull(annotation, "lookup"); // if "lookup" isn't specified, then fallback on "mappedName". We treat "mappedName" the same // as "lookup" if (isEmpty(lookupValue)) { lookupValue = stringValueOrNull(annotation, "mappedName"); } this.lookup = lookupValue; description = stringValueOrNull(annotation, "description"); } private String name() { return name; } private String beanInterface() { return beanInterface; } private String beanName() { return beanName; } private String lookup() { return lookup; } private String description() { return description; } private String stringValueOrNull(final AnnotationInstance annotation, final String attribute) { final AnnotationValue value = annotation.value(attribute); return value != null ? value.asString() : null; } private String classValueOrNull(final AnnotationInstance annotation, final String attribute) { final AnnotationValue value = annotation.value(attribute); return value != null ? value.asClass().name().toString() : null; } } }