/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* CVS $Id: XMLTools.java,v 1.29 2004/02/21 14:29:45 vgritsenko Exp $
*/
package org.apache.xindice.tools;
import org.apache.xindice.client.xmldb.DatabaseImpl;
import org.apache.xindice.server.Xindice;
import org.apache.xindice.tools.command.Command;
import org.apache.xindice.util.StringUtilities;
import org.apache.xindice.util.XindiceException;
import org.apache.xindice.xml.dom.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.XMLDBException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Hashtable;
import java.util.NoSuchElementException;
/**
* XMLAdmin is designed to take command line arguments and give
* user Xindice management flexibility within the current Database.
*
* @version CVS $Revision: 1.29 $, $Date: 2004/02/21 14:29:45 $
*/
public class XMLTools {
public static final String COLLECTION = "collection";
public static final String EXTENSION = "extension";
public static final String FILE_PATH = "filePath";
public static final String ACTION = "action";
public static final String NAME_OF = "nameOf";
public static final String PATTERN = "pattern";
public static final String QUERY = "query";
public static final String URI = "uri";
public static final String VERBOSE = "verbose";
public static final String TYPE = "type";
public static final String PAGE_SIZE = "pagesize";
public static final String MAX_KEY_SIZE = "maxkeysize";
public static final String DB_SERVER = "dbServ";
public static final String PORT = "port";
public static final String HOST = "host";
public static final String USER = "user";
public static final String LOCAL = "local";
public static final String DB_CONFIG = "dbconfig";
public static final String PASSWORD = "password";
public static final String AUTO_KEY = "autoKey";
public static final String NAMESPACES = "namespaces";
public static final String IMPL_CLASS = "implClass";
private Hashtable table;
protected String location = null;
private boolean initialized = false;
private static boolean verbose = false;
private Document commandsDocument = null;
protected NodeList commandsList = null;
public static void main(String[] args) {
try {
new XMLTools().process(args);
} catch (Exception e) {
System.out.println(e.getMessage());
if (verbose) {
e.printStackTrace(System.err);
}
}
}
/** Constructor for XMLTools, includes default variables for the command line
*/
public XMLTools() {
table = new Hashtable();
// defaults for command switches
table.put(FILE_PATH, "");
table.put(EXTENSION, "");
table.put(QUERY, "");
table.put(AUTO_KEY, "");
table.put(VERBOSE, "false");
}
protected void initCommandsList() {
// Get all user elements
NodeList list = getCommandsDocument().getElementsByTagName("user");
if (list.getLength() > 0) {
// Retrieve the index of the first element (<user>)
Element node = (Element) list.item(0);
// get all command children from the user element
list = node.getElementsByTagName("command");
}
// Return the list generated
commandsList = list;
}
/** Return true if this class has admin access
*/
public boolean isAdmin() {
return false;
}
/**
* Carries out necessary initialization of this class.
**/
public void init() throws XindiceException, FileNotFoundException {
if (!initialized) {
initCommandsDocument();
initCommandsList();
initialized = true;
}
}
/**
* Carries out the initialization of the Commands Document.
**/
protected void initCommandsDocument() throws XindiceException, FileNotFoundException {
// Absolute path to the commands.xml file, relative to $XINDICE_HOME
File xindiceHome = new File(System.getProperty(Xindice.PROP_XINDICE_HOME, "."));
File commandsFile = new File(xindiceHome, "config/commands.xml");
commandsDocument = DOMParser.toDocument(new FileInputStream(commandsFile));
}
/**
* Returns the Commands Document use for configuration.
**/
protected Document getCommandsDocument() {
return commandsDocument;
}
/**
* Returns the <command> elements from the Commands Document this
* tool can execute.
**/
protected NodeList getCommands() {
return commandsList;
}
/**
* The Process function is designed for the implementation of the
* command line tools, as well as, making the command line easier
* to use.
**/
public void process(String[] args) throws XindiceException, Exception {
try {
init();
parseArguments(args);
if (!execute()) {
printHelp();
}
} catch (IllegalArgumentException e) {
printHelp();
throw new XindiceException("ERROR : " + e.getMessage(), e);
} catch (NoSuchElementException e) {
throw new NoSuchElementException("ERROR : " + e + " Switch found. Parameter missing.");
} catch (NullPointerException e) {
e.printStackTrace(System.err);
throw new NullPointerException("ERROR : " + e);
} catch (Exception e) {
e.printStackTrace(System.err);
throw new XindiceException("ERROR : " + e.getMessage(), e);
}
}
/**
* Parses and validated the arguments of the command line. The arguments are
* stored into the <tt>table</tt> array.
*
* @exception IllegalArgumentException if an error is found
*/
protected void parseArguments(String[] args)
throws IllegalArgumentException {
// parsing arguments for the command tools
ArgTokenizer at = new ArgTokenizer(args);
if (!at.hasMoreTokens()) {
throw new IllegalArgumentException("No argument found");
}
// Action should always be the second token, if not there show help
table.put(ACTION, at.nextToken());
// Loop over remaining command line arguments, populating hashtable
while (at.hasMoreTokens()) {
String token = at.nextToken();
if (token.equalsIgnoreCase("-c") || token.equalsIgnoreCase("--collection")) {
String colname = at.nextSwitchToken();
if (!colname.startsWith("/") &&
!colname.startsWith("xmldb:xindice")) {
throw new IllegalArgumentException("The name of a collection must start with '/'");
}
table.put(COLLECTION, colname);
} else if (token.equalsIgnoreCase("-e") || token.equalsIgnoreCase("--extension")) {
table.put(EXTENSION, at.nextSwitchToken());
} else if (token.equalsIgnoreCase("-f") || token.equalsIgnoreCase("--filepath")) {
table.put(FILE_PATH, at.nextSwitchToken());
} else if (token.equalsIgnoreCase("-h") || token.equalsIgnoreCase("--help")) {
table.put(ACTION, "help");
} else if (token.equalsIgnoreCase("-n") || token.equalsIgnoreCase("--nameOf")) {
table.put(NAME_OF, at.nextSwitchToken());
} else if (token.equalsIgnoreCase("-p") || token.equalsIgnoreCase("--pattern")) {
table.put(PATTERN, at.nextSwitchToken());
} else if (token.equalsIgnoreCase("-q") || token.equalsIgnoreCase("--query")) {
table.put(QUERY, at.nextSwitchToken());
} else if (token.equalsIgnoreCase("-u") || token.equalsIgnoreCase("--uri")) {
table.put(URI, at.nextSwitchToken());
} else if (token.equalsIgnoreCase("-v") || token.equalsIgnoreCase("--verbose")) {
table.put(VERBOSE, "true");
} else if (token.equalsIgnoreCase("-l") || token.equalsIgnoreCase("--localdb")) {
table.put(LOCAL, "true");
} else if (token.equalsIgnoreCase("-d") || token.equalsIgnoreCase("--dbconfig")) {
String configFile = at.nextSwitchToken();
if (!new File(configFile).isAbsolute()) {
configFile = new File(System.getProperty("user.dir"), configFile).getAbsolutePath();
}
System.setProperty(Xindice.PROP_XINDICE_CONFIGURATION, configFile);
table.put(DB_CONFIG, configFile);
} else if (token.equalsIgnoreCase("-s") || token.equalsIgnoreCase("--namespaces")) {
table.put(NAMESPACES, at.nextSwitchToken());
// Index specific options
} else if (token.equalsIgnoreCase("-t") || token.equalsIgnoreCase("--type")) {
table.put(TYPE, at.nextSwitchToken());
} else if (token.equalsIgnoreCase("+trim")) {
if (!table.containsKey(TYPE)) {
table.put(TYPE, "trimmed");
}
} else if (token.equalsIgnoreCase("-trim")) {
if (!table.containsKey(TYPE)) {
table.put(TYPE, "string");
}
} else if (token.equalsIgnoreCase("--pagesize")) {
table.put(PAGE_SIZE, at.nextSwitchToken());
} else if (token.equalsIgnoreCase("--maxkeysize")) {
table.put(MAX_KEY_SIZE, at.nextSwitchToken());
}
} // End of while loop
}
/**
* This method is to carry out execution, after instance variables being setup by process( args )
*/
public boolean execute() throws Exception {
init();
String action = (String) table.get(ACTION);
// get command class name
String commandClass = null;
if (action != null) {
// search for the tool Class associated with the given action
NodeList commands = getCommands();
for (int i = 0; i < commands.getLength(); i++) {
Element e = (Element) commands.item(i);
if (action.equals(e.getAttribute("switch")) ||
action.equals(e.getAttribute("name"))) {
commandClass = e.getAttribute("class");
}
}
}
if (commandClass != null) {
try {
// Register Xindice Database with xml:db
DatabaseImpl db = new DatabaseImpl();
DatabaseManager.registerDatabase(db);
// Execute command class
Command command = (Command) Class.forName(commandClass).newInstance();
command.execute(table);
// Close Database
if ("true".equals(table.get(LOCAL))) {
command = new org.apache.xindice.tools.command.Shutdown();
command.execute(table);
}
return true;
} catch (XMLDBException e) {
System.err.println("XMLDB Exception " + e.errorCode + ": " + e.getMessage());
if (table.get(VERBOSE).equals("true")) {
e.printStackTrace(System.err);
}
return false;
} catch (Exception e) {
System.err.println("ERROR : " + e.getMessage());
if (table.get(VERBOSE).equals("true")) {
e.printStackTrace(System.err);
}
return false;
}
}
return false;
}
public boolean handleOption(String option, ArgTokenizer at) {
return false;
}
/**
* setAction sets the action type that will be passed to the command line.
*
* @param actionType The action value
*/
public void setAction(String actionType) {
table.put(XMLTools.ACTION, actionType);
}
/**
* getAction returns the action type that will be passed to the command line
* tool.
*
* @return The action value
*/
public String getAction() {
return (String) table.get(XMLTools.ACTION);
}
/**
* setCollectionName sets the collection name that will be passed
* to the command line.
*
* @param collectionName The collection value
*/
public void setCollectionName(String collectionName) {
table.put(COLLECTION, collectionName);
}
/**
* getCollectionName returns the collection name that will be passed
* to the command line tool.
*
* @return The collection value
*/
public String getCollectionName() {
return (String) table.get(COLLECTION);
}
/**
* setDocumentName sets the document that will be passed to the
* command line tool.
*
* @param documentName The docName value
*/
public void setDocumentName(String documentName) {
table.put(XMLTools.NAME_OF, documentName);
}
/**
* getDocumentName returns the document that will be passed to the
* command line tool.
*
* @return The docName value
*/
public String getDocumentName() {
return (String) table.get(XMLTools.NAME_OF);
}
/**
* setQuery sets the Query variable for Document Query from the command line.
*
* @param query - The query string
*/
public void setQuery(String query) {
table.put(XMLTools.QUERY, query);
}
/**
* getQuery returns the Query for Document passed to the command line tool.
*/
public String getQuery() {
return (String) table.get(XMLTools.QUERY);
}
/**
* setName sets the name for XMLObjects passed to the command line tool.
*
* @param name The docName value
*/
public void setName(String name) {
table.put(XMLTools.NAME_OF, name);
}
/**
* getName returns the name for XMLObjects that will be passed to the
* command line tool.
*
* @return The nameOf value
*/
public String getName() {
return (String) table.get(XMLTools.NAME_OF);
}
/**
* setDatabaseServer sets the Database server name that will be
* passed to the command line tool.
*
* @param appName The dbServ value
*/
public void setDatabaseServer(String appName) {
table.put(XMLTools.DB_SERVER, appName);
}
/**
* getDatabaseServer returns the Database server that will be
* passed to the command line tool.
*
* @return The dbServ value
*/
public String getDatabaseServer() {
return (String) table.get(XMLTools.DB_SERVER);
}
/**
* setPort sets the port that will passed to the command line tool.
*
* @param portName The port value
*/
public void setPort(String portName) {
table.put(XMLTools.PORT, portName);
}
/**
* getPort returns the port that will be passed to the command line tool.
*
* @return The port value
*/
public String getPort() {
return (String) table.get(XMLTools.PORT);
}
/**
* setHost sets the host that will passed to the command line tool.
*
* @param hostName The host value
*/
public void setHost(String hostName) {
table.put(HOST, hostName);
}
/**
* getPort returns the host that will be passed to the command line tool.
*
* @return The host value
*/
public String getHost() {
return (String) table.get(HOST);
}
/**
* setFilePath sets the file path that will passed to the command line tool.
*
* @param fPath The filePath value
*/
public void setFilePath(String fPath) {
table.put(XMLTools.FILE_PATH, fPath);
}
/**
* getFilePath returns the file path that will be passed to the command
*
* @return The filePath value
*/
public String getFilePath() {
return (String) table.get(XMLTools.FILE_PATH);
}
/**
* setURI sets the database URI (protocol://host:port/name) that
* will be passed to the command line
*
* @param URI The URI for the database
*/
public void setURI(String URI) {
table.put(XMLTools.URI, URI);
}
/**
* getURI gets returns the database URI (protocol://host:port/name)
* that will be passed to the command line tool
*
* @return The URI for the database
*/
public String getURI() {
return (String) table.get(XMLTools.URI);
}
/**
* setImplementClass sets the implemented class path that will be passed
* to the command line tool.
*
* @param imClassName The implClass value
*/
public void setImplementClass(String imClassName) {
table.put(XMLTools.IMPL_CLASS, imClassName);
}
/**
* getImplementClass returns the implmented class path that will be passed
* to the command line tool.
*
* @return The implClass value
*/
public String getImplementClass() {
return (String) table.get(XMLTools.IMPL_CLASS);
}
/**
* The following Security methods are simply a starting point. User names and
* their related passwords will not be this simple. Until Encryption for
* Passwords are developed, and KeyStorage is set-up, this will do for now.
* In the future, these methods will change as needed to be more efficient
* for Xindice.
*/
/**
* setUser sets the user that will be passed to the command line tool and
* will be used in Security issues.
*
* @param userName The user value
*/
public void setUser(String userName) {
table.put(XMLTools.USER, userName);
}
/**
* getUser returns the user that will be passed to the command line tool and
* will be used in Security issues.
*
* @return The user value
*/
public String getUser() {
return (String) table.get(XMLTools.USER);
}
/**
* setPassword sets the password that will be passed to the command line tool
* and will be used in conjunction with the userName value.
*
* @param pswd The passwrd value
*/
public void setPassword(String pswd) {
table.put(PASSWORD, pswd);
}
/**
* getPassword returns the password that will be passed to the command line
* tool and will be used in conjunction with the userName value.
*
* @return The password value
*/
public String getPassword() {
return (String) table.get(PASSWORD);
}
public void printHelp() {
NodeList list = getCommands();
// This method relies on two things to format the output for help
// Method isAdmin() - Tells us if this is an admin instance, used to hide certain output
// XML file Commands.xml attribute "helpclass" - used to order output
String helpClass; // Holds the helpclass for the current <command> node
String desc; // Holds the description for the current <command> node
String cmdswitch; // Holds the switch for the current <command> node
// Show the header and switch commands
System.out.println();
System.out.println("Xindice Command Tools v" + Xindice.Version);
System.out.println();
System.out.println("Format: xindice action [switch] [parameter]");
System.out.println();
System.out.println("Switches:");
System.out.println(" -c Collection context (must always be specified),");
System.out.println(" can be either canonical name of the collection");
System.out.println(" or complete xmldb URL");
System.out.println(" -e File extension for multiple documents");
System.out.println(" -f File path for document retrieval and storage");
System.out.println(" -n Name");
System.out.println(" -p Index pattern");
System.out.println(" -q Query string");
System.out.println(" -s Semi-colon delimited list of namespaces for query in ");
System.out.println(" the form prefix=namespace-uri");
System.out.println(" -l Use a local database rather then going over the network.");
System.out.println(" Should be combined with -d to specify the configuration to use.");
System.out.println(" -d Path to the database configuration to use for the local ");
System.out.println(" database. Only applies if -l is specified.");
System.out.println(" -t Specify the data type in collection index");
System.out.println(" -v Verbose");
System.out.println(" --pagesize Page size for file pages (default: 4096)");
System.out.println(" --maxkeysize The maximum size for file keys (default: 0=none)");
System.out.println();
System.out.println("Actions:");
// Show all elements with helpclass=document
// Loop over the commands, printing test from description attribute
for (int i = 0; i < list.getLength(); i++) {
helpClass = ((Element) list.item(i)).getAttribute("helpclass");
if (helpClass.equals("document")) {
desc = ((Element) list.item(i)).getAttribute("description");
cmdswitch = ((Element) list.item(i)).getAttribute("switch");
System.out.println(" " + StringUtilities.leftJustify(cmdswitch, 13) + desc);
}
}
// Loop over the commands, printing text from description attribute
for (int i = 0; i < list.getLength(); i++) {
helpClass = ((Element) list.item(i)).getAttribute("helpclass");
if (helpClass.equals("security")) {
desc = ((Element) list.item(i)).getAttribute("description");
cmdswitch = ((Element) list.item(i)).getAttribute("switch");
System.out.println(" " + StringUtilities.leftJustify(cmdswitch, 13) + desc);
}
}
System.out.println();
System.out.println("Examples:");
System.out.println(" xindice ad -c /db/test -f /tmp/xmldocument -n myxmldocument");
System.out.println(" xindice dd -c /db/test -n myxmldocument");
System.out.println(" xindice rd -c /db/test/ocs -f a:\\file.xml -n file.xml");
System.out.println(" xindice xpath -c /db/test/ocs -q test");
System.out.println(" xindice xpath -c /db/test -s a=http://somedomain.com/schema.xsd -q /a:foo");
System.out.println(" xindice xupdate -c /db/test -f /path/to/xupdate.xml");
System.out.println(" xindice xupdate -c /db/test -n document-to-update.xml -f /path/to/xupdate.xml");
System.out.println();
System.out.println("For more information, please read the Xindice - Tools Reference Guide");
System.out.println();
}
}