Clover coverage report -
Coverage timestamp: Sun Nov 1 2009 23:08:24 UTC
file stats: LOC: 367   Methods: 18
NCLOC: 249   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
XMLTools.java 13.6% 16% 27.8% 16.3%
coverage coverage
 1    /*
 2    * Licensed to the Apache Software Foundation (ASF) under one or more
 3    * contributor license agreements. See the NOTICE file distributed with
 4    * this work for additional information regarding copyright ownership.
 5    * The ASF licenses this file to You under the Apache License, Version 2.0
 6    * (the "License"); you may not use this file except in compliance with
 7    * the License. You may obtain a copy of the License at
 8    *
 9    * http://www.apache.org/licenses/LICENSE-2.0
 10    *
 11    * Unless required by applicable law or agreed to in writing, software
 12    * distributed under the License is distributed on an "AS IS" BASIS,
 13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14    * See the License for the specific language governing permissions and
 15    * limitations under the License.
 16    *
 17    * $Id: XMLTools.java 593003 2007-11-08 03:12:23Z natalia $
 18    */
 19   
 20    package org.apache.xindice.tools;
 21   
 22    import org.apache.xindice.client.xmldb.DatabaseImpl;
 23    import org.apache.xindice.server.Xindice;
 24    import org.apache.xindice.tools.command.Command;
 25    import org.apache.xindice.util.XindiceException;
 26    import org.apache.xindice.xml.dom.DOMParser;
 27   
 28    import org.w3c.dom.Document;
 29    import org.w3c.dom.Element;
 30    import org.w3c.dom.NodeList;
 31    import org.xmldb.api.DatabaseManager;
 32    import org.xmldb.api.base.XMLDBException;
 33   
 34    import java.io.File;
 35    import java.io.FileInputStream;
 36    import java.io.FileNotFoundException;
 37    import java.util.NoSuchElementException;
 38    import java.util.HashMap;
 39    import java.util.List;
 40    import java.util.ArrayList;
 41   
 42    /**
 43    * XMLTools parses command line arguments and executes corresponding command
 44    * to give user Xindice management flexibility within the current Database.
 45    *
 46    * @version $Revision: 593003 $, $Date: 2007-11-08 03:12:23 +0000 (Thu, 08 Nov 2007) $
 47    */
 48    public class XMLTools {
 49   
 50    public static final String COLLECTION = "collection";
 51    public static final String FILER = "filer";
 52    public static final String EXTENSION = "extension";
 53    public static final String FILE_PATH = "filePath";
 54    public static final String ACTION = "action";
 55    public static final String NAME_OF = "nameOf";
 56    public static final String PATTERN = "pattern";
 57    public static final String QUERY = "query";
 58    public static final String VERBOSE = "verbose";
 59    public static final String HELP = "help";
 60    public static final String TYPE = "type";
 61    public static final String PAGE_SIZE = "pagesize";
 62    public static final String MAX_KEY_SIZE = "maxkeysize";
 63    public static final String LOCAL = "local";
 64    public static final String DB_CONFIG = "dbconfig";
 65    public static final String NAMESPACES = "namespaces";
 66    public static final String COMMAND_LIST = "__command_list__";
 67    public static final String PAGE_COUNT = "pagecount";
 68   
 69    private Config config;
 70    private boolean initialized;
 71   
 72    private List commandsList;
 73   
 74  0 public static void main(String[] args) {
 75  0 XMLTools tools = new XMLTools();
 76  0 try {
 77  0 tools.process(args);
 78    } catch (Exception e) {
 79  0 System.err.println(e.getMessage());
 80  0 if (tools.config.getBoolean(VERBOSE)) {
 81  0 e.printStackTrace();
 82    }
 83    }
 84    }
 85   
 86    /**
 87    * Constructor for XMLTools, includes default variables for the
 88    * command line.
 89    */
 90  3 public XMLTools() {
 91  3 config = new Config();
 92    }
 93   
 94    /**
 95    * Constructor for XMLTools based on existing Config.
 96    */
 97  0 public XMLTools(Config config) {
 98  0 this.config = config;
 99    }
 100   
 101    /**
 102    * Reads commands document from config directory.
 103    */
 104  0 private Document readCommandsDocument() throws XindiceException, FileNotFoundException {
 105    // Absolute path to the commands.xml file, relative to $XINDICE_HOME
 106  0 File xindiceHome = new File(System.getProperty(Xindice.PROP_XINDICE_HOME, "."));
 107  0 File commandsFile = new File(xindiceHome, "config/commands.xml");
 108   
 109  0 return DOMParser.toDocument(new FileInputStream(commandsFile));
 110    }
 111   
 112  0 private void parseCommandsList(Document commands) {
 113    // Get all user elements
 114  0 NodeList list = commands.getElementsByTagName("user");
 115   
 116  0 if (list.getLength() > 0) {
 117    // Retrieve the index of the first element (<user>)
 118  0 Element node = (Element) list.item(0);
 119    // get all command children from the user element
 120  0 list = node.getElementsByTagName("command");
 121    }
 122   
 123  0 List commandList = new ArrayList();
 124  0 for (int i = 0; i < list.getLength(); i++) {
 125  0 Element e = (Element) list.item(i);
 126  0 String switchName = e.getAttribute("switch");
 127  0 String fullName = e.getAttribute("name");
 128  0 String className = e.getAttribute("class");
 129  0 String descr = e.getAttribute("description");
 130  0 String helpClass = e.getAttribute("helpclass");
 131  0 commandList.add(new Action(className, descr, helpClass, switchName, fullName));
 132    }
 133   
 134    // Return the list generated
 135  0 commandsList = commandList;
 136   
 137    // Add the command list so that the HelpCommand can access it and
 138    // print specific help information.
 139  0 config.setActions(commandsList);
 140    }
 141   
 142    /**
 143    * Carries out necessary initialization of this class.
 144    */
 145  0 public void init() throws XindiceException, FileNotFoundException {
 146  0 if (!initialized) {
 147  0 parseCommandsList(readCommandsDocument());
 148  0 initialized = true;
 149    }
 150    }
 151   
 152    /**
 153    * Returns the <command> elements from the Commands Document this
 154    * tool can execute.
 155    */
 156  0 protected List getCommands() {
 157  0 return commandsList;
 158    }
 159   
 160    /**
 161    * The Process function is designed for the implementation of the
 162    * command line tools, as well as, making the command line easier
 163    * to use.
 164    */
 165  0 public void process(String[] args) throws XindiceException {
 166  0 try {
 167  0 parseArguments(args);
 168  0 execute();
 169    } catch (IllegalArgumentException e) {
 170  0 throw new XindiceException("ERROR : " + e.getMessage() + " Try -h for help.", e);
 171    } catch (NoSuchElementException e) {
 172  0 throw new NoSuchElementException("ERROR : " + e + " Switch found. Parameter missing. Try -h for help.");
 173    } catch (NullPointerException e) {
 174  0 throw new NullPointerException("ERROR : " + e + " Try -h for help.");
 175    } catch (Exception e) {
 176  0 throw new XindiceException("ERROR : " + e.getMessage() + " Try -h for help.", e);
 177    }
 178    }
 179   
 180    /**
 181    * Parses and validated the arguments of the command line. The arguments are
 182    * stored into the <tt>Config</tt> object.
 183    *
 184    * @exception IllegalArgumentException if an error is found
 185    */
 186  3 protected void parseArguments(String[] args) throws IllegalArgumentException {
 187   
 188    // parsing arguments for the command tools
 189  3 ArgTokenizer at = new ArgTokenizer(args);
 190  3 if (!at.hasMoreTokens()) {
 191  0 throw new IllegalArgumentException("No arguments found");
 192    }
 193   
 194    // Action should always be the second token, if not there show help
 195  3 config.setString(ACTION, at.nextToken());
 196   
 197    // Loop over remaining command line arguments, populating hashtable
 198  3 while (at.hasMoreTokens()) {
 199  3 String token = at.nextToken();
 200   
 201  3 if (token.equalsIgnoreCase("-h") || token.equalsIgnoreCase("--help")) {
 202  0 config.setBoolean(HELP, true);
 203  3 } else if (token.equalsIgnoreCase("-c") || token.equalsIgnoreCase("--collection")) {
 204  3 String colname = at.nextSwitchToken();
 205  3 if (!colname.startsWith("/") && !colname.startsWith("xmldb:xindice")) {
 206  1 throw new IllegalArgumentException("The name of a collection must start with '/'");
 207    }
 208   
 209  2 if (colname.startsWith("xmldb:xindice-embed://")) {
 210  1 config.setBoolean(LOCAL, true);
 211    }
 212  2 config.setString(COLLECTION, colname);
 213  0 } else if (token.equalsIgnoreCase("--filer")) {
 214  0 config.setString(FILER, at.nextSwitchToken());
 215  0 } else if (token.equalsIgnoreCase("-e") || token.equalsIgnoreCase("--extension")) {
 216  0 config.setString(EXTENSION, at.nextSwitchToken());
 217  0 } else if (token.equalsIgnoreCase("-f") || token.equalsIgnoreCase("--filepath")) {
 218  0 config.setString(FILE_PATH, at.nextSwitchToken());
 219  0 } else if (token.equalsIgnoreCase("-n") || token.equalsIgnoreCase("--nameOf")) {
 220  0 config.setString(NAME_OF, at.nextSwitchToken());
 221  0 } else if (token.equalsIgnoreCase("-p") || token.equalsIgnoreCase("--pattern")) {
 222  0 config.setString(PATTERN, at.nextSwitchToken());
 223  0 } else if (token.equalsIgnoreCase("-q") || token.equalsIgnoreCase("--query")) {
 224  0 config.setString(QUERY, at.nextSwitchToken());
 225  0 } else if (token.equalsIgnoreCase("-v") || token.equalsIgnoreCase("--verbose")) {
 226  0 config.setBoolean(VERBOSE, true);
 227  0 } else if (token.equalsIgnoreCase("-l") || token.equalsIgnoreCase("--localdb")) {
 228  0 config.setBoolean(LOCAL, true);
 229  0 } else if (token.equalsIgnoreCase("-d") || token.equalsIgnoreCase("--dbconfig")) {
 230  0 String configFile = at.nextSwitchToken();
 231  0 if (!new File(configFile).isAbsolute()) {
 232  0 configFile = new File(System.getProperty("user.dir"), configFile).getAbsolutePath();
 233    }
 234  0 System.setProperty(Xindice.PROP_XINDICE_CONFIGURATION, configFile);
 235  0 config.setString(DB_CONFIG, configFile);
 236  0 } else if (token.equalsIgnoreCase("-s") || token.equalsIgnoreCase("--namespaces")) {
 237  0 config.setString(NAMESPACES, at.nextSwitchToken());
 238    // Index specific options
 239  0 } else if (token.equalsIgnoreCase("-t") || token.equalsIgnoreCase("--type")) {
 240  0 config.setString(TYPE, at.nextSwitchToken());
 241  0 } else if (token.equalsIgnoreCase("--pagesize")) {
 242  0 config.setString(PAGE_SIZE, at.nextSwitchToken());
 243  0 } else if (token.equalsIgnoreCase("--maxkeysize")) {
 244  0 config.setString(MAX_KEY_SIZE, at.nextSwitchToken());
 245  0 } else if (token.equalsIgnoreCase("--pagecount")) {
 246  0 config.setString(PAGE_COUNT, at.nextSwitchToken());
 247    } else {
 248    // todo: unrecognized switch
 249    }
 250    }
 251    }
 252   
 253    /**
 254    * This method is to carry out execution, after instance variables being setup by process( args )
 255    */
 256  0 public boolean execute() throws Exception {
 257  0 init();
 258  0 String action = config.getString(ACTION);
 259   
 260    // get command class name
 261  0 String commandClass = null;
 262  0 if (action != null) {
 263    // search for the tool Class associated with the given action
 264  0 List commands = getCommands();
 265  0 for (int i = 0; i < commands.size(); i++) {
 266  0 Action a = (Action) commands.get(i);
 267  0 if (action.equals(a.switchName) || action.equals(a.fullName)) {
 268  0 commandClass = a.className;
 269    }
 270    }
 271    }
 272   
 273  0 if (commandClass == null) {
 274  0 throw new IllegalArgumentException("\"" + action + "\" not recognized.");
 275    }
 276   
 277  0 Command command;
 278  0 try {
 279  0 command = (Command) Class.forName(commandClass).newInstance();
 280  0 if (config.getBoolean(HELP)) {
 281    // show command help
 282  0 command.usage();
 283    } else {
 284    // Register Xindice Database with XML:DB
 285  0 DatabaseImpl db = new DatabaseImpl();
 286  0 DatabaseManager.registerDatabase(db);
 287   
 288    // Execute command class
 289  0 command.execute(config);
 290    }
 291   
 292  0 return true;
 293    } catch (XMLDBException e) {
 294  0 System.err.println("XMLDB Exception " + e.errorCode + ": " + e.getMessage());
 295  0 if (config.getBoolean(VERBOSE)) {
 296  0 e.printStackTrace(System.err);
 297    }
 298  0 return false;
 299    } catch (Exception e) {
 300  0 System.err.println("ERROR : " + e.getMessage());
 301  0 if (config.getBoolean(VERBOSE)) {
 302  0 e.printStackTrace(System.err);
 303    }
 304  0 return false;
 305    } finally {
 306    // Close Database
 307  0 if (config.getBoolean(LOCAL)) {
 308  0 command = new org.apache.xindice.tools.command.Shutdown();
 309  0 command.execute(config);
 310    }
 311    }
 312    }
 313   
 314    public static class Config {
 315    private HashMap config;
 316   
 317  3 public Config() {
 318  3 config = new HashMap();
 319   
 320    // defaults for command switches
 321  3 setString(FILE_PATH, "");
 322  3 setString(EXTENSION, "");
 323  3 setString(QUERY, "");
 324  3 setBoolean(VERBOSE, false);
 325    }
 326   
 327  0 public String getString(String param) {
 328  0 return (String) config.get(param);
 329    }
 330   
 331  14 public void setString(String param, String value) {
 332  14 config.put(param, value);
 333    }
 334   
 335  0 public boolean getBoolean(String param) {
 336  0 return Boolean.TRUE.equals(config.get(param));
 337    }
 338   
 339  4 public void setBoolean(String param, boolean value) {
 340  4 config.put(param, Boolean.valueOf(value));
 341    }
 342   
 343  0 public List getActions() {
 344  0 return (List) config.get(COMMAND_LIST);
 345    }
 346   
 347  0 public void setActions(List value) {
 348  0 config.put(COMMAND_LIST, value);
 349    }
 350    }
 351   
 352    public static class Action {
 353    public final String helpclass;
 354    public final String className;
 355    public final String description;
 356    public final String switchName;
 357    public final String fullName;
 358   
 359  0 public Action(String className, String description, String helpclass, String switchName, String fullName) {
 360  0 this.helpclass = helpclass;
 361  0 this.className = className;
 362  0 this.description = description;
 363  0 this.switchName = switchName;
 364  0 this.fullName = fullName;
 365    }
 366    }
 367    }