All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.jackrabbit.standalone.cli.JcrClient Maven / Gradle / Ivy

There is a newer version: 2.23.1-beta
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
package org.apache.jackrabbit.standalone.cli;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.jcr.InvalidItemStateException;
import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.RepositoryException;

import jline.ArgumentCompletor;
import jline.Completor;
import jline.ConsoleReader;
import jline.History;
import jline.SimpleCompletor;

import org.apache.commons.chain.Context;
import org.apache.commons.chain.impl.ContextBase;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.Parser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.standalone.cli.CommandException;
import org.apache.jackrabbit.standalone.cli.CommandHelper;
import org.apache.jackrabbit.util.ChildrenCollectorFilter;

/**
 * Command line interface client
 */
public class JcrClient {
    /** logger */
    private static Log log = LogFactory.getLog(JcrClient.class);

    /** Resource bundle */
    private ResourceBundle bundle = CommandHelper.getBundle();

    /** exit control variable */
    private boolean exit = false;

    /** Execution context */
    private Context ctx;

    /** run options */
    private Options options;

    /**
     * Constructor
     */
    JcrClient() {
        super();
        ctx = new ContextBase();
        initOptions();
        initContext();
    }

    /**
     * Constructor
     * @param ctx
     *        the Context
     */
    public JcrClient(Context ctx) {
        super();
        this.ctx = ctx;
    }

    /**
     * @param args
     *        the arguments
     */
    public static void main(String[] args) {
        JcrClient client = new JcrClient();
        client.run(args);
    }

    /**
     * Run client
     * @param args
     *        the arguments
     */
    private void run(String[] args) {
        try {
            // parse arguments
            Parser parser = new BasicParser();
            org.apache.commons.cli.CommandLine cl = parser.parse(options, args);

            // Set locale
            this.setLocale(cl);

            // Welcome message
            System.out.println(bundle.getString("word.welcome"));

            // check interactive mode
            if (cl.hasOption("source")) {
                this.runNonInteractive(cl);
            } else {
                this.runInteractive();
            }
        } catch (Exception e) {
            HelpFormatter hf = new HelpFormatter();
            hf.printHelp("jcrclient", options);
            e.printStackTrace();
            return;
        }
    }
    
    /**
     * jline ConsoleReader tab completor that completes on the children of the
     * current jcr node (both nodes and properties).
     * 
     * @author 
     *         Alexander Klimetschek
     *
     */
    private class JcrChildrenCompletor implements Completor {

        public int complete(String buffer, int cursor, List clist) {
            String start = (buffer == null) ? "" : buffer;
            
            Node node;
            try {
                node = CommandHelper.getNode(ctx, ".");
                Collection items = new ArrayList();
                ChildrenCollectorFilter collector = new ChildrenCollectorFilter(
                    "*", items, true, true, 1);
                collector.visit(node);
                for (Object item : items) {
                    String can = ((Item) item).getName();
                    if (can.startsWith(start)) {
                        clist.add(can);
                    }
                }
                
                return 0;
            } catch (CommandException e) {
                e.printStackTrace();
            } catch (RepositoryException e) {
                e.printStackTrace();
            }
            
            return -1;
        }
        
    }

    /**
     * Run in interactive mode
     * @throws Exception
     *         if an Exception occurs
     */
    public void runInteractive() throws Exception {
        // built jline console reader with history + tab completion
        ConsoleReader reader = new ConsoleReader();
        reader.setHistory(new History());
        reader.setUseHistory(true);
        
        // get all available commands for command tab completion
        Collection commands =
            CommandLineFactory.getInstance().getCommandLines();
        List commandNames = new ArrayList();
        for (CommandLine c : commands) {
            commandNames.add(c.getName());
            for (Object alias : c.getAlias()) {
                commandNames.add((String) alias);
            }
        }
        commandNames.add("exit");
        commandNames.add("quit");
        
        // first part is the command, then all arguments will get children tab completion
        reader.addCompletor(new ArgumentCompletor( new Completor[] {
                new SimpleCompletor(commandNames.toArray(new String[] {} )),
                new JcrChildrenCompletor()
        }));
        
        while (!exit) {
            try {
                String input = reader.readLine("[" + this.getPrompt() + "] > ");
                if (input == null) {
                    input = "exit";
                } else {
                    input = input.trim();
                }
                log.debug("running: " + input);
                if (input.equals("exit") || input.equals("quit")) { // exit?
                    exit = true;
                    System.out.println("Good bye...");
                } else if (input.length() > 0) {
                    this.runCommand(input);
                }
            } catch (JcrParserException e) {
                System.out.println(e.getLocalizedMessage());
                System.out.println();
            } catch (Exception e) {
                handleException(reader, e);
            }
        }
    }

    /**
     * Run in non interactive mode
     * @param cl
     *        the CommandLine
     * @throws Exception
     *         if an Exception occurs while running the
     *         Command
     */
    private void runNonInteractive(org.apache.commons.cli.CommandLine cl) throws Exception {
        this.runCommand("source " + cl.getOptionValue("source"));
    }

    /**
     * Parses the input and runs the specified command
     * @param input
     *        the user's input
     * @throws Exception
     *         if an Exception occurs while running the
     *         Command
     */
    void runCommand(String input) throws Exception {
        if (input.startsWith("#") || input.length() == 0) {
            return;
        }

        // Process user input
        JcrParser parser = new JcrParser();
        parser.parse(input);

        // populate ctx
        parser.populateContext(ctx);

        // Execute command
        long start = System.currentTimeMillis();
        parser.getCommand().execute(ctx);
        long elapsed = System.currentTimeMillis() - start;

        // depopulate ctx
        parser.depopulateContext(ctx);

        // Display elapsed timed
        System.out.println();
        System.out.println(bundle.getString("phrase.elapsedtime") + ": "
                + elapsed + " ms.");
        System.out.println();
    }

    /**
     * Handle the Exception. 
* Shows a short message and prompt the user to show the entire stacktrace. * @param ex * the Exception to handle */ private void handleException(ConsoleReader cr, Exception ex) { System.out.println(); System.out.println(bundle.getString("exception.occurred")); System.out.println(); System.out.println(bundle.getString("exception") + ": " + ex.getClass().getName()); System.out.println(bundle.getString("word.message") + ": " + ex.getLocalizedMessage()); System.out.println(); String prompt = bundle.getString("phrase.display.stacktrace") + "? [y/n]"; String str = ""; int tries = 0; while (!str.equals("y") && !str.equals("n") && tries < 3) { tries++; try { str = cr.readLine(prompt); } catch (IOException e) { e.printStackTrace(); } } if (str.equals("y")) { ex.printStackTrace(); } } /** * Prompt message * @return prompt the prompt message * @throws RepositoryException * if the current Repository throws a * RepositoryException */ private String getPrompt() throws RepositoryException { try { CommandHelper.getRepository(ctx); } catch (CommandException e) { return bundle.getString("phrase.not.connected"); } boolean unsaved = false; try { unsaved = CommandHelper.getSession(ctx).hasPendingChanges(); } catch (CommandException e) { return bundle.getString("phrase.not.logged.in"); } try { Node n = CommandHelper.getCurrentNode(ctx); // the current node might be Invalid String path; try { path = n.getPath(); } catch (InvalidItemStateException e) { CommandHelper.setCurrentNode(ctx, CommandHelper.getSession(ctx) .getRootNode()); path = CommandHelper.getCurrentNode(ctx).getPath(); } if (unsaved) { return path + "*"; } else { return path; } } catch (CommandException e) { return bundle.getString("phrase.not.logged.in"); } } /** * Init allowed CommandLine options */ private void initOptions() { options = new Options(); options.addOption("lang", "code", true, "Language code"); options.addOption("country", "code", true, "Country code"); options.addOption("source", "path", true, "Script for noninteractive mode"); } /** * Sets the default Locale for the given CommandLine * @param cl * the CLI CommandLine * @throws ParseException * if cl can't be parsed */ private void setLocale(org.apache.commons.cli.CommandLine cl) throws ParseException { Locale locale = null; if (cl.hasOption("lang") && cl.hasOption("country")) { locale = new Locale(cl.getOptionValue("lang"), cl .getOptionValue("country")); } if (cl.hasOption("lang") && !cl.hasOption("country")) { locale = new Locale(cl.getOptionValue("lang")); } if (locale != null) { Locale.setDefault(locale); } } /** * Init context.
* Sets the Context Output to the console */ private void initContext() { CommandHelper.setOutput(ctx, new PrintWriter(System.out, true)); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy