View Javadoc

1   /*
2    * Copyright 2007-2008 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.gwe.utils.cmd;
18  
19  import java.io.BufferedReader;
20  import java.io.IOException;
21  import java.io.InputStreamReader;
22  import java.util.ArrayList;
23  import java.util.HashMap;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.gwe.utils.StringUtils;
28  import org.springframework.beans.BeanWrapper;
29  import org.springframework.beans.BeanWrapperImpl;
30  
31  /**
32   * @author Marco Ruiz
33   * @since Jul 13, 2007
34   */
35  public class OptionableAppTemplate {
36  	
37  	public final OptionTemplate OPT_HELP = new OptionTemplate('h', "help", "Help. Displays command usage");
38  	public final OptionTemplate OPT_INTERACT = new OptionTemplate("interactive", "Runs application in interactive mode, requesting the parameters to the user one by one.");
39      
40  	private List<OptionTemplate> templatesInOrder = new ArrayList<OptionTemplate>();
41  	private Map<OptionTemplate, String> options = new HashMap<OptionTemplate, String>();
42      
43      public OptionableAppTemplate() {
44      	options.put(OPT_HELP, null);
45      	options.put(OPT_INTERACT, null);
46  	}
47      
48      public OptionableAppTemplate(OptionTemplate... templates) {
49      	this();
50      	addOptions(templates);
51  	}
52      
53  	public OptionableAppTemplate addOptions(OptionTemplate... options) {
54  		for (OptionTemplate template : options)
55  			addOption(template, template.getDefaultValue());
56  
57  		return this;
58  	}
59  	
60  	public void resetArgs() {
61  		addOptions(templatesInOrder.toArray(new OptionTemplate[]{}));
62  	}
63  	
64  	public OptionTemplate addArg(OptionTemplate template) {
65  		return addOption(template, template.getDefaultValue());
66  	}
67  	
68  	public OptionTemplate addOption(OptionTemplate template, Object value) {
69  		templatesInOrder.remove(template);
70  		templatesInOrder.add(template);
71  		String strVal = (value != null) ? value.toString() : null; 
72  		options.put(template, strVal);
73  		return template;
74  	}
75  	
76  	public void removeOption(OptionTemplate template) {
77  		templatesInOrder.remove(template);
78  		options.remove(template);
79  	}
80  	
81  	public String[] getInvocationArgs() {
82  		List<String> result = new ArrayList<String>();
83  		for (OptionTemplate template : templatesInOrder) {
84  			result.add("-" + String.valueOf(template.getShortFlag()));
85  			result.add(options.get(template));
86  		}
87  		return result.toArray(new String[]{});
88  	}
89      
90  //	public String getInvocationArgsAsStr() { return StringUtils.getArrayAsAsStr(getInvocationArgs()); }
91      
92      public <APP_TYPE> APP_TYPE loadArgs(String[] args, APP_TYPE appObject) {
93      	loadArgs(args);
94      	return populateAppObject(appObject);
95      }
96      
97      public void loadArgs(String[] args) {
98      	resetArgs();
99      	for (OptionTemplate option : options.keySet()) 
100     		options.put(option, option.readOptionValue(args));
101     	
102     	if (getArg(OPT_HELP) != null) {
103     		System.out.println(getUsage());
104     		System.exit(0);
105     	}
106     	
107     	if (getArg(OPT_INTERACT) != null) {
108     		System.out.println("PLEASE ENTER THE PARAMETERS AS THEY ARE REQUESTED.\n" +
109     				"To use a field's default value just leave it blank and press return.\n" +
110     				"======================================================================");
111         	for (OptionTemplate option : templatesInOrder) readOptionFromConsole(option);
112     	}
113     }
114     
115     public String[] getWithoutOptionsArgs(String[] args) {
116     	for (OptionTemplate option : options.keySet()) 
117     		args = option.removeOptionFromArray(args);
118     	return args;
119     }
120     
121     public String getWithoutOptionsArgsAsStr(String[] args) { return StringUtils.getArrayAsStr(getWithoutOptionsArgs(args)); }
122     
123 	private void readOptionFromConsole(OptionTemplate option) {
124 		try {
125 			String value = readNextField(option.getDescription() + "\n" + option.getLongFlag());
126 			if (value == null || "".equals(value)) value = option.getDefaultValue();
127 			options.put(option, value);
128 		} catch (IOException e) {
129 			System.out.print("There was an IO error trying to collect your information. " +
130 					"The application will use the default value of " + option.getDefaultValue() + " for " + option.getLongFlag());
131 		}
132 	}
133     
134 	public String getArg(OptionTemplate key) { return options.get(key); }
135 	
136 	public Integer getArgAsInt(OptionTemplate key) {
137 		try {
138 			return Integer.parseInt(options.get(key));
139 		} catch (Exception e) {
140 			return null;
141 		}
142 	}
143 	
144 	public Long getArgAsLong(OptionTemplate key) {
145 		try {
146 			return Long.parseLong(options.get(key));
147 		} catch (Exception e) {
148 			return null;
149 		}
150 	}
151 	
152 	public <APP_TYPE> APP_TYPE populateAppObject(APP_TYPE appObject) {
153 		BeanWrapper appObjectWrapper = new BeanWrapperImpl(appObject);
154 		for (OptionTemplate template : templatesInOrder) 
155 			template.setObjectProperty(appObjectWrapper, options.get(template));
156 		return appObject;
157 	}
158 	
159     public String getUsage() {
160     	String usage;
161     	usage = "Usage: java " + this.getClass().getName() + " [OPTION]\n\nOptions:\n";
162 
163     	int longFlagSize = 0;
164     	for (OptionTemplate option : templatesInOrder) longFlagSize = Math.max(longFlagSize, option.getLongFlag().length());
165     	for (OptionTemplate option : templatesInOrder) usage += option.toString(longFlagSize);
166     	return usage; 
167     }
168     
169     public String toString() {
170     	return getUsage();
171     }
172     
173     private String readNextField(String fieldName) throws IOException {
174         System.out.print(fieldName + ": ");
175 	    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
176         String line = reader.readLine();
177         if (line == null) return null;
178 		return line;
179     }
180     
181     public OptionableAppTemplate clone() {
182     	OptionableAppTemplate result = new OptionableAppTemplate(templatesInOrder.toArray(new OptionTemplate[]{}));
183    		result.options.putAll(options);
184    		return result;
185     }
186 }
187