001 /*
002 * $Id: ArgumentManager.java,v 1.23 2012/04/30 20:48:16 jbeavers Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2012
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 *
012 * All Rights Reserved
013 *
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.
016 *
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 *
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025 * GNU Lesser Public License for more details.
026 *
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program. If not, see http://www.gnu.org/licenses.
029 */
030
031 package edu.wisc.ssec.mcidasv;
032
033 import java.util.ArrayList;
034 import java.util.Collections;
035 import java.util.List;
036
037 import edu.wisc.ssec.mcidasv.startupmanager.StartupManager;
038
039 import ucar.unidata.idv.ArgsManager;
040 import ucar.unidata.idv.IntegratedDataViewer;
041 import ucar.unidata.util.IOUtil;
042 import ucar.unidata.util.LogUtil;
043 import ucar.unidata.util.PatternFileFilter;
044
045 /**
046 * McIDAS-V needs to handle a few command line flags/options that the IDV does
047 * not. Only the ability to force the Aqua look and feel currently exists.
048 *
049 * @author McIDAS-V Developers
050 */
051 public class ArgumentManager extends ArgsManager {
052
053 /** usage message */
054 public static final String USAGE_MESSAGE =
055 "Usage: runMcV [OPTIONS] <bundle/script files, e.g., .mcv, .mcvz, .py>";
056
057 /**
058 * Given by the "-user" argument. Alternative user path for bundles, resources, etc.
059 */
060 String defaultUserDirectory = StartupManager.INSTANCE.getPlatform().getUserDirectory();
061
062 /**
063 * Just bubblin' on up the inheritance hierarchy.
064 *
065 * @param idv The IDV instance.
066 * @param args The command line arguments that were given.
067 */
068 public ArgumentManager(IntegratedDataViewer idv, String[] args) {
069 super(idv, args);
070 }
071
072 /**
073 * Currently we're only handling the {@code -forceaqua} flag so we can
074 * mitigate some overlay issues we've been seeing on OS X Leopard.
075 *
076 * @param arg The current argument we're examining.
077 * @param args The actual array of arguments.
078 * @param idx The index of {@code arg} within {@code args}.
079 *
080 * @return The idx of the last value in the args array we look at. i.e.,
081 * if the flag arg does not require any further values in the args array
082 * then don't increment idx. If arg requires one more value then
083 * increment idx by one. etc.
084 *
085 * @throws Exception Throw bad things off to something that can handle 'em!
086 */
087 protected int parseArg(String arg, String[] args, int idx)
088 throws Exception {
089
090 if ("-forceaqua".equals(arg)) {
091 // unfortunately we can't simply set the look and feel here. If I
092 // were to do so, the loadLookAndFeel in the IdvUIManager would
093 // eventually get loaded and then set the look and feel to whatever
094 // the preferences dictate.
095 // instead I use the boolean toggle to signal to McV's
096 // UIManager.loadLookAndFeel that it should simply ignore the user's
097 // preference is and load the Aqua L&F from there.
098 McIDASV.useAquaLookAndFeel = true;
099 } else if (ARG_HELP.equals(arg)) {
100 System.err.println(USAGE_MESSAGE);
101 System.err.println(getUsageMessage());
102 ((McIDASV)getIdv()).exit(1);
103 } else if (checkArg(arg, "-script", args, idx, 1) || checkArg(arg, "-pyfile", args, idx, 1)) {
104 scriptingFiles.add(args[idx++]);
105 if (!getIslInteractive()) {
106 setIsOffScreen(true);
107 }
108 } else {
109 if (ARG_ISLINTERACTIVE.equals(arg) || ARG_B64ISL.equals(arg) || ARG_ISLFILE.equals(arg) || isIslFile(arg)) {
110 System.err.println("*** WARNING: ISL is being deprecated!");
111 }
112 return super.parseArg(arg, args, idx);
113 }
114 return idx;
115 }
116
117 /**
118 * Print out the command line usage message and exit
119 *
120 * @param err The usage message
121 */
122 @Override public void usage(String err) {
123 String msg = USAGE_MESSAGE;
124 msg = msg + '\n' + getUsageMessage();
125 LogUtil.userErrorMessage(err + '\n' + msg);
126 ((McIDASV)getIdv()).exit(1);
127 }
128
129 /**
130 * Append some McIDAS-V specific command line options to the default IDV
131 * usage message.
132 *
133 * @return Usage message.
134 */
135 protected String getUsageMessage() {
136 return msg(ARG_HELP, "(this message)")
137 + msg("-forceaqua", "Forces the Aqua look and feel on OS X")
138 + msg(ARG_PROPERTIES, "<property file>")
139 + msg("-Dpropertyname=value", "(Define the property value)")
140 + msg(ARG_INSTALLPLUGIN, "<plugin jar file or url to install>")
141 + msg(ARG_PLUGIN, "<plugin jar file, directory, url for this run>")
142 + msg(ARG_NOPLUGINS, "Don't load plugins")
143 + msg(ARG_CLEARDEFAULT, "(Clear the default bundle)")
144 + msg(ARG_NODEFAULT, "(Don't read in the default bundle file)")
145 + msg(ARG_DEFAULT, "<.mcv/.mcvz file>")
146 + msg(ARG_BUNDLE, "<bundle file or url>")
147 + msg(ARG_B64BUNDLE, "<base 64 encoded inline bundle>")
148 + msg(ARG_SETFILES, "<datasource pattern> <semi-colon delimited list of files> (Use the list of files for the bundled datasource)")
149 + msg(ARG_ONEINSTANCEPORT, "<port number> (Check if another version of McIDAS-V is running. If so pass command line arguments to it and shutdown)")
150 + msg(ARG_NOONEINSTANCE, "(Don't do the one instance port)")
151 + msg(ARG_NOPREF, "(Don't read in the user preferences)")
152 + msg(ARG_USERPATH, "<user directory to use>")
153 + msg(ARG_SITEPATH, "<url path to find site resources>")
154 + msg(ARG_NOGUI, "(Don't show the main window gui)")
155 + msg(ARG_DATA, "<data source> (Load the data source)")
156 + msg(ARG_DISPLAY, "<parameter> <display>")
157 // + msg("<scriptfile.isl>", "(Run the IDV script in batch mode)")
158 + msg("-script", "<jython script file to evaluate>")
159 + msg("-pyfile", "<jython script file to evaluate>")
160 // + msg(ARG_B64ISL, "<base64 encoded inline isl> This will run the isl in interactive mode")
161 // + msg(ARG_ISLINTERACTIVE, "run any isl files in interactive mode")
162 + msg(ARG_IMAGE, "<image file name> (create a jpeg image and then exit)")
163 + msg(ARG_MOVIE, "<movie file name> (create a quicktime movie and then exit)")
164 + msg(ARG_IMAGESERVER, "<port number or .properties file> (run McIDAS-V in image generation server mode. Support http requests on the given port)")
165 + msg(ARG_CATALOG, "<url to a chooser catalog>")
166 + msg(ARG_CONNECT, "<collaboration hostname to connect to>")
167 + msg(ARG_SERVER, "(Should McIDAS-V run in collaboration server mode)")
168 + msg(ARG_PORT, "<Port number collaboration server should listen on>")
169 + msg(ARG_CHOOSER, "(show the data chooser on start up) ")
170 + msg(ARG_PRINTJNLP, "(Print out any embedded bundles from jnlp files)")
171 + msg(ARG_CURRENTTIME, "<dttm> (Override current time for background processing)")
172 // + msg(ARG_CURRENTTIME, "<dttm> (Override current time for ISL processing)")
173 + msg(ARG_LISTRESOURCES, "<list out the resource types")
174 + msg(ARG_DEBUG, "(Turn on debug print)")
175 + msg(ARG_MSG_DEBUG, "(Turn on language pack debug)")
176 + msg(ARG_MSG_RECORD, "<Language pack file to write missing entries to>")
177 + msg(ARG_TRACE, "(Print out trace messages)")
178 + msg(ARG_NOERRORSINGUI, "(Don't show errors in gui)")
179 + msg(ARG_TRACEONLY, "<trace pattern> (Print out trace messages that match the pattern)");
180 }
181
182 /**
183 * @see ArgsManager#getBundleFileFilters()
184 */
185 @Override public List<PatternFileFilter> getBundleFileFilters() {
186 List<PatternFileFilter> filters = new ArrayList<PatternFileFilter>();
187 Collections.addAll(filters, getXidvFileFilter(), getZidvFileFilter(), FILTER_JNLP, FILTER_ISL, super.getXidvFileFilter(), super.getZidvFileFilter());
188 return filters;
189 }
190
191 /**
192 * Returns a list of {@link PatternFileFilter}s that can be used to determine
193 * if a file is a bundle.
194 *
195 * <p>If {@code fromOpen} is {@code true}, the
196 * returned list will contain {@code PatternFileFilter}s for bundles as
197 * well as JNLP and ISL files. If {@code false}, the returned list will
198 * only contain filters for XML and zipped bundles.
199 *
200 * @param fromOpen Whether or not this has been called from an
201 * {@literal "open file"} dialog.
202 *
203 * @return Filters for bundles.
204 */
205 public List<PatternFileFilter> getBundleFilters(final boolean fromOpen) {
206 List<PatternFileFilter> filters = new ArrayList<PatternFileFilter>();
207
208 if (fromOpen)
209 Collections.addAll(filters, getXidvZidvFileFilter(), FILTER_JNLP, FILTER_ISL, super.getXidvZidvFileFilter());
210 else
211 filters.addAll(getBundleFileFilters());
212
213 return filters;
214 }
215
216 /**
217 * @see ArgsManager#getXidvFileFilter()
218 */
219 @Override public PatternFileFilter getXidvFileFilter() {
220 return Constants.FILTER_MCV;
221 }
222
223 /**
224 * @see ArgsManager#getZidvFileFilter()
225 */
226 @Override public PatternFileFilter getZidvFileFilter() {
227 return Constants.FILTER_MCVZ;
228 }
229
230 /**
231 * @see ArgsManager#getXidvZidvFileFilter()
232 */
233 @Override public PatternFileFilter getXidvZidvFileFilter() {
234 return Constants.FILTER_MCVMCVZ;
235 }
236
237 /*
238 * There's some internal IDV file opening code that relies on this method.
239 * We've gotta override if we want to use .zidv bundles.
240 */
241 @Override public boolean isZidvFile(final String name) {
242 return isZippedBundle(name);
243 }
244
245 /* same story as isZidvFile! */
246 @Override public boolean isXidvFile(final String name) {
247 return isXmlBundle(name);
248 }
249
250 /**
251 * Tests to see if <code>name</code> has a known XML bundle extension.
252 *
253 * @param name Name of the bundle.
254 *
255 * @return Whether or not <code>name</code> has an XML bundle suffix.
256 */
257 public static boolean isXmlBundle(final String name) {
258 return IOUtil.hasSuffix(name, Constants.FILTER_MCV.getPreferredSuffix())
259 || IOUtil.hasSuffix(name, Constants.FILTER_XIDV.getPreferredSuffix());
260 }
261
262 /**
263 * Tests to see if <code>name</code> has a known zipped bundle extension.
264 *
265 * @param name Name of the bundle.
266 *
267 * @return Whether or not <code>name</code> has zipped bundle suffix.
268 */
269 public static boolean isZippedBundle(final String name) {
270 return IOUtil.hasSuffix(name, Constants.FILTER_MCVZ.getPreferredSuffix())
271 || IOUtil.hasSuffix(name, Constants.FILTER_ZIDV.getPreferredSuffix());
272 }
273
274 /**
275 * Tests <code>name</code> to see if it has a known bundle extension.
276 *
277 * @param name Name of the bundle.
278 *
279 * @return Whether or not <code>name</code> has a bundle suffix.
280 */
281 public static boolean isBundle(final String name) {
282 return (isXmlBundle(name) || isZippedBundle(name));
283 }
284 }