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 }