Java tutorial
/**************************************************************** * 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.james.cli; import java.io.IOException; import java.io.PrintStream; import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.time.StopWatch; import org.apache.james.adapter.mailbox.SerializableQuota; import org.apache.james.cli.exceptions.InvalidArgumentNumberException; import org.apache.james.cli.exceptions.InvalidPortException; import org.apache.james.cli.exceptions.JamesCliException; import org.apache.james.cli.exceptions.MissingCommandException; import org.apache.james.cli.exceptions.UnrecognizedCommandException; import org.apache.james.cli.probe.ServerProbe; import org.apache.james.cli.probe.impl.JmxServerProbe; import org.apache.james.cli.type.CmdType; import org.apache.james.cli.utils.ValueWithUnit; import org.apache.james.mailbox.model.Quota; import org.apache.james.rrt.lib.Mappings; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; /** * Command line utility for managing various aspect of the James server. */ public class ServerCmd { public static final String HOST_OPT_LONG = "host"; public static final String HOST_OPT_SHORT = "h"; public static final String PORT_OPT_LONG = "port"; public static final String PORT_OPT_SHORT = "p"; private static final int DEFAULT_PORT = 9999; private static Options createOptions() { Options options = new Options(); Option optHost = new Option(HOST_OPT_SHORT, HOST_OPT_LONG, true, "node hostname or ip address"); optHost.setRequired(true); options.addOption(optHost); options.addOption(PORT_OPT_SHORT, PORT_OPT_LONG, true, "remote jmx agent port number"); return options; } private final ServerProbe probe; public ServerCmd(ServerProbe probe) { this.probe = probe; } /** * Main method to initialize the class. * * @param args Command-line arguments. */ public static void main(String[] args) { try { StopWatch stopWatch = new StopWatch(); stopWatch.start(); CommandLine cmd = parseCommandLine(args); CmdType cmdType = new ServerCmd(new JmxServerProbe(cmd.getOptionValue(HOST_OPT_LONG), getPort(cmd))) .executeCommandLine(cmd); stopWatch.split(); print(new String[] { Joiner.on(' ').join(cmdType.getCommand(), "command executed sucessfully in", stopWatch.getSplitTime(), "ms.") }, System.out); stopWatch.stop(); System.exit(0); } catch (JamesCliException e) { failWithMessage(e.getMessage()); } catch (ParseException e) { failWithMessage("Error parsing command line : " + e.getMessage()); } catch (IOException ioe) { failWithMessage("Error connecting to remote JMX agent : " + ioe.getMessage()); } catch (Exception e) { failWithMessage("Error while executing command:" + e.getMessage()); } } @VisibleForTesting static CommandLine parseCommandLine(String[] args) throws ParseException { CommandLineParser parser = new PosixParser(); CommandLine commandLine = parser.parse(createOptions(), args); if (commandLine.getArgs().length < 1) { throw new MissingCommandException(); } return commandLine; } @VisibleForTesting static int getPort(CommandLine cmd) throws ParseException { String portNum = cmd.getOptionValue(PORT_OPT_LONG); if (portNum != null) { try { return validatePortNumber(Integer.parseInt(portNum)); } catch (NumberFormatException e) { throw new ParseException("Port must be a number"); } } return DEFAULT_PORT; } private static int validatePortNumber(int portNumber) { if (portNumber < 1 || portNumber > 65535) { throw new InvalidPortException(portNumber); } return portNumber; } private static void failWithMessage(String s) { System.err.println(s); printUsage(); System.exit(1); } @VisibleForTesting CmdType executeCommandLine(CommandLine cmd) throws Exception { String[] arguments = cmd.getArgs(); String cmdName = arguments[0]; CmdType cmdType = CmdType.lookup(cmdName); if (cmdType == null) { throw new UnrecognizedCommandException(cmdName); } if (!cmdType.hasCorrectArguments(arguments.length)) { throw new InvalidArgumentNumberException(cmdType, arguments.length); } executeCommand(arguments, cmdType); return cmdType; } private void executeCommand(String[] arguments, CmdType cmdType) throws Exception { switch (cmdType) { case ADDUSER: probe.addUser(arguments[1], arguments[2]); break; case REMOVEUSER: probe.removeUser(arguments[1]); break; case LISTUSERS: print(probe.listUsers(), System.out); break; case ADDDOMAIN: probe.addDomain(arguments[1]); break; case REMOVEDOMAIN: probe.removeDomain(arguments[1]); break; case CONTAINSDOMAIN: if (probe.containsDomain(arguments[1])) { System.out.println(arguments[1] + " exists"); } else { System.out.println(arguments[1] + " does not exists"); } break; case LISTDOMAINS: print(probe.listDomains(), System.out); break; case LISTMAPPINGS: print(probe.listMappings(), System.out); break; case LISTUSERDOMAINMAPPINGS: Mappings userDomainMappings = probe.listUserDomainMappings(arguments[1], arguments[2]); print(userDomainMappings.asStrings(), System.out); break; case ADDADDRESSMAPPING: probe.addAddressMapping(arguments[1], arguments[2], arguments[3]); break; case REMOVEADDRESSMAPPING: probe.removeAddressMapping(arguments[1], arguments[2], arguments[3]); break; case ADDREGEXMAPPING: probe.addRegexMapping(arguments[1], arguments[2], arguments[3]); break; case REMOVEREGEXMAPPING: probe.removeRegexMapping(arguments[1], arguments[2], arguments[3]); break; case SETPASSWORD: probe.setPassword(arguments[1], arguments[2]); break; case COPYMAILBOX: probe.copyMailbox(arguments[1], arguments[2]); break; case DELETEUSERMAILBOXES: probe.deleteUserMailboxesNames(arguments[1]); break; case CREATEMAILBOX: probe.createMailbox(arguments[1], arguments[2], arguments[3]); break; case LISTUSERMAILBOXES: Collection<String> mailboxes = probe.listUserMailboxes(arguments[1]); print(mailboxes.toArray(new String[0]), System.out); break; case DELETEMAILBOX: probe.deleteMailbox(arguments[1], arguments[2], arguments[3]); break; case GETSTORAGEQUOTA: printStorageQuota(arguments[1], probe.getStorageQuota(arguments[1])); break; case GETMESSAGECOUNTQUOTA: printMessageQuota(arguments[1], probe.getMessageCountQuota(arguments[1])); break; case GETQUOTAROOT: System.out.println("Quota Root : " + probe.getQuotaRoot(arguments[1], arguments[2], arguments[3])); break; case GETMAXSTORAGEQUOTA: System.out.println("Storage space allowed for Quota Root " + arguments[1] + " : " + formatStorageValue(probe.getMaxStorage(arguments[1]))); break; case GETMAXMESSAGECOUNTQUOTA: System.out.println("MailboxMessage count allowed for Quota Root " + arguments[1] + " : " + formatMessageValue(probe.getMaxMessageCount(arguments[1]))); break; case SETMAXSTORAGEQUOTA: probe.setMaxStorage(arguments[1], ValueWithUnit.parse(arguments[2]).getConvertedValue()); break; case SETMAXMESSAGECOUNTQUOTA: probe.setMaxMessageCount(arguments[1], Long.parseLong(arguments[2])); break; case SETDEFAULTMAXSTORAGEQUOTA: probe.setDefaultMaxStorage(ValueWithUnit.parse(arguments[1]).getConvertedValue()); break; case SETDEFAULTMAXMESSAGECOUNTQUOTA: probe.setDefaultMaxMessageCount(Long.parseLong(arguments[1])); break; case GETDEFAULTMAXSTORAGEQUOTA: System.out .println("Default Maximum Storage Quota : " + formatStorageValue(probe.getDefaultMaxStorage())); break; case GETDEFAULTMAXMESSAGECOUNTQUOTA: System.out.println("Default Maximum message count Quota : " + formatMessageValue(probe.getDefaultMaxMessageCount())); break; case REINDEXMAILBOX: probe.reIndexMailbox(arguments[1], arguments[2], arguments[3]); break; case REINDEXALL: probe.reIndexAll(); break; case SETSIEVEQUOTA: probe.setSieveQuota(ValueWithUnit.parse(arguments[1]).getConvertedValue()); break; case SETSIEVEUSERQUOTA: probe.setSieveQuota(arguments[1], ValueWithUnit.parse(arguments[2]).getConvertedValue()); break; case GETSIEVEQUOTA: System.out.println("Storage space allowed for Sieve scripts by default : " + formatStorageValue(probe.getSieveQuota())); break; case GETSIEVEUSERQUOTA: System.out.println("Storage space allowed for " + arguments[1] + " Sieve scripts : " + formatStorageValue(probe.getSieveQuota(arguments[1]))); break; case REMOVESIEVEQUOTA: probe.removeSieveQuota(); break; case REMOVESIEVEUSERQUOTA: probe.removeSieveQuota(arguments[1]); break; default: throw new UnrecognizedCommandException(cmdType.getCommand()); } } private static void print(String[] data, PrintStream out) { print(Arrays.asList(data), out); } private static void print(Iterable<String> data, PrintStream out) { if (data != null) { for (String u : data) { out.println(u); } out.println(Joiner.on('\n').join(data)); } } private void printStorageQuota(String quotaRootString, SerializableQuota quota) { System.out.println(String.format("Storage quota for %s is : %s / %s", quotaRootString, formatStorageValue(quota.getUsed()), formatStorageValue(quota.getMax()))); } private void printMessageQuota(String quotaRootString, SerializableQuota quota) { System.out.println(String.format("MailboxMessage count quota for %s is : %s / %s", quotaRootString, formatMessageValue(quota.getUsed()), formatMessageValue(quota.getMax()))); } private String formatStorageValue(long value) { if (value == Quota.UNKNOWN) { return ValueWithUnit.UNKNOWN; } if (value == Quota.UNLIMITED) { return ValueWithUnit.UNLIMITED; } return FileUtils.byteCountToDisplaySize(value); } private String formatMessageValue(long value) { if (value == Quota.UNKNOWN) { return ValueWithUnit.UNKNOWN; } if (value == Quota.UNLIMITED) { return ValueWithUnit.UNLIMITED; } return String.valueOf(value); } private void print(Map<String, Mappings> map, PrintStream out) { if (map != null) { for (Entry<String, Mappings> entry : map.entrySet()) { out.println(entry.getKey() + '=' + entry.getValue().serialize()); } out.println(); } } private static void printUsage() { StringBuilder footerBuilder = new StringBuilder(); for (CmdType cmdType : CmdType.values()) { footerBuilder.append(cmdType.getUsage()).append("\n"); } new HelpFormatter().printHelp(String.format("java %s --host <arg> <command>%n", ServerCmd.class.getName()), "", createOptions(), footerBuilder.toString()); } }