package org.jboss.hibernate.har;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.Attribute;
import javax.management.MBeanInfo;
import org.jboss.deployment.DeploymentInfo;
import org.jboss.deployment.SubDeployerSupport;
import org.jboss.deployment.DeploymentException;
import org.jboss.system.ServiceControllerMBean;
import org.jboss.mx.util.MBeanProxyExt;
import org.jboss.mx.util.ObjectNameFactory;
import org.jboss.hibernate.jmx.Hibernate;
public class HARDeployer extends SubDeployerSupport
implements HARDeployerMBean
{
private static final ObjectName OBJECT_NAME = ObjectNameFactory.create("jboss.har:service=HARDeployer");
private static final String DESCRIPTOR_NAME = "hibernate-service.xml";
private static final String RELATIVE_DESCRIPTOR_URL = "META-INF/" + DESCRIPTOR_NAME;
private ServiceControllerMBean serviceController;
private HashMap deployments = new HashMap();
private boolean validateDTDs;
public HARDeployer()
{
setSuffixes( new String[] { ".har" } );
setRelativeOrder( RELATIVE_ORDER_400 );
}
public Iterator getDeployedApplications()
{
return deployments.values().iterator();
}
protected ObjectName getObjectName(MBeanServer server, ObjectName name)
throws MalformedObjectNameException
{
return name == null ? OBJECT_NAME : name;
}
protected void startService() throws Exception
{
serviceController = ( ServiceControllerMBean ) MBeanProxyExt.create(
ServiceControllerMBean.class,
ServiceControllerMBean.OBJECT_NAME, server
);
super.startService();
}
protected void stopService() throws Exception
{
Iterator modules = deployments.values().iterator();
while ( modules.hasNext() )
{
DeploymentInfo di = (DeploymentInfo)modules.next();
stop(di);
}
modules = new ArrayList( deployments.values() ).iterator();
while ( modules.hasNext() )
{
DeploymentInfo di = (DeploymentInfo)modules.next();
destroy(di);
}
deployments.clear();
super.stopService();
serviceController = null;
}
public boolean getValidateDTDs()
{
return validateDTDs;
}
public void setValidateDTDs(boolean validate)
{
this.validateDTDs = validate;
}
protected void processNestedDeployments(DeploymentInfo di) throws DeploymentException
{
super.processNestedDeployments( di );
}
protected void deployUrl(DeploymentInfo di, URL url, String name) throws DeploymentException
{
super.deployUrl( di, url, name );
}
public boolean isDeployable(String name, URL url)
{
log.debug( "Checking deployability of [name=" + name + ", url=" + url.getFile() + "]" );
return name.endsWith( ".jar" ) || name.endsWith( RELATIVE_DESCRIPTOR_URL );
}
public boolean accepts(DeploymentInfo di)
{
String urlStr = di.url.getFile();
if ( !urlStr.endsWith( ".har" ) && !urlStr.endsWith( ".har/" ) )
{
return false;
}
boolean accept = false;
try
{
URL dd = di.localCl.findResource( RELATIVE_DESCRIPTOR_URL );
if ( dd != null )
{
if ( di.localUrl != null )
{
urlStr = di.localUrl.toString();
}
String ddStr = dd.toString();
if( ddStr.indexOf( urlStr ) >= 0 )
{
accept = true;
}
}
}
catch( Exception ignore )
{
}
log.debug( "accept> url=" + di.url + ", accepted=" + accept );
return accept;
}
public void init(DeploymentInfo di) throws DeploymentException
{
log.debug( "Deploying HAR; init; " + di );
try
{
if( "file".equalsIgnoreCase( di.url.getProtocol() ) )
{
File file = new File( di.url.getFile() );
if ( !file.isDirectory() )
{
di.watch = di.url;
}
else
{
di.watch = new URL( di.url, DESCRIPTOR_NAME );
}
}
else
{
di.watch = di.url;
}
}
catch( Exception e )
{
if ( e instanceof DeploymentException )
{
throw ( DeploymentException ) e;
}
throw new DeploymentException( "failed to initialize", e );
}
super.init( di );
}
public synchronized void create(DeploymentInfo di) throws DeploymentException
{
log.debug( "Deploying HAR; create; " + di );
super.create( di );
Iterator subdeployments = di.subDeployments.iterator();
while ( subdeployments.hasNext() )
{
DeploymentInfo nested = ( DeploymentInfo ) subdeployments.next();
log.debug( "Checking sub-deployment [" + nested.url + "] for descriptor-name" );
if ( nested.url.getFile().endsWith( DESCRIPTOR_NAME ) )
{
log.debug( "Attempting to locate HibernateMBean in sub-deployment [" + nested.url + "]" );
Iterator mbeans = nested.mbeans.iterator();
while ( mbeans.hasNext() )
{
ObjectName service = ( ObjectName ) mbeans.next();
log.debug( "Testing [" + service + "] as HibernateMBean" );
if ( isHibernateMBean( service ) )
{
log.debug( "Located HibernateMBean" );
Attribute attr = new Attribute( "HarUrl", di.url );
try
{
server.setAttribute( service, attr );
}
catch( Exception e )
{
throw new DeploymentException( "Failed to set HarUrl attribute: " + e.getMessage(), e );
}
}
}
break;
}
}
}
public synchronized void start(DeploymentInfo di) throws DeploymentException
{
log.debug( "Deploying HAR; start; " + di );
super.start( di );
}
public void stop(DeploymentInfo di) throws DeploymentException
{
log.debug( "Undeploying HAR; stop; " + di );
try
{
serviceController.stop(di.deployedObject);
}
catch(Exception e)
{
throw new DeploymentException("problem stopping har module: " + di.url, e);
}
super.stop(di);
}
public void destroy(DeploymentInfo di) throws DeploymentException
{
log.debug( "Undeploying HAR; destroy; " + di );
deployments.remove(di.url);
try
{
serviceController.destroy(di.deployedObject);
serviceController.remove(di.deployedObject);
}
catch(Exception e)
{
throw new DeploymentException("problem destroying har module: " + di.url, e);
}
super.destroy( di );
}
private boolean isHibernateMBean(ObjectName service)
{
try
{
MBeanInfo serviceInfo = server.getMBeanInfo( service );
return Hibernate.class.getName().equals( serviceInfo.getClassName() );
}
catch( Throwable t )
{
log.warn( "Unable to determine whether MBean [" + service + "] is Hibernate MBean" );
return false;
}
}
}