/**
* EasyBeans
* Copyright (C) 2006-2008 Bull S.A.S.
* Copyright 2013 Peergreen S.A.S.
* Contact: easybeans@ow2.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* --------------------------------------------------------------------------
* $Id:EjbJarClassMetadata.java 2372 2008-02-08 18:18:37Z benoitf $
* --------------------------------------------------------------------------
*/
package org.ow2.easybeans.deployment.metadata.ejbjar.view;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.ow2.easybeans.asm.Opcodes;
import org.ow2.easybeans.deployment.annotations.exceptions.InterceptorsValidationException;
import org.ow2.easybeans.deployment.metadata.ejbjar.EasyBeansEjbJarMethodMetadata;
import org.ow2.util.ee.metadata.common.api.struct.IJavaxPersistenceContext;
import org.ow2.util.ee.metadata.common.api.struct.IJavaxPersistenceContextType;
import org.ow2.util.ee.metadata.common.api.view.ICommonView;
import org.ow2.util.ee.metadata.ejbjar.api.InterceptorType;
import org.ow2.util.ee.metadata.ejbjar.api.view.IEJBClassView;
import org.ow2.util.ee.metadata.ejbjar.impl.view.EJBView;
import org.ow2.util.pool.api.IPoolConfiguration;
import org.ow2.util.pool.api.IPoolMetadata;
import org.ow2.util.scan.api.metadata.IClassMetadata;
import org.ow2.util.scan.api.metadata.IFieldMetadata;
import org.ow2.util.scan.api.metadata.IMetadata;
import org.ow2.util.scan.api.metadata.IMethodMetadata;
import org.ow2.util.scan.api.metadata.structures.IMethod;
import org.ow2.util.scan.impl.metadata.JMethod;
/**
* This class represents the annotation metadata of a Bean.<br>
* From this class, we can access to all methods of a bean with its associated
* information.
* @author Florent Benoit
*/
public class EasyBeansClassView extends EJBView implements IPoolMetadata, IEJBClassView {
private final IMetadata classMetadata;
/**
* View is based on the given class metadata
*/
public EasyBeansClassView(final IMetadata classMetadata) {
super(classMetadata);
this.classMetadata = classMetadata;
}
/**
* @return the method metadata with annotation @{@link javax.interceptor.AroundInvoke}.
*/
public boolean isAroundInvokeMethodMetadata() {
return (this.classMetadata.getProperty("javax.interceptor.AroundInvoke") != null);
}
/**
* @return the list of methods metadata with annotation @{@link javax.interceptor.AroundInvoke}.
*/
public LinkedList<IMethodMetadata> getDelegateAroundInvokeMethodMetadatas() {
return this.classMetadata.getProperty("javax.interceptor.AroundInvoke");
}
/**
* Add a given method metadata if not yet added
* @param methodMetadata the method.
* @param property the given property to use.
*/
public void addPropertyMetadata(final IMethodMetadata methodMetadata, final String property, final boolean checkExists) {
LinkedList<IMethodMetadata> existingMethodsMetadata = this.classMetadata.getProperty(property);
if (existingMethodsMetadata == null) {
existingMethodsMetadata = new LinkedList<IMethodMetadata>();
this.classMetadata.setProperty(property, existingMethodsMetadata);
}
// Check not yet present
if (checkExists) {
for (IMethodMetadata foundMethodMetadata : existingMethodsMetadata) {
if (methodMetadata.getClassMetadata().getClassName().equals(foundMethodMetadata.getClassMetadata().getClassName())) {
if (methodMetadata.getJMethod().equals(foundMethodMetadata.getJMethod())) {
return;
}
}
}
}
existingMethodsMetadata.addFirst(methodMetadata);
}
/**
* Add a @{@link javax.interceptor.AroundInvoke} method of this class.
* @param aroundInvokeMethodMetadata the method.
*/
public void addAroundInvokeMethodMetadata(final IMethodMetadata aroundInvokeMethodMetadata) {
addPropertyMetadata(aroundInvokeMethodMetadata, "javax.interceptor.AroundInvoke", true);
}
/**
* @return the methods metadata with annotation @{@link javax.annotation.PostConstruct}.
*/
public LinkedList<IMethodMetadata> getDelegatePostConstructMethodsMetadata() {
return this.classMetadata.getProperty("javax.annotation.PostConstruct");
}
/**
* Adds a @{@link javax.annotation.PostConstruct} method of this class.
* @param postConstructMethodMetadata the method.
*/
public void addPostConstructMethodMetadata(final IMethodMetadata postConstructMethodMetadata) {
if (checkLifeCycleDuplicate(postConstructMethodMetadata, InterceptorType.POST_CONSTRUCT, getDelegatePostConstructMethodsMetadata())) {
addPropertyMetadata(postConstructMethodMetadata, "javax.annotation.PostConstruct", false);
}
}
/**
* Checks that only method at one level of a class is present.
* @param methodMetadata method to check
* @param itcType the type of interceptor (used for the error)
* @param existingList current list of methods
*/
private boolean checkLifeCycleDuplicate(final IMethodMetadata methodMetadata,
final InterceptorType itcType, final List<IMethodMetadata> existingList) {
// First case : not inherited
IClassMetadata wantToAddClassMetadata = methodMetadata.getClassMetadata();
EasyBeansEjbJarMethodMetadata methodView = methodMetadata.as(EasyBeansEjbJarMethodMetadata.class);
if (methodView.isInherited()) {
wantToAddClassMetadata = methodView.getOriginalClassMetadata();
}
if (existingList != null) {
for (IMethodMetadata method : existingList) {
IClassMetadata compareMetaData;
EasyBeansEjbJarMethodMetadata localMethodView = method.as(EasyBeansEjbJarMethodMetadata.class);
if (localMethodView.isInherited()) {
compareMetaData = localMethodView.getOriginalClassMetadata();
} else {
compareMetaData = method.getClassMetadata();
}
if (compareMetaData.equals(wantToAddClassMetadata)) {
IMethod jMethod = method.getJMethod();
JMethod otherMethod = new JMethod(Opcodes.ACC_PUBLIC, jMethod.getName()
+ compareMetaData.getClassName().replace("/", ""), jMethod.getDescriptor(), jMethod
.getSignature(), jMethod.getExceptions());
if (!methodMetadata.getJMethod().equals(method.getJMethod()) && !methodMetadata.getJMethod().equals(otherMethod)) {
throw new InterceptorsValidationException("Class " + compareMetaData.getClassName() + " has already a " + itcType
+ " method which is " + method.getJMethod().getName() + ", cannot set new method "
+ methodMetadata.getJMethod().getName());
}
return false;
}
}
}
return true;
}
/**
* @return the methods metadata with annotation @{@link javax.annotation.PreDestroy}.
*/
public LinkedList<IMethodMetadata> getDelegatePreDestroyMethodsMetadata() {
return this.classMetadata.getProperty("javax.annotation.PreDestroy");
}
/**
* Adds a @{@link javax.annotation.PreDestroy} method of this class.
* @param preDestroyMethodMetadata the method.
*/
public void addPreDestroyMethodMetadata(final IMethodMetadata preDestroyMethodMetadata) {
checkLifeCycleDuplicate(preDestroyMethodMetadata, InterceptorType.PRE_DESTROY, getDelegatePreDestroyMethodsMetadata());
addPropertyMetadata(preDestroyMethodMetadata, "javax.annotation.PreDestroy", false);
}
/**
* @return the methods metadata with annotation @{@link javax.ejb.PostActivate}.
*/
public LinkedList<IMethodMetadata> getDelegatePostActivateMethodsMetadata() {
return this.classMetadata.getProperty("javax.ejb.PostActivate");
}
/**
* Adds a @{@link javax.ejb.PostActivate} method of this class.
* @param postActivateMethodMetadata the method.
*/
public void addPostActivateMethodMetadata(final IMethodMetadata postActivateMethodMetadata) {
checkLifeCycleDuplicate(postActivateMethodMetadata, InterceptorType.POST_ACTIVATE, getDelegatePostActivateMethodsMetadata());
addPropertyMetadata(postActivateMethodMetadata, "javax.ejb.PostActivate", false);
}
/**
* @return the method metadata with annotation @{@link javax.ejb.PrePassivate}.
*/
public LinkedList<IMethodMetadata> getDelegatePrePassivateMethodsMetadata() {
return this.classMetadata.getProperty("javax.ejb.PrePassivate");
}
/**
* Adds a @{@link javax.ejb.PrePassivate} method of this class.
* @param prePassivateMethodMetadata the method.
*/
public void addPrePassivateMethodMetadata(final IMethodMetadata prePassivateMethodMetadata) {
checkLifeCycleDuplicate(prePassivateMethodMetadata, InterceptorType.PRE_PASSIVATE, getDelegatePrePassivateMethodsMetadata());
addPropertyMetadata(prePassivateMethodMetadata, "javax.ejb.PrePassivate", false);
}
/**
* Is that this class is an interceptor class ?
* @return true if it the case, else false.
*/
public boolean isInterceptor() {
return (getDelegateAroundInvokeMethodMetadatas() != null && getDelegateAroundInvokeMethodMetadatas().size() > 0)
|| (getDelegatePostConstructMethodsMetadata() != null && getDelegatePostConstructMethodsMetadata().size() > 0)
|| (getDelegatePreDestroyMethodsMetadata() != null && getDelegatePreDestroyMethodsMetadata().size() > 0)
|| (getDelegatePrePassivateMethodsMetadata() != null && getDelegatePrePassivateMethodsMetadata().size() > 0)
|| (getDelegatePostActivateMethodsMetadata() != null && getDelegatePostActivateMethodsMetadata().size() > 0);
}
/**
* @return the pool configuration for this metadata.
*/
public IPoolConfiguration getPoolConfiguration() {
return this.classMetadata.get(IPoolConfiguration.class);
}
/**
* Sets the pool configuration for this metadata.
* @param poolConfiguration the given configuration.
*/
public void setPoolConfiguration(final IPoolConfiguration poolConfiguration) {
this.classMetadata.set(IPoolConfiguration.class, poolConfiguration);
}
/**
* @return the iherited interfaces of the super classes.
*/
public List<String> getInheritedInterfaces() {
List<String> inherited = this.classMetadata.getProperty("inheritedInterfaces");
if (inherited == null) {
return new ArrayList<String>();
} else {
return inherited;
}
}
/**
* Sets the interfaces used in the super classes.
* @param inheritedInterfaces the given interfaces
*/
public void setInheritedInterfaces(final List<String> inheritedInterfaces) {
this.classMetadata.setProperty("inheritedInterfaces", inheritedInterfaces);
}
/**
* Gets the cluster configuration.
* @return the cluster
*/
public Object getCluster() {
return this.classMetadata.getProperty("cluster");
}
/**
* Sets the cluster configuration.
* @param cluster the clusterConfiguration to set
*/
public void setCluster(final Object cluster) {
this.classMetadata.setProperty("cluster", cluster);
}
/**
* @return the endpoint address associated with this bean configuration (may be null).
*/
public String getWebServiceEndpointAddress() {
return this.classMetadata.getProperty("webServiceEndpointAddress");
}
/**
* Set the web service endpoint address.
* @param webServiceEndpointAddress URI address
*/
public void setWebServiceEndpointAddress(final String webServiceEndpointAddress) {
this.classMetadata.setProperty("webServiceEndpointAddress", webServiceEndpointAddress);
}
public String getWebServiceContextRoot() {
return this.classMetadata.getProperty("webServiceContextRoot");
}
public void setWebServiceContextRoot(final String webServiceContextRoot) {
this.classMetadata.setProperty("webServiceContextRoot", webServiceContextRoot);
}
public String getWebServiceRealmName() {
return this.classMetadata.getProperty("webServiceRealmName");
}
public void setWebServiceRealmName(final String webServiceRealmName) {
this.classMetadata.setProperty("webServiceRealmName", webServiceRealmName);
}
public String getWebServiceTransportGuarantee() {
return this.classMetadata.getProperty("webServiceTransportGuarantee");
}
public void setWebServiceTransportGuarantee(final String webServiceTransportGuarantee) {
this.classMetadata.setProperty("webServiceTransportGuarantee", webServiceTransportGuarantee);
}
public String getWebServiceAuthMethod() {
return this.classMetadata.getProperty("webServiceAuthMethod");
}
public void setWebServiceAuthMethod(final String webServiceAuthMethod) {
this.classMetadata.setProperty("webServiceAuthMethod", webServiceAuthMethod);
}
public List<String> getWebServiceHttpMethods() {
return this.classMetadata.getProperty("webServiceHttpMethods");
}
public void setWebServiceHttpMethods(final List<String> webServiceHttpMethods) {
this.classMetadata.setProperty("webServiceHttpMethods", webServiceHttpMethods);
}
/**
* @return true if the class and attributes or setter methods have an extended persistence context.
*/
public boolean hasExtendedPersistenceContext() {
// Compute a list of persistence contexts
List<IJavaxPersistenceContext> persistenceContexts = new ArrayList<IJavaxPersistenceContext>();
ICommonView commonView = this.classMetadata.as(ICommonView.class);
// On the class
if (commonView.getJavaxPersistenceContext() != null) {
persistenceContexts.add(commonView.getJavaxPersistenceContext());
}
if (commonView.getJavaxPersistencePersistenceContexts() != null && commonView.getJavaxPersistencePersistenceContexts().size() > 0) {
persistenceContexts.addAll(commonView.getJavaxPersistencePersistenceContexts());
}
// Now, for all methods
Collection<IMethodMetadata> methods = getClassMetadata().getMethodMetadataCollection();
for (IMethodMetadata method : methods) {
ICommonView methodView = method.as(ICommonView.class);
if (methodView.getJavaxPersistenceContext() != null) {
persistenceContexts.add(methodView.getJavaxPersistenceContext());
}
}
// Now, for all attributes
Collection<IFieldMetadata> fields = getClassMetadata().getFieldMetadataCollection();
for (IFieldMetadata field : fields) {
ICommonView fieldView = field.as(ICommonView.class);
if (fieldView.getJavaxPersistenceContext() != null) {
persistenceContexts.add(fieldView.getJavaxPersistenceContext());
}
}
boolean hasExtendedPersistenceContext = false;
for (IJavaxPersistenceContext persistenceContext : persistenceContexts) {
if (IJavaxPersistenceContextType.EXTENDED == persistenceContext.getType()) {
hasExtendedPersistenceContext = true;
break;
}
}
return hasExtendedPersistenceContext;
}
public IClassMetadata getClassMetadata() {
return (IClassMetadata) this.classMetadata;
}
public String getClassName() {
return getClassMetadata().getInternalClassName();
}
}