/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file 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.profileservice.management.views;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.jboss.deployers.spi.management.ContextStateMapper;
import org.jboss.deployers.spi.management.RuntimeComponentDispatcher;
import org.jboss.logging.Logger;
import org.jboss.managed.api.DeploymentState;
import org.jboss.managed.api.ManagedComponent;
import org.jboss.managed.api.ManagedDeployment;
import org.jboss.managed.api.ManagedObject;
import org.jboss.managed.api.ManagedOperation;
import org.jboss.managed.api.ManagedProperty;
import org.jboss.managed.api.MutableManagedComponent;
import org.jboss.managed.api.MutableManagedObject;
import org.jboss.managed.api.RunState;
import org.jboss.managed.api.annotation.ViewUse;
import org.jboss.metatype.api.values.MetaValue;
import org.jboss.profileservice.management.AbstractRuntimeComponentDispatcher;
import org.jboss.profileservice.management.ManagedOperationProxyFactory;
import org.jboss.profileservice.spi.Profile;
import org.jboss.profileservice.spi.ProfileKey;
/**
* A abstract profile view.
*
* @author Scott.Stark@jboss.org
* @author adrian@jboss.org
* @author ales.justin@jboss.org
* @author <a href="mailto:emuckenh@redhat.com">Emanuel Muckenhuber</a>
*
* @version $Revision$
*/
public abstract class AbstractProfileView extends AbstractManagedDeploymentView
{
/** The logger. */
private static final Logger log = Logger.getLogger(AbstractProfileView.class);
/** The state mappings. */
private static final ContextStateMapper<RunState> runStateMapper;
private static final ContextStateMapper<DeploymentState> deploymentStateMapper;
/** The runtime component dispatcher. */
private RuntimeComponentDispatcher dispatcher;
/** The proxy factory. */
private ManagedOperationProxyFactory proxyFactory;
static
{
// Set default run state mappings for mc beans/mbeans
Map<String, RunState> runStateMappings = new HashMap<String, RunState>();
runStateMappings.put("**ERROR**", RunState.FAILED);
runStateMappings.put("Not Installed", RunState.STOPPED);
runStateMappings.put("PreInstall", RunState.STOPPED);
runStateMappings.put("Described", RunState.STOPPED);
runStateMappings.put("Instantiated", RunState.STOPPED);
runStateMappings.put("Configured", RunState.STOPPED);
runStateMappings.put("Create", RunState.STOPPED);
runStateMappings.put("Start", RunState.STOPPED);
runStateMappings.put("Installed", RunState.RUNNING);
runStateMapper = new ContextStateMapper<RunState>(runStateMappings,
RunState.STARTING, RunState.STOPPED, RunState.FAILED, RunState.UNKNOWN);
Map<String, DeploymentState> deploymentMappings = new HashMap<String, DeploymentState>();
deploymentMappings.put("**ERROR**", DeploymentState.FAILED);
deploymentMappings.put("Not Installed", DeploymentState.STOPPED);
deploymentMappings.put("Installed", DeploymentState.STARTED);
deploymentStateMapper = new ContextStateMapper<DeploymentState>(deploymentMappings,
DeploymentState.STARTING, DeploymentState.STOPPING, DeploymentState.FAILED, DeploymentState.UNKNOWN);
}
public AbstractProfileView(ManagedOperationProxyFactory proxyFactory)
{
if(proxyFactory == null)
throw new IllegalArgumentException("null proxy factory");
if(proxyFactory.getDispatcher() == null)
throw new IllegalArgumentException("null runtime component dispatcher");
this.proxyFactory = proxyFactory;
this.dispatcher = proxyFactory.getDispatcher();
}
public abstract boolean hasBeenModified(Profile profile);
public abstract ProfileKey getProfileKey();
protected void processRootManagedDeployment(ManagedDeployment md, boolean trace) throws Exception
{
DeploymentState state = getDeploymentState(md);
processManagedDeployment(md, state, 0, trace);
}
@Override
protected void mergeRuntimeMO(ManagedObject mo, ManagedObject runtimeMO)
throws Exception
{
Map<String, ManagedProperty> runtimeProps = runtimeMO.getProperties();
Set<ManagedOperation> runtimeOps = runtimeMO.getOperations();
// Get the runtime MO component name
Object componentName = runtimeMO.getComponentName();
log.debug("Merging runtime: "+runtimeMO.getName()+", compnent name: "+componentName);
Map<String, ManagedProperty> moProps = null;
Set<ManagedOperation> moOps = null;
HashMap<String, ManagedProperty> props = null;
HashSet<ManagedOperation> ops = null;
// If mo is null, the merge target is the runtimeMO
if (mo == null)
{
// Just proxy the runtime props/ops
mo = runtimeMO;
moProps = mo.getProperties();
moOps = mo.getOperations();
// These will be updated with the proxied values, don't duplicate props/ops
props = new HashMap<String, ManagedProperty>();
ops = new HashSet<ManagedOperation>();
}
else
{
// Merge the runtime props/ops
moProps = mo.getProperties();
moOps = mo.getOperations();
props = new HashMap<String, ManagedProperty>(moProps);
ops = new HashSet<ManagedOperation>(moOps);
}
if (runtimeProps != null && runtimeProps.size() > 0)
{
log.debug("Properties before:"+props);
// We need to pull the runtime values for stats
for(ManagedProperty prop : runtimeProps.values())
{
if(prop.hasViewUse(ViewUse.STATISTIC))
{
String propName = prop.getMappedName();
try
{
AbstractRuntimeComponentDispatcher.setActiveProperty(prop);
MetaValue propValue = dispatcher.get(componentName, propName);
if(propValue != null)
prop.setValue(propValue);
}
catch(Throwable t)
{
log.debug("Failed to get stat value, "+componentName+":"+propName);
}
ManagedProperty proxiedProp = createPropertyProxy(prop);
props.put(prop.getName(), proxiedProp);
}
else
{
props.put(prop.getName(), prop);
}
// Keep the property associated with the runtime MO for invocations/updates
if (prop.getTargetManagedObject() == null)
prop.setTargetManagedObject(runtimeMO);
}
log.debug("Properties after:"+props);
}
if (runtimeOps != null && runtimeOps.size() > 0)
{
log.debug("Ops before:"+ops);
runtimeOps = createOperationProxies(runtimeMO, runtimeOps);
ops.addAll(runtimeOps);
log.debug("Ops after:"+ops);
}
MutableManagedObject moi = (MutableManagedObject) mo;
moi.setProperties(props);
moi.setOperations(ops);
}
@Override
protected Set<ManagedOperation> createOperationProxies(ManagedObject mo, Set<ManagedOperation> ops)
throws Exception
{
if (proxyFactory == null)
throw new IllegalArgumentException("Missing RuntimeComponentDispatcher.");
Object componentName = mo.getComponentName();
return createOperationProxies(ops, componentName);
}
protected Set<ManagedOperation> createOperationProxies(Set<ManagedOperation> ops, Object componentName)
throws Exception
{
// Create the delegate operation
return proxyFactory.createOperationProxies(ops, componentName);
}
private ManagedProperty createPropertyProxy(ManagedProperty prop)
throws Exception
{
if (proxyFactory == null)
throw new IllegalArgumentException("Missing RuntimeComponentDispatcher.");
// Create the delegate property
Object componentName = prop.getManagedObject().getComponentName();
return proxyFactory.createPropertyProxy(prop, componentName);
}
protected RunState updateRunState(ManagedObject runtimeMO, ManagedComponent comp)
{
RunState state = comp.getRunState();
if (state == RunState.UNKNOWN && dispatcher != null)
{
Object name = comp.getComponentName();
if (name == null && runtimeMO != null)
name = runtimeMO.getComponentName();
if (name != null)
{
state = getMappedState(name, runStateMapper);
if (comp instanceof MutableManagedComponent)
{
MutableManagedComponent mcomp = MutableManagedComponent.class.cast(comp);
mcomp.setRunState(state);
}
}
}
return state;
}
protected DeploymentState getDeploymentState(ManagedDeployment md)
{
DeploymentState state = md.getDeploymentState();
if(state == DeploymentState.UNKNOWN && dispatcher != null)
{
Object name = md.getName();
if(name != null)
{
state = getMappedState(name, deploymentStateMapper);
}
}
return state;
}
protected <T extends Enum<?>> T getMappedState(Object name, ContextStateMapper<T> mapper)
{
T state = null;
if(dispatcher != null)
{
try
{
//TODO, update RuntimeComponentDispatcher
AbstractRuntimeComponentDispatcher xdispatcher = (AbstractRuntimeComponentDispatcher) dispatcher;
state = xdispatcher.mapControllerState(name, mapper);
}
catch(Exception e)
{
state = mapper.getErrorState();
}
}
return state;
}
}