package org.cyclopsgroup.jmxterm.cc;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.collections.ExtendedProperties;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.Validate;
import org.cyclopsgroup.jmxterm.Command;
import org.cyclopsgroup.jmxterm.CommandFactory;
import org.cyclopsgroup.jmxterm.utils.ExtendedPropertiesUtils;
/**
* Factory class of commands which knows how to create Command class with given command name
*
* @author <a href="mailto:jiaqi.guo@gmail.com">Jiaqi Guo</a>
*/
class PredefinedCommandFactory
implements CommandFactory
{
private final CommandFactory delegate;
/**
* Default constructor
*
* @throws IOException Thrown when Jar is corrupted
*/
PredefinedCommandFactory()
throws IOException
{
this( "META-INF/cyclopsgroup/jmxterm.properties" );
}
/**
* Constructor which builds up command types
*
* @param configPath Path of configuration file in classpath
* @throws IOException Thrown when Jar is corrupted
*/
@SuppressWarnings( "unchecked" )
public PredefinedCommandFactory( String configPath )
throws IOException
{
Validate.notNull( configPath, "configPath can't be NULL" );
ClassLoader classLoader = getClass().getClassLoader();
ExtendedProperties props = ExtendedPropertiesUtils.loadFromOverlappingResources( configPath, classLoader );
if ( props == null )
{
throw new FileNotFoundException( "Couldn't load configuration from " + configPath
+ ", classpath has problem" );
}
props = props.subset( "jmxterm.commands" );
if ( props == null )
{
throw new IOException( "Expected configuration doesn't appear in " + configPath );
}
HashMap<String, Class<? extends Command>> commands = new HashMap<String, Class<? extends Command>>();
for ( String name : props.getStringArray( "name" ) )
{
String type = props.getString( name + ".type" );
Class<? extends Command> commandType;
try
{
commandType = (Class<? extends Command>) classLoader.loadClass( type );
}
catch ( ClassNotFoundException e )
{
throw new RuntimeException( "Couldn't load type " + type, e );
}
commands.put( name, commandType );
String[] aliases = props.getStringArray( name + ".alias" );
if ( !ArrayUtils.isEmpty( aliases ) )
{
for ( String alias : aliases )
{
commands.put( alias, commandType );
}
}
}
commands.put( "help", HelpCommand.class );
delegate = new TypeMapCommandFactory( commands );
}
/**
* @inheritDoc
*/
public Command createCommand( String commandName )
{
return delegate.createCommand( commandName );
}
/**
* @inheritDoc
*/
public Map<String, Class<? extends Command>> getCommandTypes()
{
return delegate.getCommandTypes();
}
}