/******************************************************************************* * Copyright (c) 2004, 2006 * Thomas Hallgren, Kenneth Olwing, Mitch Sonies * Pontus Rydin, Nils Unden, Peer Torngren * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the individual * copyright holders listed above, as Initial Contributors under such license. * The text of such license is available at www.eclipse.org. *******************************************************************************/ package org.eclipse.buckminster.cmdline; import java.util.ArrayList; import java.util.HashSet; import org.eclipse.buckminster.runtime.Buckminster; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.osgi.util.NLS; public class CommandInfo { public static final int NORMAL = 0; public static final int DEPRECATED = 1; public static final int HIDDEN = 2; public static final int DISABLED = 3; static private final String COMMAND_EXTPOINT = "org.eclipse.buckminster.cmdline.commands"; //$NON-NLS-1$ static private final String ALIAS_ELEMENTS = "alias"; //$NON-NLS-1$ static private final String CLASS_ATTRIBUTE = "class"; //$NON-NLS-1$ static private final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$ static private final String DEPRECATED_BY_ATTRIBUTE = "deprecatedBy"; //$NON-NLS-1$ static private final char PERIOD_CHARACTER = '.'; static private final String STATUS_ATTRIBUTE = "status"; //$NON-NLS-1$ static private final String ADD_HELP_FLAGS_ATTRIBUTE = "addhelpflags"; //$NON-NLS-1$ static private CommandInfo[] commandInfos; public static CommandInfo getCommand(String commandName) throws UsageException { ArrayList<CommandInfo> matches = new ArrayList<CommandInfo>(); CommandInfo[] implementors = CommandInfo.getImplementors(); int top = implementors.length; StringBuffer sb = new StringBuffer(); for (int idx = 0; idx < top; ++idx) { CommandInfo ci = implementors[idx]; if (ci.getStatus() == CommandInfo.DISABLED) continue; String[] allNames = ci.getAllNames(); for (int nidx = 0; nidx < allNames.length; ++nidx) { String[] parts = allNames[nidx].split("\\."); //$NON-NLS-1$ int len = parts.length; for (int i = 0; i < len; i++) { sb.setLength(0); for (int j = len - i - 1; j < len; j++) { if (sb.length() != 0) sb.append('.'); sb.append(parts[j]); } if (sb.toString().equals(commandName)) matches.add(ci); } } } int foundMatches = matches.size(); if (foundMatches == 0) throw new UsageException(NLS.bind(Messages.CommandInfo_Command_0_not_found, commandName)); if (foundMatches > 1) { sb.setLength(0); sb.append(NLS.bind(Messages.CommandInfo_Multiple_matches_for_0_for, commandName)); for (int idx = 0; idx < foundMatches; ++idx) { CommandInfo ci = matches.get(idx); sb.append(ci.getFullName()); sb.append(NLS.bind(Messages.CommandInfo_implemented_by_class_0, ci.getImplementingClass())); if (idx < foundMatches - 1) sb.append(", "); //$NON-NLS-1$ } throw new UsageException(sb.toString()); } CommandInfo ci = matches.get(0); if (ci.getStatus() == DEPRECATED) { sb.setLength(0); sb.append(NLS.bind(Messages.CommandInfo_Command_0_is_deprecated, ci.getName())); String by = ci.getDeprecatedBy(); if (by != null) { sb.append(NLS.bind(Messages.CommandInfo_Use_command_0_instead, by)); } Buckminster.getLogger().warning(sb.toString()); } return ci; } static public synchronized CommandInfo[] getImplementors() { if (commandInfos == null) { IExtensionRegistry er = Platform.getExtensionRegistry(); IConfigurationElement[] elems = er.getConfigurationElementsFor(COMMAND_EXTPOINT); commandInfos = new CommandInfo[elems.length]; for (int i = 0; i < elems.length; i++) commandInfos[i] = new CommandInfo(elems[i]); } return commandInfos; } private static int parseCommandStatus(String statusString) { int status; if ("normal".equalsIgnoreCase(statusString)) //$NON-NLS-1$ status = NORMAL; else if ("deprecated".equalsIgnoreCase(statusString)) //$NON-NLS-1$ status = DEPRECATED; else if ("hidden".equalsIgnoreCase(statusString)) //$NON-NLS-1$ status = HIDDEN; else if ("disabled".equalsIgnoreCase(statusString)) //$NON-NLS-1$ status = DISABLED; else throw new IllegalArgumentException(NLS.bind(Messages.CommandInfo__0_is_not_a_valid_command_status, statusString)); return status; } private final String[] aliases; private final IConfigurationElement cfgElement; private final String deprecatedBy; private final String name; private final String[] allNames; private final String namespace; private final int status; private CommandInfo(IConfigurationElement cfgElement) { this.cfgElement = cfgElement; status = parseCommandStatus(cfgElement.getAttribute(STATUS_ATTRIBUTE)); IExtension ext = cfgElement.getDeclaringExtension(); StringBuffer ns = new StringBuffer(ext.getNamespaceIdentifier()); String n = cfgElement.getAttribute(NAME_ATTRIBUTE); int period = n.lastIndexOf(PERIOD_CHARACTER); if (period != -1) { ns.append(PERIOD_CHARACTER).append(n.substring(0, period)); n = n.substring(period + 1); } namespace = ns.toString(); name = n; IConfigurationElement[] aliasElements = cfgElement.getChildren(ALIAS_ELEMENTS); HashSet<String> uniqueNames = new HashSet<String>(); for (int i = 0; i < aliasElements.length; i++) { String alias = aliasElements[i].getAttribute(NAME_ATTRIBUTE); if (alias.indexOf(PERIOD_CHARACTER) != -1) throw new IllegalCommandAliasException(alias); if (!n.equals(alias)) uniqueNames.add(alias); } aliases = uniqueNames.toArray(new String[uniqueNames.size()]); uniqueNames.clear(); uniqueNames.add(namespace + PERIOD_CHARACTER + n); for (int i = 0; i < aliases.length; i++) uniqueNames.add(namespace + PERIOD_CHARACTER + aliases[i]); allNames = uniqueNames.toArray(new String[uniqueNames.size()]); deprecatedBy = cfgElement.getAttribute(DEPRECATED_BY_ATTRIBUTE); } public AbstractCommand createInstance() throws CoreException { AbstractCommand cmd = (AbstractCommand) cfgElement.createExecutableExtension(CLASS_ATTRIBUTE); cmd.init(Boolean.valueOf(cfgElement.getAttribute(ADD_HELP_FLAGS_ATTRIBUTE)).booleanValue()); return cmd; } public String[] getAliases() { return aliases; } public String[] getAllNames() { return allNames; } public IConfigurationElement getCfgElement() { return cfgElement; } public String getDeprecatedBy() { return deprecatedBy; } public String getFullName() { return allNames[0]; } public String getImplementingClass() { return cfgElement.getAttribute(CLASS_ATTRIBUTE); } public String getName() { return name; } public String getNamespace() { return namespace; } public int getStatus() { return status; } }