/*
* JBoss, Home of Professional Open Source
* Copyright 2006, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.deployers.structure.spi.helpers;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.concurrent.CopyOnWriteArrayList;
import org.jboss.dependency.spi.DependencyInfo;
import org.jboss.deployers.client.spi.Deployment;
import org.jboss.deployers.spi.DeploymentException;
import org.jboss.deployers.spi.DeploymentState;
import org.jboss.deployers.spi.attachments.Attachments;
import org.jboss.deployers.spi.attachments.AttachmentsFactory;
import org.jboss.deployers.spi.attachments.MutableAttachments;
import org.jboss.deployers.structure.spi.ClassLoaderFactory;
import org.jboss.deployers.structure.spi.DeploymentContext;
import org.jboss.deployers.structure.spi.DeploymentContextVisitor;
import org.jboss.deployers.structure.spi.DeploymentResourceLoader;
import org.jboss.deployers.structure.spi.DeploymentUnit;
import org.jboss.deployers.structure.spi.scope.ScopeBuilder;
import org.jboss.logging.Logger;
import org.jboss.metadata.spi.MetaData;
import org.jboss.metadata.spi.MutableMetaData;
import org.jboss.metadata.spi.scope.ScopeKey;
/**
* AbstractDeploymentContext.
*
* @author <a href="adrian@jboss.com">Adrian Brock</a>
* @author Scott.Stark@jboss.org
* @version $Revision: 59630 $
*/
public class ComponentDeploymentContext implements DeploymentContext
{
/** The serialVersionUID */
private static final long serialVersionUID = -5105972679660633071L;
/** The log */
protected Logger log = Logger.getLogger(getClass());
/** The name */
private String name;
/** The controller context names - should be serializable */
private Set<Object> controllerContextNames;
/** The deployment unit */
private DeploymentUnit unit;
/** The parent context */
private DeploymentContext parent;
/** The component contexts */
private List<DeploymentContext> components = new CopyOnWriteArrayList<DeploymentContext>();
/** The attachments */
private transient MutableAttachments transientAttachments = AttachmentsFactory.createMutableAttachments();
/** The managed objects */
private transient MutableAttachments transientManagedObjects = AttachmentsFactory.createMutableAttachments();
/** The scope */
private ScopeKey scope;
/** The mutable scope */
private ScopeKey mutableScope;
/**
* For serialization
*/
public ComponentDeploymentContext()
{
}
/**
* Create a new ComponentDeploymentContext.
*
* @param name the name
* @param parent the parent
* @throws IllegalArgumentException if the name or parent is null
*/
public ComponentDeploymentContext(String name, DeploymentContext parent)
{
if (name == null)
throw new IllegalArgumentException("Null name");
if (parent == null)
throw new IllegalArgumentException("Null parent");
this.name = name;
this.parent = parent;
}
public String getName()
{
return name;
}
public Set<Object> getControllerContextNames()
{
return controllerContextNames != null ? Collections.unmodifiableSet(controllerContextNames) : null;
}
public synchronized void addControllerContextName(Object name)
{
if (controllerContextNames == null)
controllerContextNames = new HashSet<Object>();
controllerContextNames.add(name);
}
public synchronized void removeControllerContextName(Object name)
{
if (controllerContextNames != null)
{
controllerContextNames.remove(name);
if (controllerContextNames.isEmpty())
controllerContextNames = null;
}
else
log.warn("Removing name on null names: " + name);
}
public String getSimpleName()
{
return parent.getSimpleName();
}
public String getRelativePath()
{
return parent.getRelativePath();
}
public int getRelativeOrder()
{
return 0;
}
public void setRelativeOrder(int relativeOrder)
{
// No relative ordering of components?
}
public Comparator<DeploymentContext> getComparator()
{
return null;
}
public void setComparator(Comparator<DeploymentContext> comparator)
{
// No relative ordering of components?
}
public ScopeKey getScope()
{
if (scope == null)
{
ScopeBuilder builder = AbstractDeploymentContext.getScopeBuilder(this);
scope = builder.getComponentScope(this);
}
return scope;
}
public void setScope(ScopeKey scope)
{
this.scope = scope;
}
public ScopeKey getMutableScope()
{
if (mutableScope == null)
{
ScopeBuilder builder = AbstractDeploymentContext.getScopeBuilder(this);
mutableScope = builder.getMutableComponentScope(this);
}
return mutableScope;
}
public void setMutableScope(ScopeKey mutableScope)
{
this.mutableScope = mutableScope;
}
public MetaData getMetaData()
{
return AbstractDeploymentContext.getMetaData(this);
}
public MutableMetaData getMutableMetaData()
{
return AbstractDeploymentContext.getMutableMetaData(this);
}
public DeploymentState getState()
{
return parent.getState();
}
public void setState(DeploymentState state)
{
parent.setState(state);
}
public DeploymentUnit getDeploymentUnit()
{
if (unit == null)
throw new IllegalStateException("Deployment unit has not been set");
return unit;
}
public void setDeploymentUnit(DeploymentUnit unit)
{
this.unit = unit;
}
public void setMetaDataPath(String path)
{
throw new UnsupportedOperationException("Not supported for components");
}
public ClassLoader getClassLoader()
{
return parent.getClassLoader();
}
public void setClassLoader(ClassLoader classLoader)
{
throw new UnsupportedOperationException("Not supported for components");
}
public boolean createClassLoader(ClassLoaderFactory factory) throws DeploymentException
{
return false;
}
public void removeClassLoader()
{
}
public void removeClassLoader(ClassLoaderFactory factory)
{
}
public boolean isTopLevel()
{
return false;
}
public DeploymentContext getTopLevel()
{
return parent.getTopLevel();
}
public DeploymentContext getParent()
{
return parent;
}
public void setParent(DeploymentContext parent)
{
throw new UnsupportedOperationException("Not supported for components");
}
public List<DeploymentContext> getChildren()
{
return Collections.emptyList();
}
public void addChild(DeploymentContext child)
{
throw new UnsupportedOperationException("Not supported for components");
}
public boolean removeChild(DeploymentContext child)
{
throw new UnsupportedOperationException("Not supported for components");
}
public Deployment getDeployment()
{
return parent.getDeployment();
}
public void setDeployment(Deployment deployment)
{
throw new UnsupportedOperationException("Not supported for components");
}
public boolean isComponent()
{
return true;
}
public List<DeploymentContext> getComponents()
{
return Collections.unmodifiableList(components);
}
public void addComponent(DeploymentContext component)
{
if (component == null)
throw new IllegalArgumentException("Null component");
components.add(component);
}
public boolean removeComponent(DeploymentContext component)
{
if (component == null)
throw new IllegalArgumentException("Null component");
boolean result = components.remove(component);
component.cleanup();
return result;
}
public ClassLoader getResourceClassLoader()
{
return parent.getResourceClassLoader();
}
public DeploymentResourceLoader getResourceLoader()
{
return parent.getResourceLoader();
}
public DependencyInfo getDependencyInfo()
{
return parent.getDependencyInfo();
}
public void visit(DeploymentContextVisitor visitor) throws DeploymentException
{
if (visitor == null)
throw new IllegalArgumentException("Null visitor");
visit(this, visitor);
}
/**
* Visit a context
*
* @param context the context
* @param visitor the visitor
* @throws DeploymentException for any error
*/
private void visit(DeploymentContext context, DeploymentContextVisitor visitor) throws DeploymentException
{
visitor.visit(context);
try
{
List<DeploymentContext> children = context.getChildren();
if (children.isEmpty())
return;
DeploymentContext[] childContexts = children.toArray(new DeploymentContext[children.size()]);
for (int i = 0; i < childContexts.length; ++i)
{
if (childContexts[i] == null)
throw new IllegalStateException("Null child context for " + context.getName() + " children=" + children);
try
{
visit(childContexts[i], visitor);
}
catch (Throwable t)
{
for (int j = i-1; j >= 0; --j)
visitError(childContexts[j], visitor, true);
throw DeploymentException.rethrowAsDeploymentException("Error visiting: " + childContexts[i].getName(), t);
}
}
}
catch (Throwable t)
{
visitError(context, visitor, false);
throw DeploymentException.rethrowAsDeploymentException("Error visiting: " + context.getName(), t);
}
}
/**
* Unwind the visit invoking the previously visited context's error handler
*
* @param context the context
* @param visitor the visitor
* @param visitChildren whether to visit the children
* @throws DeploymentException for any error
*/
private void visitError(DeploymentContext context, DeploymentContextVisitor visitor, boolean visitChildren) throws DeploymentException
{
if (visitChildren)
{
List<DeploymentContext> children = context.getChildren();
if (children.isEmpty())
return;
for (DeploymentContext child : children)
{
try
{
visitError(child, visitor, true);
}
catch (Throwable t)
{
log.warn("Error during visit error: " + child.getName(), t);
}
}
}
try
{
visitor.error(context);
}
catch (Throwable t)
{
log.warn("Error during visit error: " + context.getName(), t);
}
}
public Attachments getPredeterminedManagedObjects()
{
return parent.getPredeterminedManagedObjects();
}
public void setPredeterminedManagedObjects(Attachments objects)
{
throw new UnsupportedOperationException("Not supported for components");
}
public MutableAttachments getTransientManagedObjects()
{
return transientManagedObjects;
}
public MutableAttachments getTransientAttachments()
{
return transientAttachments;
}
public Throwable getProblem()
{
return parent.getProblem();
}
public void setProblem(Throwable problem)
{
parent.setProblem(problem);
}
public void deployed()
{
parent.deployed();
}
public boolean isDeployed()
{
return parent.isDeployed();
}
public void cleanup()
{
AbstractDeploymentContext.cleanupRepository(this);
}
public String toString()
{
StringBuilder buffer = new StringBuilder();
buffer.append(getClass().getSimpleName());
buffer.append('@');
buffer.append(System.identityHashCode(this));
buffer.append('{').append(name).append('}');
return buffer.toString();
}
}