📄 main.java
字号:
// ========================================================================
// Copyright (c) 2003 Mort Bay Consulting (Australia) Pty. Ltd.
// $Id: Main.java 6177 2007-02-19 10:11:27Z aaime $
// ========================================================================
package org.mortbay.start;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Policy;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.StringTokenizer;
/*-------------------------------------------*/
/** Main start class.
* This class is intended to be the main class listed in the MANIFEST.MF of
* the start.jar archive. It allows an application to be started with the
* command "java -jar start.jar".
*
* The behaviour of Main is controlled by the "org/mortbay/start/start.config"
* file obtained as a resource or file. This can be overridden with the START
* system property.
*
* The format of each line in this file is:<PRE>
* SUBJECT [ [!] CONDITION [AND|OR] ]*
* </PRE>
* where SUBJECT:<PRE>
* ends with ".class" is the Main class to run.
* ends with ".xml" is a configuration file for the command line
* ends with "/" is a directory from which add all jar and zip files from.
* ends with "/*" is a directory from which add all unconsidered jar and zip files from.
* Containing = are used to assign system properties.
* all other subjects are treated as files to be added to the classpath.
* </PRE>
* Subjects may include system properties with $(propertyname) syntax.
* File subjects starting with "/" are considered absolute, all others are relative to
* the home directory.
* <P>
* CONDITION is one of:<PRE>
* always
* never
* available package.class
* java OPERATOR n.n
* nargs OPERATOR n
* OPERATOR := one of "<",">","<=",">=","==","!="
* </PRE>
* CONTITIONS can be combined with AND OR or !, with AND being the assume
* operator for a list of CONDITIONS.
* Classpath operations are evaluated on the fly, so once a class or jar is
* added to the classpath, subsequent available conditions will see that class.
*
* The system parameter CLASSPATH, if set is given to the start classloader before
* any paths from the configuration file.
*
* Programs started with start.jar may be stopped with the stop.jar, which connects
* via a local port to stop the server. The default port can be set with the
* STOP.PORT system property (a port of < 0 disables the stop mechanism). If the STOP.KEY
* system property is set, then a random key is generated and written to stdout. This key
* must be passed to the stop.jar.
*
* @author Jan Hlavaty (hlavac@code.cz)
* @author Greg Wilkins
* @version $Revision: 1.1 $
*/
public class Main {
static boolean _debug = System.getProperty("DEBUG", null) != null;
private String _classname = null;
private Classpath _classpath = new Classpath();
private String _config = System.getProperty("START", "org/mortbay/start/start.config");
private ArrayList _xml = new ArrayList();
public static void main(String[] args) {
try {
new Main().start(args);
} catch (Exception e) {
e.printStackTrace();
}
}
static File getDirectory(String name) {
try {
if (name != null) {
File dir = new File(name).getCanonicalFile();
if (dir.isDirectory()) {
return dir;
}
}
} catch (IOException e) {
}
return null;
}
boolean isAvailable(String classname) {
try {
Class.forName(classname);
return true;
} catch (ClassNotFoundException e) {
}
ClassLoader loader = _classpath.getClassLoader();
try {
loader.loadClass(classname);
return true;
} catch (ClassNotFoundException e) {
}
return false;
}
public static void invokeMain(ClassLoader classloader, String classname, String[] args)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException,
ClassNotFoundException {
Class invoked_class = null;
invoked_class = classloader.loadClass(classname);
Class[] method_param_types = new Class[1];
method_param_types[0] = args.getClass();
Method main = null;
main = invoked_class.getDeclaredMethod("main", method_param_types);
Object[] method_params = new Object[1];
method_params[0] = args;
main.invoke(null, method_params);
}
/* ------------------------------------------------------------ */
String expand(String s) {
int i1 = 0;
int i2 = 0;
while (s != null) {
i1 = s.indexOf("$(", i2);
if (i1 < 0) {
break;
}
i2 = s.indexOf(")", i1 + 2);
if (i2 < 0) {
break;
}
String property = System.getProperty(s.substring(i1 + 2, i2), "");
s = s.substring(0, i1) + property + s.substring(i2 + 1);
}
return s;
}
/* ------------------------------------------------------------ */
void configure(InputStream config, String[] args) throws Exception {
BufferedReader cfg = new BufferedReader(new InputStreamReader(config, "ISO-8859-1"));
Version java_version = new Version(System.getProperty("java.version"));
Version ver = new Version();
// JAR's already processed
java.util.Hashtable done = new Hashtable();
// Initial classpath
String classpath = System.getProperty("CLASSPATH");
if (classpath != null) {
StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator);
while (tok.hasMoreTokens())
_classpath.addComponent(tok.nextToken());
}
// Handle line by line
String line = null;
while (true) {
line = cfg.readLine();
if (line == null) {
break;
}
if ((line.length() == 0) || line.startsWith("#")) {
continue;
}
try {
StringTokenizer st = new StringTokenizer(line);
String subject = st.nextToken();
boolean expression = true;
boolean not = false;
String condition = null;
// Evaluate all conditions
while (st.hasMoreTokens()) {
condition = st.nextToken();
if (condition.equalsIgnoreCase("!")) {
not = true;
continue;
}
if (condition.equalsIgnoreCase("OR")) {
if (expression) {
break;
}
expression = true;
continue;
}
if (condition.equalsIgnoreCase("AND")) {
if (!expression) {
break;
}
continue;
}
boolean eval = true;
if (condition.equals("true") || condition.equals("always")) {
eval = true;
} else if (condition.equals("false") || condition.equals("never")) {
eval = false;
} else if (condition.equals("available")) {
String class_to_check = st.nextToken();
eval = isAvailable(class_to_check);
} else if (condition.equals("exists")) {
try {
eval = false;
File file = new File(expand(st.nextToken()));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -