package org.mobicents.slee.container.component; import java.io.File; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; import javassist.LoaderClassPath; import javax.slee.ComponentID; import javax.slee.management.AlreadyDeployedException; import javax.slee.management.ComponentDescriptor; import javax.slee.management.DependencyException; import javax.slee.management.DeploymentException; import org.mobicents.slee.container.component.deployment.ClassPool; import org.mobicents.slee.container.component.deployment.DeployableUnit; import org.mobicents.slee.container.component.deployment.classloading.ComponentClassLoader; import org.mobicents.slee.container.component.deployment.classloading.URLClassLoaderDomain; import org.mobicents.slee.container.component.security.PermissionHolder; /** * Base class for a SLEE component, providing features related with class * loading, deployable unit and other component references * * @author martins * */ public abstract class SleeComponent { /** * the component class loader */ private ComponentClassLoader classLoader; /** * the class loader domain for the component jar this component belongs, * components that depend on this component must add this in its domain */ private URLClassLoaderDomain classLoaderDomain; /** * the javassist class pool */ private ClassPool classPool; /** * the DU the component belongs */ private DeployableUnit deployableUnit; /** * where this component is deployed */ private File deploymentDir; /** * the source for this component (component jar/service descriptor) in the * deployable unit */ private String deploymentUnitSource; protected Set<PermissionHolder> permissions = new TreeSet<PermissionHolder>(); /** * Retrieves the component class loader * * @return */ public ComponentClassLoader getClassLoader() { return classLoader; } /** * Sets the component class loader * * @param classLoader */ public void setClassLoader(ComponentClassLoader classLoader) { this.classLoader = classLoader; } private void addDomainLoadersToJavassistPool(Set<URLClassLoaderDomain> visitedDomains, URLClassLoaderDomain domain) { if (visitedDomains.add(domain)) { classPool.appendClassPath(new LoaderClassPath(domain)); // add dependency loaders class paths to the component's javassist classpool for (URLClassLoaderDomain dependencyDomain : domain.getDependencies()) { addDomainLoadersToJavassistPool(visitedDomains, dependencyDomain); } } } /** * Retrieves the class loader domain for the component jar this component * belongs, components that depend on this component must add this in its * domain. * * @return */ public URLClassLoaderDomain getClassLoaderDomain() { return classLoaderDomain; } /** * Sets the class loader domain for the component jar this component belongs * * @param classLoaderDomain */ public void setClassLoaderDomain(URLClassLoaderDomain classLoaderDomain) { this.classLoaderDomain = classLoaderDomain; } /** * Retrieves the component javassist class pool * * @return */ public ClassPool getClassPool() { if (classPool == null) { if (classLoader == null) { throw new IllegalStateException("can't init javassit classpool, there is no class loader set for the component"); } classPool = new ClassPool(); // add class path for domain and dependencies addDomainLoadersToJavassistPool(new HashSet<URLClassLoaderDomain>(),classLoaderDomain); // add class path also for slee classPool.appendClassPath(new LoaderClassPath(classLoaderDomain.getSleeClassLoader())); } return classPool; } /** * Retrieves the file pointing to where this component is deployed * * @return */ public File getDeploymentDir() { return deploymentDir; } /** * Sets the the file pointing where this component is deployed * * @param deploymentDir */ public void setDeploymentDir(File deploymentDir) { this.deploymentDir = deploymentDir; } /** * Retrieves the source for this component (component jar/service * descriptor) in the deployable unit * * @return */ public String getDeploymentUnitSource() { return deploymentUnitSource; } /** * Sets the source for this component (component jar/service descriptor) in * the deployable unit * * @param deploymentUnitSource */ public void setDeploymentUnitSource(String deploymentUnitSource) { this.deploymentUnitSource = deploymentUnitSource; } /** * Retrieves the Deployable Unit this component belongs * * @return */ public DeployableUnit getDeployableUnit() { return deployableUnit; } /** * Specifies the the Deployable Unit this component belongs. This method * also sets the reverse relation, adding the component to the deployable * unit * * @param deployableUnit * @throws AlreadyDeployedException * if a component with same id already exists in the du * @throws IllegalStateException * if this method is invoked and the deployable unit was already * set before */ public void setDeployableUnit(DeployableUnit deployableUnit) throws AlreadyDeployedException { if (this.deployableUnit != null) { throw new IllegalStateException( "deployable unit already set. du = " + this.deployableUnit); } this.deployableUnit = deployableUnit; if (!addToDeployableUnit()) { throw new AlreadyDeployedException( "unable to install du having multiple components with id " + getComponentID()); } } /** * Gets set with permissions. This may be empty list in case of components that dont have them. * In case of compoennts that can have xml-desc wide permissions - this set contains this permissions, * as does any other components set defined in that xml-descr. however impl of Policy MUST * handle double defined polic * @return */ public Set<PermissionHolder> getPermissions() { return Collections.unmodifiableSet(this.permissions); } /** * adds the component to the deployable unit * * @return true if the component was added */ abstract boolean addToDeployableUnit(); /** * Retrieves the set of components IDs this component depends * * @return */ public abstract Set<ComponentID> getDependenciesSet(); /** * Retrieves the ID of this component * * @return */ public abstract ComponentID getComponentID(); /** * Indicates if the component is new to SLEE 1.1 specs * * @return */ public abstract boolean isSlee11(); /** * Validates the component. * * @return * @throws DependencyException * @throws DeploymentException */ public abstract boolean validate() throws DependencyException, DeploymentException; @Override public int hashCode() { return getComponentID().hashCode(); } @Override public boolean equals(Object obj) { if (obj != null && obj.getClass() == this.getClass()) { return ((SleeComponent) obj).getComponentID().equals( this.getComponentID()); } else { return false; } } @Override public String toString() { return getComponentID().toString(); } /** * Retrieves the JAIN SLEE specs component descriptor * * @return */ public abstract ComponentDescriptor getComponentDescriptor(); public abstract void processSecurityPermissions() throws DeploymentException; /** * Indicates that the component was undeployed and thus should clean up any resources */ public void undeployed() { classLoader = null; if (classLoaderDomain != null) { classLoaderDomain.clean(); classLoaderDomain = null; } if (classPool != null) { classPool.clean(); classPool = null; } if (permissions != null) { permissions.clear(); permissions = null; } } }