001package runwar.options;
002
003import java.io.File;
004import java.util.Comparator;
005
006//import static java.io.File.*;
007//import static java.util.Arrays.*;
008//
009//import joptsimple.OptionParser;
010//import joptsimple.OptionSet;
011
012import org.apache.commons.cli.CommandLine;
013import org.apache.commons.cli.HelpFormatter;
014import org.apache.commons.cli.Option;
015import org.apache.commons.cli.OptionBuilder;
016import org.apache.commons.cli.Options;
017import org.apache.commons.cli.PosixParser;
018
019import runwar.Server;
020import runwar.logging.Logger;
021
022public class CommandLineHandler {
023    private static final Options options = new Options();
024    private static PosixParser parser;
025    private static final String SYNTAX = " java -jar runwar.jar [-war] path/to/war [options]";
026    private static final String HEADER = " The runwar lib wraps undertow with more awwsome. Defaults (parenthetical)";
027    private static final String FOOTER = " source: https://github.com/cfmlprojects/runwar.git";
028    private static Logger log = Logger.getLogger("CommandLineHandler");
029    
030    public CommandLineHandler(){
031    }
032
033    public static ServerOptions parseArguments(String[] args) {
034        ServerOptions serverOptions = new ServerOptions();
035        serverOptions = parseArguments(args, serverOptions);
036        return serverOptions;
037    }
038
039    @SuppressWarnings("static-access")
040    public static ServerOptions parseArguments(String[] args, ServerOptions serverOptions) {
041//        parser = new OptionParser();
042//        parser.acceptsAll(asList("c","config")).withRequiredArg()
043//        .describedAs( "config file" )
044//        .ofType( File.class );
045
046        parser = new PosixParser();
047        options.addOption( OptionBuilder
048                .withLongOpt( "config" )
049                .withDescription( "config file" )
050                .hasArg().withArgName("file")
051                .create("c") );
052        
053        options.addOption( OptionBuilder
054                .withDescription( "path to war" )
055                .hasArg()
056                .withArgName("path")
057                .create("war") );
058        
059        options.addOption( OptionBuilder
060                .withLongOpt( "server-name" )
061                .withDescription( "server name (default)" )
062                .hasArg()
063                .withArgName("name")
064                .create("name") );
065        
066        options.addOption( OptionBuilder
067                .withLongOpt( "context-path" )
068                .withDescription( "context path.  (/)" )
069                .hasArg().withArgName("context")
070                .create("context") );
071        
072        options.addOption( OptionBuilder
073                .withDescription( "host.  (127.0.0.1)" )
074                .hasArg().withArgName("host")
075                .create("host") );
076        
077        options.addOption( OptionBuilder
078                .withLongOpt( "port" )
079                .withDescription( "port number.  (8088)" )
080                .hasArg().withArgName("http port").withType(Number.class)
081                .create('p') );
082        
083        options.addOption( OptionBuilder
084                .withLongOpt( "stop-port" )
085                .withDescription( "stop listener port number. (8779)\n" )
086                .hasArg().withArgName("port").withType(Number.class)
087                .create("stopsocket") );
088        
089        options.addOption( OptionBuilder
090                        .withLongOpt( "stop-password" )
091                        .withDescription( "Pasword checked when stopping server\n" )
092                        .hasArg().withArgName("password")
093                        .create("password") );
094        
095        options.addOption( OptionBuilder
096                .withDescription( "stop backgrounded.  Optional stop-port" )
097                .hasOptionalArg().withArgName("port")
098                .hasOptionalArg().withArgName("password")
099                .withValueSeparator(' ')
100                .create("stop") );
101        
102        options.addOption( OptionBuilder
103                        .withLongOpt( "http-enable" )
104                        .withDescription( "Enable HTTP.  Default is true ,unless SSL or AJP are enabled." )
105                        .hasArg().withArgName("true|false").withType(Boolean.class)
106                        .create("httpenable") );
107        
108        options.addOption( OptionBuilder
109                .withLongOpt( "ajp-enable" )
110                .withDescription( "Enable AJP.  Default is false.  When enabled, http is disabled by default." )
111                .hasArg().withArgName("true|false").withType(Boolean.class)
112                .create("ajpenable") );
113        
114        options.addOption( OptionBuilder
115                .withLongOpt( "urlrewrite-enable" )
116                .withDescription( "Enable URL Rewriting.  Default is true." )
117                .hasArg().withArgName("true|false").withType(Boolean.class)
118                .create("urlrewriteenable") );
119
120        options.addOption( OptionBuilder
121                .withLongOpt( "urlrewrite-file" )
122                .withDescription( "URL rewriting config file." )
123                .hasArg().withArgName("path/to/urlrewrite/file")
124                .create("urlrewritefile") );
125
126        options.addOption( OptionBuilder
127                        .withLongOpt( "ssl-enable" )
128                        .withDescription( "Enable SSL.  Default is false.  When enabled, http is disabled by default." )
129                        .hasArg().withArgName("true|false").withType(Boolean.class)
130                        .create("sslenable") );
131        
132        options.addOption( OptionBuilder
133                        .withLongOpt( "ssl-port" )
134                        .withDescription( "SSL port.  Disabled if not set." )
135                        .hasArg().withArgName("port").withType(Number.class)
136                        .create("sslport") );
137        
138        options.addOption( OptionBuilder
139                        .withLongOpt( "ssl-cert" )
140                        .withDescription( "SSL certificate file in x509 (PKS#12) format." )
141                        .hasArg().withArgName("certificate")
142                        .create("sslcert") );
143        
144        options.addOption( OptionBuilder
145                        .withLongOpt( "ssl-key" )
146                        .withDescription( "SSL private key file in DER (PKS#8) format." )
147                        .hasArg().withArgName("key")
148                        .create("sslkey") );
149        
150        options.addOption( OptionBuilder
151                        .withLongOpt( "ssl-keypass" )
152                        .withDescription( "SSL key passphrase." )
153                        .hasArg().withArgName("passphrase")
154                        .create("sslkeypass") );
155        
156        options.addOption( OptionBuilder
157                .withLongOpt( "ajp-port" )
158                .withDescription( "AJP port.  Disabled if not set." )
159                .hasArg().withArgName("ajp port").withType(Number.class)
160                .create("ajpport") );
161        
162        options.addOption( OptionBuilder
163                .withLongOpt( "log-dir" )
164                .withDescription( "Log directory.  (WEB-INF/logs)" )
165                .hasArg().withArgName("path/to/log/dir")
166                .create("logdir") );
167
168        options.addOption( OptionBuilder
169                .withLongOpt( "request-log" )
170                .withDescription( "Log requests to specified file" )
171                .hasArg().withArgName("/path/to/log")
172                .create("requestlog") );
173
174        options.addOption( OptionBuilder
175                .withLongOpt( "dirs" )
176                .withDescription( "List of external directories to serve from" )
177                .hasArg().withArgName("path,path,...")
178                .create("d") );
179        
180        options.addOption( OptionBuilder
181                .withLongOpt( "lib-dirs" )
182                .withDescription( "List of directories to add contents of to classloader" )
183                .hasArg().withArgName("path,path,...")
184                .create("libdirs") );
185        
186        options.addOption( OptionBuilder
187                .withLongOpt( "jar" )
188                .withDescription( "jar to be added to classpath" )
189                .hasArg().withArgName("path")
190                .create("j") );
191        
192        options.addOption( OptionBuilder
193                .withLongOpt( "background" )
194                .withDescription( "Run in background (true)" )
195                .hasArg().withArgName("true|false").withType(Boolean.class)
196                .create('b') );
197        
198        options.addOption( OptionBuilder
199                .withLongOpt( "open-browser" )
200                .withDescription( "Open default web browser after start (false)" )
201                .hasArg().withArgName("true|false")
202                .create("open") );
203
204        options.addOption( OptionBuilder
205                .withLongOpt( "open-url" )
206                .withDescription( "URL to open browser to. (http://$host:$port)\n" )
207                .hasArg().withArgName("url")
208                .create("url") );
209        
210        options.addOption( OptionBuilder
211                .withLongOpt( "pid-file" )
212                .withDescription( "Process ID file." )
213                .hasArg().withArgName("pidfile")
214                .create("pidfile") );
215
216        options.addOption( OptionBuilder
217                .withLongOpt( "timeout" )
218                .withDescription( "Startup timout for background process. (50)\n" )
219                .hasArg().withArgName("seconds").withType(Number.class)
220                .create("t") );
221
222        options.addOption( OptionBuilder
223                .withLongOpt( "log-level" )
224                .withDescription( "log level [DEBUG|INFO|WARN|ERROR] (WARN)" )
225                .hasArg().withArgName("level")
226                .create("level") );
227
228        options.addOption( OptionBuilder
229                .withLongOpt( "debug-enable" )
230                .withDescription( "set log level to debug" )
231                .hasArg().withArgName("true|false").withType(Boolean.class)
232                .create("debug") );
233        
234        options.addOption( OptionBuilder
235                .withLongOpt( "processname" )
236                .withDescription( "Process name where applicable" )
237                .hasArg().withArgName("name")
238                .create("procname") );
239
240        options.addOption( OptionBuilder
241                .withLongOpt( "tray-icon" )
242                .withDescription( "tray icon and OS X dock icon png image" )
243                .hasArg().withArgName("path")
244                .create("icon") );
245
246        options.addOption( OptionBuilder
247                .withLongOpt( "tray-config" )
248                .withDescription( "tray menu config path" )
249                .hasArg().withArgName("path")
250                .create("trayconfig") );
251        
252        options.addOption( OptionBuilder
253                .withLongOpt( "status-file" )
254                .withDescription( "status file (started/stopped) path" )
255                .hasArg().withArgName("path")
256                .create("statusfile") );
257        
258        options.addOption( OptionBuilder
259                .withLongOpt( "web-xml-path" )
260                .withDescription( "full path to default web.xml file for configuring the server" )
261                .hasArg().withArgName("path")
262                .create("webxmlpath") );
263        
264        options.addOption( OptionBuilder
265                .withLongOpt( "cfengine-name" )
266                .withDescription( "name of cfml engine, defaults to lucee" )
267                .hasArg().withArgName("name")
268                .create("cfengine") );
269        
270        options.addOption( OptionBuilder
271                        .withLongOpt( "cfml-web-config" )
272                        .withDescription( "full path to cfml web context config directory" )
273                        .hasArg().withArgName("path")
274                        .create("cfwebconf") );
275        
276        options.addOption( OptionBuilder
277                .withLongOpt( "cfml-server-config" )
278                .withDescription( "full path to cfml server context config directory" )
279                .hasArg().withArgName("path")
280                .create("cfserverconf") );
281        
282        options.addOption( OptionBuilder.withArgName( "property=value" )
283                .withLongOpt( "sysprop" )
284                .hasArgs(2)
285                .withValueSeparator()
286                .withDescription( "system property to set" )
287                .create("D") );
288        
289        options.addOption( OptionBuilder
290                .withLongOpt( "welcome-files" )
291                .withDescription( "comma delinated list of welcome files used if no web.xml file exists" )
292                .hasArg().withArgName("index.cfm,default.cfm,...")
293                .create("welcomefiles") );
294
295        options.addOption( OptionBuilder
296                .withLongOpt( "directory-index" )
297                .withDescription( "enable directory browsing" )
298                .hasArg().withArgName("true|false").withType(Boolean.class)
299                .create("directoryindex") );
300        
301        options.addOption( OptionBuilder
302                        .withLongOpt( "cache-enable" )
303                        .withDescription( "enable static asset cache" )
304                        .hasArg().withArgName("true|false").withType(Boolean.class)
305                        .create("cache") );
306        
307        options.addOption( OptionBuilder
308                        .withLongOpt( "custom-httpstatus-enable" )
309                        .withDescription( "enable custom HTTP status code messages" )
310                        .hasArg().withArgName("true|false").withType(Boolean.class)
311                        .create("customstatus") );
312        
313        options.addOption( OptionBuilder
314                .withLongOpt( "transfer-min-size" )
315                .withDescription( "Minimun transfer file size to offload to OS. (100)\n" )
316                .hasArg().withArgName("transferminsize").withType(Long.class)
317                .create("transferminsize") );
318
319        options.addOption( OptionBuilder
320                .withLongOpt( "sendfile-enable" )
321                .withDescription( "enable sendfile" )
322                .hasArg().withArgName("true|false").withType(Boolean.class)
323                .create("sendfile") );
324        
325        options.addOption( OptionBuilder
326                .withLongOpt( "gzip-enable" )
327                .withDescription( "enable gzip" )
328                .hasArg().withArgName("true|false").withType(Boolean.class)
329                .create("gzip") );
330        
331        options.addOption( OptionBuilder
332                .withLongOpt( "mariadb4j-enable" )
333                .withDescription( "enable MariaDB4j" )
334                .hasArg().withArgName("true|false").withType(Boolean.class)
335                .create("mariadb4j") );
336        
337        options.addOption( OptionBuilder
338                .withLongOpt( "mariadb4j-port" )
339                .withDescription( "enable MariaDB4j" )
340                .hasArg().withArgName("port").withType(Number.class)
341                .create("mariadb4jport") );
342        
343        options.addOption( OptionBuilder
344                .withLongOpt( "mariadb4j-basedir" )
345                .withDescription( "base directory.  (temp/mariadb4j)" )
346                .hasArg().withArgName("path/to/base/dir")
347                .create("mariadb4jbasedir") );
348        
349        options.addOption( OptionBuilder
350                .withLongOpt( "mariadb4j-datadir" )
351                .withDescription( "data directory.  (temp/mariadb4j/data)" )
352                .hasArg().withArgName("path/to/data/dir")
353                .create("mariadb4jdatadir") );
354        
355        options.addOption( OptionBuilder
356                .withLongOpt( "mariadb4j-import" )
357                .withDescription( "SQL file to import." )
358                .hasArg().withArgName("path/to/sql/file")
359                .create("mariadb4jimport") );
360        
361        options.addOption( new Option( "h", "help", false, "print this message" ) );
362        options.addOption( new Option( "v", "version", false, "print runwar version and undertow version" ) );
363
364
365        try {
366            CommandLine line = parser.parse( options, args );
367            // parse the command line arguments
368            if (line.hasOption("help")) {
369                printUsage("Options",0);
370            }
371            if (line.hasOption("version")) {
372                Server.printVersion();
373                System.exit(0);
374            }
375            if (line.hasOption("c")) {
376                String config = line.getOptionValue("c");
377                log.debug("Loading config from file: " + getFile(config));
378                serverOptions = new ConfigParser(getFile(config)).getServerOptions();
379            }
380            
381            if (line.hasOption("name")) {
382                serverOptions.setServerName(line.getOptionValue("name"));
383            }
384
385            if (line.hasOption("debug")) {
386                Boolean debug= Boolean.valueOf(line.getOptionValue("debug"));
387                serverOptions.setDebug(debug);
388                if(debug)serverOptions.setLoglevel("DEBUG");
389            }
390
391            if (line.hasOption("level") && line.getOptionValue("level").length() > 0) {
392                serverOptions.setLoglevel(line.getOptionValue("level"));
393            }
394            
395            if (line.hasOption("background")) {
396                serverOptions.setBackground(Boolean.valueOf(line.getOptionValue("background")));
397            }
398            if (line.hasOption("libdirs") && line.getOptionValue("libdirs").length() > 0) {
399                String[] list = line.getOptionValue("libdirs").split(",");
400                for (String path : list) {
401                    File lib = new File(path);
402                    if (!lib.exists() || !lib.isDirectory())
403                        printUsage("No such lib directory "+path,1);
404                }               
405                serverOptions.setLibDirs(line.getOptionValue("libdirs"));
406            }
407            if (line.hasOption("welcomefiles") && line.getOptionValue("welcomefiles").length() > 0) {
408                serverOptions.setWelcomeFiles(line.getOptionValue("welcomefiles").split(","));
409            }
410
411            if (line.hasOption("jar")) {
412                 File jar = new File(line.getOptionValue("jar"));
413                    if (!jar.exists() || jar.isDirectory())
414                        printUsage("No such jar "+jar,1);
415                    serverOptions.setJarURL(jar.toURI().toURL());
416            }
417            
418            if (line.hasOption("timeout")) {
419                serverOptions.setLaunchTimeout(((Number)line.getParsedOptionValue("timeout")).intValue() * 1000);
420            }
421            if (line.hasOption("password")) {
422                serverOptions.setStopPassword(line.getOptionValue("password").toCharArray());
423            }
424            if (line.hasOption("stopsocket")) {
425                serverOptions.setSocketNumber(((Number)line.getParsedOptionValue("stopsocket")).intValue());
426            }
427            if (line.hasOption("war")) {
428                String warPath = line.getOptionValue("war");
429                serverOptions.setWarFile(getFile(warPath));
430            } else if (!line.hasOption("stop") && !line.hasOption("c")) {
431                printUsage("Must specify -war path/to/war, or -stop [-stop-socket]",1);
432            } 
433            if(line.hasOption("D")){
434                final String[] properties = line.getOptionValues("D");
435                for (int i = 0; i < properties.length; i++) {
436                    log.debugf("setting system property: %s", properties[i].toString()+'='+properties[i+1].toString());
437                    System.setProperty(properties[i].toString(),properties[i+1].toString());
438                    i++;
439                }
440            }
441
442            if (line.hasOption("webxmlpath")) {
443                String webXmlPath = line.getOptionValue("webxmlpath");
444                File webXmlFile = new File(webXmlPath);
445                if(webXmlFile.exists()) {
446                    serverOptions.setWebXmlFile(webXmlFile);
447                } else {
448                    throw new RuntimeException("Could not find web.xml! " + webXmlPath);
449                }
450            }
451
452            if (line.hasOption("stop")) {
453                serverOptions.setAction("stop");
454                String[] values = line.getOptionValues("stop");
455                if(values != null && values.length > 0) {
456                    serverOptions.setSocketNumber(Integer.parseInt(values[0])); 
457                }
458                if(values != null && values.length >= 1) {
459                        serverOptions.setStopPassword(values[1].toCharArray()); 
460                }
461            } else {
462                serverOptions.setAction("start");
463            }
464
465            if (line.hasOption("context")) {
466                serverOptions.setContextPath(line.getOptionValue("context"));
467            }
468            if (line.hasOption("host")) {
469                serverOptions.setHost(line.getOptionValue("host"));
470            }
471            if (line.hasOption("p")) {
472                serverOptions.setPortNumber(((Number)line.getParsedOptionValue("p")).intValue());
473            }
474            if (line.hasOption("enableajp")) {
475                serverOptions.setEnableAJP(Boolean.valueOf(line.getOptionValue("enableajp")));
476            }
477            if (line.hasOption("ajpport")) {
478                // disable http if no http port is specified
479                serverOptions.setEnableHTTP(line.hasOption("port"))
480                .setEnableAJP(true).setAJPPort(((Number)line.getParsedOptionValue("ajpport")).intValue());
481            }
482            if (line.hasOption("sslport")) {
483                if(!line.hasOption("httpenable")) {
484                    serverOptions.setEnableHTTP(false);
485                }
486                serverOptions.setEnableSSL(true).setSSLPort(((Number)line.getParsedOptionValue("sslport")).intValue());
487            }
488            if (line.hasOption("sslcert")) {
489                serverOptions.setSSLCertificate(getFile(line.getOptionValue("sslcert")));
490                if (!line.hasOption("sslkey") || !line.hasOption("sslkey")) {
491                    throw new RuntimeException("Using a SSL certificate requires -sslkey /path/to/file and -sslkeypass pass**** arguments!");   
492                }
493            }
494            if (line.hasOption("sslkey")) {
495                serverOptions.setSSLKey(getFile(line.getOptionValue("sslkey")));
496            }
497            if (line.hasOption("sslkeypass")) {
498                serverOptions.setSSLKeyPass(line.getOptionValue("sslkeypass").toCharArray());
499            }
500            if (line.hasOption("sslenable")) {
501                if(!line.hasOption("httpenable")) {
502                    serverOptions.setEnableHTTP(false);
503                }
504                serverOptions.setEnableSSL(Boolean.valueOf(line.getOptionValue("sslenable")));
505            }
506            if (line.hasOption("httpenable")) {
507                serverOptions.setEnableHTTP(Boolean.valueOf(line.getOptionValue("httpenable")));
508            }
509            if (line.hasOption("urlrewritefile")) {
510                serverOptions.setURLRewriteFile(getFile(line.getOptionValue("urlrewritefile")));
511                if(!line.hasOption("urlrewriteenable")) {
512                    serverOptions.setEnableURLRewrite(true);
513                }
514            }
515            if (line.hasOption("urlrewriteenable")) {
516                serverOptions.setEnableURLRewrite(Boolean.valueOf(line.getOptionValue("urlrewriteenable")));
517            }
518            if (line.hasOption("logdir")) {
519                serverOptions.setLogDir(line.getOptionValue("logdir"));
520            } else {
521                if(serverOptions.getWarFile() != null){
522                        File warFile = serverOptions.getWarFile();
523                        String logDir;
524                        if(warFile.isDirectory() && new File(warFile,"WEB-INF").exists()) {
525                                logDir = warFile.getPath() + "/WEB-INF/logs/";
526                        } else {
527                                String serverConfigDir = System.getProperty("cfml.server.config.dir");
528                                if(serverConfigDir == null) {
529                                        logDir = new File(Server.getThisJarLocation().getParentFile(),"engine/cfml/server/log/").getAbsolutePath();
530                                } else {
531                                        logDir = new File(serverConfigDir,"log/").getAbsolutePath();                        
532                                }
533                        }
534                        serverOptions.setLogDir(logDir);
535                }
536            }
537            if(serverOptions.getWarFile() != null){
538                serverOptions.setCfmlDirs(serverOptions.getWarFile().getAbsolutePath());
539            }
540            if (line.hasOption("dirs")) {
541                serverOptions.setCfmlDirs(line.getOptionValue("dirs"));
542            }
543            if (line.hasOption("requestlog")) {
544                serverOptions.setKeepRequestLog(Boolean.valueOf(line.getOptionValue("requestlog")));
545            }
546            
547            if (line.hasOption("open-browser")) {
548                serverOptions.setOpenbrowser(Boolean.valueOf(line.getOptionValue("open")));
549            }
550            if (line.hasOption("open-url")) {
551                serverOptions.setOpenbrowserURL(line.getOptionValue("open-url"));
552            }
553
554            if (line.hasOption("pidfile")) {
555                serverOptions.setPidFile(line.getOptionValue("pidfile"));
556            }
557
558            if (line.hasOption("processname")) {
559                serverOptions.setProcessName(line.getOptionValue("processname"));
560            }
561
562            if (line.hasOption("icon")) {
563                serverOptions.setIconImage(line.getOptionValue("icon"));
564            }
565
566            if (line.hasOption("trayconfig") && line.getOptionValue("trayconfig").length() > 0) {
567                serverOptions.setTrayConfig(getFile(line.getOptionValue("trayconfig")));
568            }
569            
570            if (line.hasOption("statusfile") && line.getOptionValue("statusfile").length() > 0) {
571                serverOptions.setStatusFile(getFile(line.getOptionValue("statusfile")));
572            }
573            
574            if (line.hasOption("cfengine")) {
575                serverOptions.setCFEngineName(line.getOptionValue("cfengine"));
576            }
577            if (line.hasOption("cfserverconf")) {
578                serverOptions.setCFMLServletConfigServerDir(line.getOptionValue("cfserverconf"));
579            }
580            if (line.hasOption("cfwebconf")) {
581                serverOptions.setCFMLServletConfigWebDir(line.getOptionValue("cfwebconf"));
582            }
583            if (line.hasOption("directoryindex")) {
584                serverOptions.setDirectoryListingEnabled(Boolean.valueOf(line.getOptionValue("directoryindex")));
585            }
586            if (line.hasOption("cache")) {
587                serverOptions.setCacheEnabled(Boolean.valueOf(line.getOptionValue("cache")));
588            }
589            if (line.hasOption("customstatus")) {
590                serverOptions.setCustomHTTPStatusEnabled(Boolean.valueOf(line.getOptionValue("customstatus")));
591            }
592            if (line.hasOption("transferminsize")) {
593                serverOptions.setTransferMinSize(Long.valueOf(line.getOptionValue("transferminsize")));
594            }
595            if (line.hasOption("sendfile")) {
596                serverOptions.setSendfileEnabled(Boolean.valueOf(line.getOptionValue("sendfile")));
597            }
598            if (line.hasOption("gzip")) {
599                serverOptions.setGzipEnabled(Boolean.valueOf(line.getOptionValue("gzip")));
600            }
601            if (line.hasOption("mariadb4j")) {
602                serverOptions.setMariaDB4jEnabled(Boolean.valueOf(line.getOptionValue("mariadb4j")));
603            }
604            if (line.hasOption("mariadb4jport") && line.getOptionValue("mariadb4jport").length() > 0) {
605                serverOptions.setMariaDB4jPort(Integer.valueOf(line.getOptionValue("mariadb4jport")));
606            }
607            if (line.hasOption("mariadb4jbasedir") && line.getOptionValue("mariadb4jbasedir").length() > 0) {
608                serverOptions.setMariaDB4jBaseDir(new File(line.getOptionValue("mariadb4jbasedir")));
609            }
610            if (line.hasOption("mariadb4jdatadir") && line.getOptionValue("mariadb4jdatadir").length() > 0) {
611                serverOptions.setMariaDB4jDataDir(new File(line.getOptionValue("mariadb4jdatadir")));
612            }
613            if (line.hasOption("mariadb4jimport") && line.getOptionValue("mariadb4jimport").length() > 0) {
614                serverOptions.setMariaDB4jImportSQLFile(new File(line.getOptionValue("mariadb4jimport")));
615            }
616            if(serverOptions.getLoglevel().equals("DEBUG")) {
617                for(Option arg: line.getOptions()) {
618                        log.debug(arg);
619                        log.debug(arg.getValue());
620                }
621            }
622            return serverOptions;
623        }
624        catch( Exception exp ) {
625            exp.printStackTrace();
626            String msg = exp.getMessage();
627            if(msg == null){
628                msg = "null : "+exp.getStackTrace()[0].toString();
629                if(exp.getStackTrace().length > 0) {
630                    msg += '\n' + exp.getStackTrace()[1].toString();
631                }
632            } else {
633                msg = exp.getClass().getName() + " " + msg;
634            }
635            printUsage(msg,1);
636        }
637        return null;
638    }    
639    
640    static File getFile(String path) {
641        File file = new File(path);
642        if(!file.exists() || file == null) {
643            throw new RuntimeException("File not found: " + path);
644        }
645        return file;
646    }
647
648    static void printUsage(String message, int exitCode) {
649        HelpFormatter formatter = new HelpFormatter();
650        formatter.setOptionComparator(new Comparator<Option>() {
651            public int compare(Option o1, Option o2) {
652                if(o1.getOpt().equals("war")) {return -1;} else if(o2.getOpt().equals("war")) {return 1;}
653                if(o1.getOpt().equals("p")) {return -1;} else if(o2.getOpt().equals("p")) {return 1;}
654                if(o1.getOpt().equals("c")) { return -1; } else if(o2.getOpt().equals("c")) {return 1;}
655                if(o1.getOpt().equals("context")) { return -1; } else if(o2.getOpt().equals("context")) {return 1;}
656                if(o1.getOpt().equals("d")) { return -1; } else if(o2.getOpt().equals("d")) {return 1;}
657                if(o1.getOpt().equals("b")) { return -1; } else if(o2.getOpt().equals("b")) {return 1;}
658                if(o1.getOpt().equals("h")) {return 1;} else if(o2.getOpt().equals("h")) {return -1;}
659                if(o1.getOpt().equals("url")) {return 1;} else if(o2.getOpt().equals("url")) {return -1;}
660                if(o1.getOpt().equals("open")) {return 1;} else if(o2.getOpt().equals("open")) {return -1;}
661                if(o1.getOpt().equals("stopsocket")) {return 1;} else if(o2.getOpt().equals("stopsocket")) {return -1;}
662                if(o1.getOpt().equals("stop")) {return 1;} else if(o2.getOpt().equals("stop")) {return -1;}
663                return o1.getOpt().compareTo(o2.getOpt());
664            }
665        });
666        formatter.setWidth(80);
667        formatter.setSyntaxPrefix("USAGE:");
668        formatter.setLongOptPrefix("--");
669        //formatter.printHelp( SYNTAX, options,false);
670        if(exitCode == 0) {
671            formatter.printHelp(80, SYNTAX, message + '\n' + HEADER, options, FOOTER, false);
672        } else {
673            System.out.println("USAGE:  " + SYNTAX + '\n' + message);
674        }
675        System.exit(exitCode);
676    }
677
678
679}