Creating your own Command shell plugin

To create your own Version number adapter we must create a new class that implements the Command interface:

package com.openkm.terminal;

import java.util.concurrent.BlockingQueue;

import net.xeoh.plugins.base.Plugin;

import org.apache.commons.cli.Options;

import com.openkm.bean.CommandMessageQueue;

 * Command
public interface Command extends Plugin, Runnable {
    public abstract void init(String path, String[] args, BlockingQueue<CommandMessageQueue> queue);
    public abstract Options getOptions();
    public abstract String getHelp();
    public abstract boolean isAllowInputReader();
    public abstract void setInputQueue(BlockingQueue<CommandMessageQueue> inputQueue);
    public abstract String getCommandName();
    public abstract String getDescription();

More information at Register a new plugin.

The new class must be loaded into the package com.openkm.terminal because the application plugin system loads from there.

Do not miss the tag @PluginImplementation otherwise the application plugin system will not be able to retrieve the new class.

Methods description


init(String path, String[] args, BlockingQueue<CommandMessageQueue> queue)


Initialize the object.


Options Return the available command parameters.



Return the command line help.

boolean isAllowInputReader()


Indicate if command can process input values.

"grep" parameter processes the output results of another command line. For example "ls grep test"

setInputQueue(BlockingQueue<CommandMessageQueue> inputQueue)


Set the input queue to be processed.

it only makes sense when isAllowInputReader() returns the value true.

getCommandName() String Return the command name.
getDescription() String Return the description that is shown at the plugin table.

Intermediate object

The command line uses a blocking queue between each command line object execution.

Several environment variables are stored in the envMap, by default they are always stored in the ENVIRONMENT_PARAMETER_PATH that contains the actual path value.

At the beginning the default value is "/okm:root".

When a user goes into another folder - command cd - this value changes.

  • The variable finish, when true, indicate that the queue process has been finished.
  • The variable error indicates that there has been some error when its value is true.
  • The variable message contains some message, normally an error message.
package com.openkm.bean;

import java.util.HashMap;
import java.util.Map;

 * CommandMessageQueue
public class CommandMessageQueue implements Serializable {
    private static final long serialVersionUID = 1L;
    // path
    public static final String ENVIRONMENT_PARAMETER_PATH = "path";
    // message can be displayed in one row or several rows ( table )
    public static final int TYPE_ROW = 1;
    public static final int TYPE_TABLE = 2;
    // indicate when table date start or ends
    public static final int TABLE_DATA_START = 1;
    public static final int TABLE_DATA_END = 2;
    private String message = "";
    private boolean error = false;
    private boolean finish = false;
    private Map<String, String> envMap = new HashMap<String, String>();
    private int type = TYPE_ROW;
    private int tablePosition = 0;
     * CommandMessageQueue
    public CommandMessageQueue() {
     * CommandMessageQueue
    public CommandMessageQueue(String message) {
        this.message = message;
     * CommandMessageQueue
    public CommandMessageQueue(String message, int tablePosition) {
        this.message = message;
        this.tablePosition = tablePosition;
        switch (tablePosition) {             case TABLE_DATA_START:             case TABLE_DATA_END :                 this.type = TYPE_TABLE;                 break;                          default:                 this.type = TYPE_ROW;                 break;         }     }             /**      * CommandMessageQueue      */     public CommandMessageQueue(boolean finish) {         this.finish = finish;     }          /**      * CommandMessageQueue      */     public CommandMessageQueue(boolean error, boolean finish, String message) {         this.error = error;         this.finish = finish;         this.message = message;     }          public String getMessage() {         return message;     }          public void setMessage(String message) {         this.message = message;     }          public boolean isError() {         return error;     }          public void setError(boolean error) {         this.error = error;     }          public boolean isFinish() {         return finish;     }          public void setFinish(boolean finish) {         this.finish = finish;     }          public Map<String, String> getEnvMap() {         return envMap;     }          public int getType() {         return type;     }          public void setType(int type) {         this.type = type;     }          public int getTablePosition() {         return tablePosition;     }          public void setTablePosition(int tablePosition) {         this.tablePosition = tablePosition;     }          public String toString() {         StringBuilder sb = new StringBuilder();         sb.append("{");         sb.append("message=").append(message);         sb.append(", finish=").append(finish);         sb.append(", error=").append(error);         sb.append(", envMap=").append(envMap);         sb.append(", type=").append(type);         sb.append(", tablePosition=").append(tablePosition);         sb.append("}");         return sb.toString();     } }

Example of the Command shell implementation

package com.openkm.terminal;

import java.util.concurrent.BlockingQueue;

import net.xeoh.plugins.base.annotations.PluginImplementation;

import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

import com.openkm.api.OKMFolder;
import com.openkm.api.OKMRepository;
import com.openkm.bean.CommandMessageQueue;
import com.openkm.core.DatabaseException;
import com.openkm.core.PathNotFoundException;
import com.openkm.core.RepositoryException;
import com.openkm.util.CmdUtils;
import com.openkm.util.PathUtils;

* */ @PluginImplementation public class CmdCd implements Command {     private static final String COMMAND_NAME = "cd";     private static final String USAGE = COMMAND_NAME+" [UUID|PATH]->folder";          private BlockingQueue<CommandMessageQueue> queue;     private String path;     private String[] args;     private boolean allowInputReader = false;          @Override     public void init(String path, String[] args, BlockingQueue<CommandMessageQueue> queue) {         this.path = path;         this.queue = queue;         this.args = args;     }          @Override     public String getHelp() {         StringWriter sw = new StringWriter();         PrintWriter pw = new PrintWriter(sw);         CmdUtils.printHelp(pw, USAGE, getOptions());         pw.flush();         pw.close();         return sw.toString();     }          @Override     public Options getOptions() {         Options options = new Options();         options.addOption("?", "help", false, "display this help and exit");         return options;     }          @Override     public boolean isAllowInputReader() {         return allowInputReader;     }          @Override     public void setInputQueue(BlockingQueue<CommandMessageQueue> inputQueue) {     }          @Override     public String getCommandName() {         return COMMAND_NAME;     }          @Override     public String getDescription() {         return "Change current working directory";     }     @Override     public void run() {         CommandLineParser parser = new BasicParser();
        try {             try {                 CommandLine cmdLine = parser.parse(getOptions(), args);                 String arg[] = cmdLine.getArgs();
                if (cmdLine.hasOption("?") || cmdLine.hasOption("help")) {                     queue.put(new CommandMessageQueue(false, false, getHelp()));                 } else if (arg.length > 1) {                     queue.put(new CommandMessageQueue(true, false, COMMAND_NAME+": incorrect arguments"));                     queue.put(new CommandMessageQueue(true, false, "Try \""+COMMAND_NAME+" -?\" for more information"));                 } else {                     if (arg.length == 1) {                         String param = arg[0];
                                                 if (param.equals("..")) {                             path = PathUtils.getParent(path);                         } else if (param.equals(".")) {                             // Nothing to do here                         } else {                             // normalize path                             path = TerminalUtils.normalizePath(param, path);                         }                     } else {                         path = "/okm:root";                     }                                          if (OKMRepository.getInstance().hasNode(null, path)) {                         if (OKMFolder.getInstance().isValid(null, path)) {                             CommandMessageQueue cmq = new CommandMessageQueue();                             cmq.getEnvMap().put(CommandMessageQueue.ENVIRONMENT_PARAMETER_PATH, path);                             queue.put(cmq);                         } else {                             queue.put(new CommandMessageQueue(true, false, "Node "+path+" is not a foldermessage"));                         }                     } else {                         queue.put(new CommandMessageQueue(true, false, "Node "+path+" not exists"));                     }                 }
                queue.put(new CommandMessageQueue(true)); // finish             } catch (ParseException e) {                 queue.put(new CommandMessageQueue(true, false, COMMAND_NAME + " command arguments parse exception"));                 queue.put(new CommandMessageQueue(true, true, "Try \"" + COMMAND_NAME + " -?\" for more information"));                 e.printStackTrace();             } catch (RepositoryException e) {                 queue.put(new CommandMessageQueue(true, true, "RepositoryException:"));                 e.printStackTrace();             } catch (DatabaseException e) {                 queue.put(new CommandMessageQueue(true, true, "DatabaseException:"));                 e.printStackTrace();             } catch (PathNotFoundException e) {                 queue.put(new CommandMessageQueue(true, true, "PathNotFoundException: " + path));                 e.printStackTrace();             }         } catch (InterruptedException e) {             e.printStackTrace();         }     } }