package org.neo4j.util.shell.apps;
import java.rmi.RemoteException;
import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;
import org.neo4j.util.shell.AbstractApp;
import org.neo4j.util.shell.AbstractAppServer;
import org.neo4j.util.shell.App;
import org.neo4j.util.shell.AppCommandParser;
import org.neo4j.util.shell.ClassLister;
import org.neo4j.util.shell.OptionValueType;
import org.neo4j.util.shell.Output;
import org.neo4j.util.shell.Session;
import org.neo4j.util.shell.ShellException;
import org.neo4j.util.shell.ShellServer;
public class Man extends AbstractApp
{
private static Collection<String> availableCommands;
public String execute( AppCommandParser parser, Session session,
Output out ) throws ShellException
{
try
{
if ( parser.arguments().size() == 0 )
{
// throw new ShellException(
// "Need to supply a command: " + getShortUsageString() );
out.println( getHelpString( getServer() ) );
return null;
}
App app = this.getApp( parser );
out.println( "" );
out.println( this.fixDesciption( app.getDescription() ) );
println( out, "" );
boolean hasOptions = false;
for ( String option : app.getAvailableOptions() )
{
hasOptions = true;
String description = this.fixDesciption(
app.getDescription( option ) );
OptionValueType type = app.getOptionValueType( option );
println( out, "-" + option + "\t" + description + " " +
( type == OptionValueType.NONE ? "(no value)" : "" ) +
( type == OptionValueType.MAY ? "(may have value)" : "" ) +
( type == OptionValueType.MUST ? "(must have value)" : "" ) );
}
if ( hasOptions )
{
println( out, "" );
}
}
catch ( RemoteException e )
{
throw new ShellException( e );
}
return null;
}
private static String getShortUsageString()
{
return "man <command>";
}
private String fixDesciption( String description )
{
if ( description == null )
{
description = "";
}
else if ( !description.endsWith( "." ) )
{
description = description + ".";
}
return description;
}
private void println( Output out, String string ) throws RemoteException
{
out.println( "\t" + string );
}
private App getApp( AppCommandParser parser ) throws ShellException
{
String appName = parser.arguments().get( 0 );
try
{
App app = this.getServer().findApp( appName );
if ( app == null )
{
throw new ShellException( "No manual entry for '" +
appName + "'" );
}
return app;
}
catch ( RemoteException e )
{
throw new ShellException( e );
}
}
@Override
public String getDescription()
{
return "Display a manual for a command or a general help message.\n" +
"Usage: " + getShortUsageString();
}
public static String getHelpString( ShellServer server )
{
return "Available commands: " +
availableCommandsAsString( server ) + "\n" +
"Use " + getShortUsageString() + " for info about each command.";
}
public static synchronized Collection<String> getAvailableCommands(
ShellServer server )
{
if ( availableCommands == null )
{
// TODO Shouldn't trust the server to be an AbstractAppServer
Set<String> packages =
( ( AbstractAppServer ) server ).getPackages();
availableCommands = new TreeSet<String>();
for ( Class<? extends App> appClass :
ClassLister.listClassesExtendingOrImplementing( App.class,
packages ) )
{
if ( packages.contains( appClass.getPackage().getName() ) )
{
availableCommands.add(
appClass.getSimpleName().toLowerCase() );
}
}
availableCommands.add( "quit" );
}
return availableCommands;
}
private static synchronized String availableCommandsAsString(
ShellServer server )
{
StringBuffer commands = new StringBuffer();
for ( String command : getAvailableCommands( server ) )
{
if ( commands.length() > 0 )
{
commands.append( " " );
}
commands.append( command );
}
return commands.toString();
}
}