1 package fr.in2p3.jsaga.command;
2
3 import org.apache.commons.cli.*;
4
5 import java.io.ByteArrayOutputStream;
6 import java.io.PrintWriter;
7 import java.util.ArrayList;
8 import java.util.List;
9
10
11
12
13
14
15
16
17
18
19
20
21
22 public abstract class AbstractCommand {
23 private String m_appName;
24 private Options m_options;
25 private String[] m_nonOptionNames;
26 private String[] m_standaloneOptionNames;
27 private Parser m_parser;
28 protected String[] m_nonOptionValues;
29
30 protected abstract Options createOptions();
31
32
33
34
35
36
37
38 protected AbstractCommand(String appName, String[] nonOptionNames, String[] standaloneOptionNames, Parser parser) {
39 m_appName = appName;
40 m_options = this.createOptions();
41 m_nonOptionNames = nonOptionNames;
42 m_standaloneOptionNames = standaloneOptionNames;
43 m_parser = (parser!=null ? parser : new PosixParser());
44 m_nonOptionValues = null;
45 }
46
47 protected AbstractCommand(String appName, String[] nonOptionNames, String[] standaloneOptionNames) {
48 this(appName, nonOptionNames, standaloneOptionNames, null);
49 }
50
51 protected AbstractCommand(String appName) {
52 this(appName, null, null, null);
53 }
54
55 protected CommandLine parse(String[] args) {
56
57 List list = new ArrayList();
58 for (int i=0; args!=null && i<args.length; i++) {
59 String[] array;
60 if (args[i]!=null && args[i].startsWith("-D") && (array=args[i].split("=")).length<=2) {
61 String name = array[0].substring(2);
62 String value = array.length==2 ? array[1] : "";
63 System.setProperty(name, value);
64 } else {
65 list.add(args[i]);
66 }
67 }
68 String[] newArgs = (args!=null && list.size()!=args.length
69 ? (String[]) list.toArray(new String[list.size()])
70 : args);
71
72
73 try {
74 boolean stopAtNonOption = (m_nonOptionNames==null || m_nonOptionNames.length==0);
75 CommandLine line = m_parser.parse(m_options, newArgs, stopAtNonOption);
76 m_nonOptionValues = line.getArgs();
77 if (m_nonOptionNames!=null && m_nonOptionValues.length>m_nonOptionNames.length) {
78 throw new UnrecognizedOptionException("Unexpected option: "+ m_nonOptionValues[m_nonOptionNames.length]);
79 } else if (m_standaloneOptionNames!=null && m_nonOptionValues.length<m_nonOptionNames.length && !this.hasStandaloneOption(line)) {
80 throw new MissingOptionException("Missing option: "+m_nonOptionNames[m_nonOptionValues.length]);
81 } else {
82 return line;
83 }
84 } catch(ParseException e) {
85 printHelpAndExit(e.getMessage());
86 return null;
87 }
88 }
89 private boolean hasStandaloneOption(CommandLine line) {
90 for (int i=0; m_standaloneOptionNames!=null && i<m_standaloneOptionNames.length; i++) {
91 if (line.hasOption(m_standaloneOptionNames[i])) {
92 return true;
93 }
94 }
95 return false;
96 }
97
98 protected void printHelpAndExit(String errorMessage) {
99 if (errorMessage != null) {
100 System.err.println(errorMessage);
101 System.err.println();
102 this.printHelp();
103 System.exit(1);
104 } else {
105 this.printHelp();
106 System.exit(0);
107 }
108 }
109 private void printHelp() {
110 HelpFormatter help = new HelpFormatter();
111
112
113 ByteArrayOutputStream usage = new ByteArrayOutputStream();
114 PrintWriter writer = new PrintWriter(usage);
115 help.printUsage(
116 writer,
117 HelpFormatter.DEFAULT_WIDTH,
118 m_appName,
119 m_options);
120 writer.flush();
121
122
123 writer = new PrintWriter(System.out);
124 writer.write(usage.toString(), 0, usage.size()-2);
125 printNonOptionNames(writer, 0);
126 writer.println();
127 writer.println();
128 writer.println("where:");
129 help.printOptions(
130 writer,
131 HelpFormatter.DEFAULT_WIDTH,
132 m_options,
133 HelpFormatter.DEFAULT_LEFT_PAD,
134 HelpFormatter.DEFAULT_DESC_PAD);
135 writer.flush();
136 }
137 private void printNonOptionNames(PrintWriter writer, int current) {
138 if (m_nonOptionNames!=null && current<m_nonOptionNames.length) {
139 if (m_standaloneOptionNames != null) {
140 writer.print(" <"+m_nonOptionNames[current]+">");
141 } else {
142 writer.print(" [<"+m_nonOptionNames[current]+">");
143 printNonOptionNames(writer, current+1);
144 writer.print("]");
145 }
146 }
147 }
148 }