1 package org.sourceforge.jemm.server; 2 3 import java.io.File; 4 5 import org.apache.commons.cli.CommandLine; 6 import org.apache.commons.cli.Options; 7 import org.apache.commons.cli.ParseException; 8 9 public class ServerOptions { 10 public static final int DEFAULT_CLIENT_PORT = 5001; 11 public static final int DEFAULT_CONTROL_PORT = 5002; 12 13 private final ServerAction action; 14 private final int controlPort; 15 private final int port; 16 private final ServerMode mode; 17 private final File dataDir; 18 19 public ServerOptions(CommandLine cmd) throws ParseException { 20 21 if(!cmd.hasOption('a')) 22 throw new ParseException("'action' must be defined"); 23 24 action = ServerAction.parseServerAction(cmd.getOptionValue('a')); 25 26 if(cmd.hasOption('c')) 27 controlPort = parsePortNumber("controlport",cmd.getOptionValue('c')); 28 else 29 controlPort = DEFAULT_CONTROL_PORT; 30 31 if(cmd.hasOption('p')) 32 port = parsePortNumber("port",cmd.getOptionValue('p')); 33 else 34 port = DEFAULT_CLIENT_PORT; 35 36 if(controlPort == port) 37 throw new ParseException("Client port and control port must be different."); 38 39 if(cmd.hasOption('m')) 40 mode = ServerMode.parseServerMode(cmd.getOptionValue('m')); 41 else 42 mode = ServerMode.DEFAULT; 43 44 if(mode == ServerMode.PERSISTENT) { 45 if(action == ServerAction.STOP) 46 dataDir = null; 47 else if(!cmd.hasOption('d')) 48 throw new ParseException("For persistent server data directory must be specified"); 49 else { 50 dataDir = new File(cmd.getOptionValue('d')); 51 if(!fileDirExistsAndIsWritable(dataDir)) 52 throw new ParseException("given datadir '" + dataDir + "' is not a directory or is not writeable"); 53 } 54 } else { 55 if(cmd.hasOption('d')) 56 throw new ParseException("DataDir not allowed for memory based servers"); 57 dataDir = null; 58 } 59 } 60 61 protected boolean fileDirExistsAndIsWritable(File file) { 62 return file.exists() && file.isDirectory() && file.canRead() && file.canWrite(); 63 } 64 65 private int parsePortNumber(String optionName,String optionValue) throws ParseException { 66 try { 67 int value = Integer.parseInt(optionValue); 68 if(value < 1) 69 throw new ParseException(optionName + " must not be < 1"); 70 return value; 71 } catch(NumberFormatException nfe) { 72 throw new ParseException("value for " + optionName + " not an integer"); 73 } 74 } 75 76 public static Options generateOptions() { 77 Options options = new Options(); 78 options.addOption("h","help", false, "Print help information and exit"); 79 options.addOption("a","action", true, "The process action to take start|stop"); 80 options.addOption("m","mode",true,"Mode to run in persistent|memory (default persistent)"); 81 options.addOption("p","port", true, "The port that the server listens for client connections on" 82 + " (default " + DEFAULT_CLIENT_PORT + ")"); 83 options.addOption("c","controlport", true, "The port that the server listens for control commands" 84 + " on (default " + DEFAULT_CONTROL_PORT + ")"); 85 86 options.addOption("d","datadir", true, "The persistent data directory (required when mode=persistent)" 87 + " on (default " + DEFAULT_CONTROL_PORT + ")"); 88 89 return options; 90 } 91 92 public ServerAction getAction() { 93 return action; 94 } 95 96 public int getControlPort() { 97 return controlPort; 98 } 99 100 public int getPort() { 101 return port; 102 } 103 104 public ServerMode getMode() { 105 return mode; 106 } 107 108 public File getDataDir() { 109 return dataDir; 110 } 111 112 @Override public String toString() { 113 StringBuilder sb = new StringBuilder(); 114 115 sb.append("mode=").append(getMode()).append('\n'); 116 if(mode == ServerMode.PERSISTENT) 117 sb.append("dataDir=").append(getDataDir()).append('\n'); 118 sb.append("port=" + getPort()).append('\n'); 119 sb.append("controlPort=" + getControlPort()); 120 return sb.toString(); 121 } 122 }