/**
* $Id: xpwd.java 21 2008-07-04 08:33:47Z daldei $
* $Date: 2008-07-04 04:33:47 -0400 (Fri, 04 Jul 2008) $
*
*/
package org.xmlsh.modules.java;
import java.io.InputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Permission;
import java.util.List;
import org.xmlsh.annotations.Command;
import org.xmlsh.core.InvalidArgumentException;
import org.xmlsh.core.XCommand;
import org.xmlsh.core.XValue;
import org.xmlsh.sh.shell.SerializeOpts;
import org.xmlsh.util.Util;
/*
*
* Command to call into any java class's main method in the same JVM
*
* jcall class args
*/
@Command
public class jcall extends XCommand
{
@SuppressWarnings("serial")
private static class ExitException extends SecurityException
{
int mExitCode;
ExitException(int code)
{
mExitCode = code;
}
}
private static class NoExitSecurityManager extends SecurityManager
{
SecurityManager mParent;
@Override
public void checkPermission(Permission perm)
{
if(mParent != null)
mParent.checkPermission(perm);
}
@Override
public void checkPermission(Permission perm, Object context)
{
if(mParent != null)
mParent.checkPermission(perm, context);
}
NoExitSecurityManager(SecurityManager parent)
{
mParent = parent;
}
/*
* (non-Javadoc)
*
* @see java.lang.SecurityManager#checkExit(int)
*/
@Override
public void checkExit(int status)
{
throw new ExitException(status);
}
}
/*
* jcall invoke native java main class
*
* @see org.xmlsh.core.XCommand#run(java.util.List)
*/
@Override
public synchronized int run(List<XValue> args) throws Exception
{
SerializeOpts serializeOpts = getSerializeOpts();
/*
* Do NOT use Options because we need to split out the jcall options differently then the invoked options
*/
ClassLoader classloader = null;
if(args.size() > 1) {
String arg1 = args.get(0).toString();
if(arg1.equals("-cp") || arg1.equals("-classpath")) {
args.remove(0);
XValue classpath = args.remove(0);
classloader = getClassLoader(classpath);
}
}
if(classloader == null)
classloader = getClassLoader();
SecurityManager oldManager = null;
if(args.size() < 1)
throw new InvalidArgumentException("usage: jcall [-cp classpath] [class|object] [args]");
PrintStream stdout = System.out;
// DAL: Resesting stderr causes stderr to be lost after this call
// dont know why. Dont reset stderr and all is well.
// PrintStream stderr = System.err;
InputStream stdin = System.in;
PrintStream newStdout = null;
// PrintStream newStderr = null;
try {
oldManager = System.getSecurityManager();
System.setSecurityManager(new NoExitSecurityManager(oldManager));
System.setOut(newStdout = getStdout().asPrintStream(serializeOpts));
System.setIn(getStdin().asInputStream(serializeOpts));
String className = args.remove(0).toString();
Class<?> cls = Class.forName(className, true, classloader);
Method method = cls.getMethod("main", String[].class);
method.invoke(null, new Object[] { Util.toStringArray(args) });
} catch (InvocationTargetException e) {
Throwable e2 = e.getTargetException();
if(e2 instanceof ExitException)
return ((ExitException) e2).mExitCode;
else if(e2 != null && e2 instanceof Exception)
throw (Exception) e2;
else throw e;
} catch (ExitException e) {
return e.mExitCode;
} catch (Exception e) {
e.printStackTrace();
}
finally {
System.setSecurityManager(oldManager);
System.setOut(stdout);
// System.setErr(stderr);
System.setIn(stdin);
newStdout.flush();
// newStderr.flush();
}
return 0;
}
/*
* Test for calling jcall or exiting
*/
public static void main(String[] args)
{
if(args.length > 0)
System.out.println(args[0]);
if(args.length == 1 && args[0].equals("exit"))
System.exit(1);
}
}
//
//
// Copyright (C) 2008-2014 David A. Lee.
//
// The contents of this file are subject to the "Simplified BSD License" (the "License");
// you may not use this file except in compliance with the License. You may obtain a copy of the
// License at http://www.opensource.org/licenses/bsd-license.php
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
// See the License for the specific language governing rights and limitations under the License.
//
// The Original Code is: all this file.
//
// The Initial Developer of the Original Code is David A. Lee
//
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
//
// Contributor(s): none.
//