001/* 002 * (C) Copyright 2006-2010 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * bstefanescu 018 */ 019package org.nuxeo.shell; 020 021import java.util.Arrays; 022import java.util.Comparator; 023import java.util.HashMap; 024import java.util.HashSet; 025import java.util.LinkedHashMap; 026import java.util.Map; 027import java.util.Set; 028import java.util.TreeSet; 029 030import org.nuxeo.shell.impl.DefaultCommandType; 031 032/** 033 * A command registry associated to a given domain name. Registries are named so each registry is using a different 034 * namespace. For example you can have a "local" and a "remote" namespace using different command registries. Commands 035 * in local namespace are working on the filesystem while the one in remote namespace are working on a remote server. 036 * 037 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 038 */ 039public abstract class CommandRegistry { 040 041 protected String name; 042 043 protected CommandRegistry parent; 044 045 protected Map<String, CommandType> cmds; 046 047 public CommandRegistry(CommandRegistry parent, String name) { 048 cmds = new HashMap<String, CommandType>(); 049 this.parent = parent; 050 this.name = name; 051 } 052 053 public abstract String getTitle(); 054 055 public abstract String getDescription(); 056 057 public String getName() { 058 return name; 059 } 060 061 public CommandRegistry getParent() { 062 return parent; 063 } 064 065 public void addCommandType(CommandType type) { 066 cmds.put(type.getName(), type); 067 String[] aliases = type.getAliases(); 068 if (aliases != null && aliases.length > 0) { 069 for (String alias : aliases) { 070 cmds.put(alias, type); 071 } 072 } 073 } 074 075 public void addAnnotatedCommand(Class<? extends Runnable> clazz) { 076 addCommandType(DefaultCommandType.fromAnnotatedClass(clazz)); 077 } 078 079 public CommandType getCommandType(String name) { 080 CommandType type = cmds.get(name); 081 if (type == null && parent != null) { 082 type = parent.getCommandType(name); 083 } 084 return type; 085 } 086 087 public Set<CommandType> getCommandTypeSet() { 088 HashSet<CommandType> set = new HashSet<CommandType>(); 089 if (parent != null) { 090 set.addAll(parent.getCommandTypeSet()); 091 } 092 set.addAll(cmds.values()); 093 return set; 094 } 095 096 public CommandType[] getCommandTypes() { 097 Set<CommandType> set = getCommandTypeSet(); 098 CommandType[] ar = set.toArray(new CommandType[set.size()]); 099 Arrays.sort(ar, new Comparator<CommandType>() { 100 public int compare(CommandType o1, CommandType o2) { 101 return o1.getName().compareTo(o2.getName()); 102 } 103 }); 104 return ar; 105 } 106 107 public CommandType[] getLocalCommandTypes() { 108 CommandType[] ar = cmds.values().toArray(new CommandType[cmds.size()]); 109 Arrays.sort(ar, new Comparator<CommandType>() { 110 public int compare(CommandType o1, CommandType o2) { 111 return o1.getName().compareTo(o2.getName()); 112 } 113 }); 114 return ar; 115 } 116 117 protected void collectCommandTypesByNamespace(Map<String, Set<CommandType>> map) { 118 if (parent != null) { 119 parent.collectCommandTypesByNamespace(map); 120 } 121 TreeSet<CommandType> set = new TreeSet<CommandType>(); 122 for (CommandType cmd : cmds.values()) { 123 set.add(cmd); 124 } 125 map.put(getName(), set); 126 } 127 128 public Map<String, Set<CommandType>> getCommandTypesByNamespace() { 129 LinkedHashMap<String, Set<CommandType>> map = new LinkedHashMap<String, Set<CommandType>>(); 130 collectCommandTypesByNamespace(map); 131 return map; 132 } 133 134 public Set<String> getCommandNameSet() { 135 HashSet<String> set = new HashSet<String>(); 136 if (parent != null) { 137 set.addAll(parent.getCommandNameSet()); 138 } 139 set.addAll(cmds.keySet()); 140 return set; 141 } 142 143 /** 144 * Get sorted command names including aliases 145 * 146 * @return 147 */ 148 public String[] getCommandNames() { 149 Set<String> set = getCommandNameSet(); 150 String[] ar = set.toArray(new String[set.size()]); 151 Arrays.sort(ar); 152 return ar; 153 } 154 155 public void clear() { 156 cmds.clear(); 157 } 158 159 /** 160 * Override this to provide a custom prompt for your command namespace 161 * 162 * @param shell 163 * @return 164 */ 165 public String getPrompt(Shell shell) { 166 return "> "; 167 } 168 169 /** 170 * Override this to automatically run some commands at startup if needed. This is invoked by the interactive mode 171 * just after it was started on the current namespace. This way you can do some initialization for your namespace if 172 * needed - like automatically connecting to remote if connection details were filled to the application command 173 * line arguments. 174 */ 175 public void autorun(Shell shell) { 176 177 } 178}