/**
* $Id: $
* $Date: $
*
*/
package org.xmlsh.sh.module;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.xmlsh.core.CoreException;
import org.xmlsh.core.EvalEnv;
import org.xmlsh.core.EvalFlag;
import org.xmlsh.core.XFunction;
import org.xmlsh.core.ICommand;
import org.xmlsh.core.IXFunction;
import org.xmlsh.core.InvalidArgumentException;
import org.xmlsh.core.XClassLoader;
import org.xmlsh.core.XValue;
import org.xmlsh.sh.shell.Shell;
import org.xmlsh.types.TypeFamily;
import org.xmlsh.util.JavaUtils;
import org.xmlsh.util.Util;
public class JavaModule extends Module
{
static class JavaModuleFunction extends XFunction
{
private JavaModule mModule;
private Class<?> mClass;
public JavaModuleFunction(JavaModule javaModule, String func, Class<?> cls, ClassLoader cl)
{
super(func);
mModule = javaModule;
mClass = cls;
}
@Override
public EvalEnv argumentEnv(EvalEnv parent)
{
return parent.withFlagsOff(EvalFlag.EXPAND_WILD, EvalFlag.SPLIT_WORDS);
}
@Override
public Module getModule() {
return mModule;
}
@Override
public EvalEnv returnEnv(EvalEnv parent)
{
return EvalEnv.evalNone();
}
@Override
public XValue run(Shell shell, List<XValue> args) throws Exception
{
XValue retVal = null;
if(Util.isEqual("new", getName())) { // Constructor
retVal = JavaUtils.newXValue(mClass, args);
}
else
// return class as an object
if(Util.isEqual("class", getName())) {
retVal = XValue.newXValue(TypeFamily.JAVA, mClass);
}
else {
Object thisObj = null;
// Static first
Method m = JavaUtils.getBestMatch(mClass, getName(), args, true);
if(m == null && args.size() > 0) {
thisObj = args.remove(0).asObject();
if(mClass.isInstance(thisObj))
m = JavaUtils.getBestMatch(mClass, getName(), args, false);
}
if(m == null)
throw new InvalidArgumentException("Cannot find matching method: " + getName());
retVal = thisObj != null ? JavaUtils.callMethod(m, thisObj, args) : JavaUtils.callStaticMethod(m, args);
}
return retVal;
}
}
private Class<?> mJavaClass;
static Logger mLogger = LogManager.getLogger();
JavaModule( ModuleConfig config, XClassLoader loader) throws CoreException
{
super(config, loader );
mJavaClass = findClass(config.getModuleClass());
if(mJavaClass == null)
throw new InvalidArgumentException("Class not found:" + config.getModuleClass());
}
static ModuleConfig getConfiguration(Shell shell, String clsname,
List<URL> at) {
ModuleConfig config = new ModuleConfig("java" , "java:" + clsname , at, shell.getSerializeOpts());
config.setModuleClass(clsname);
return config ;
}
@Override
public String describe()
{
return "java [ class=" + mJavaClass.getName() + " ]";
}
@Override
public ICommand getCommand(String name)
{
return null;
}
@Override
public IXFunction getFunction(final String name)
{
return new JavaModuleFunction( this , name, mJavaClass, getClassLoader());
}
@Override
public boolean hasHelp(String name)
{
// TODO Auto-generated method stub
return false;
}
@Override
public URL findResource(String res) {
mLogger.trace("TODO: maybe look in class's package for resource {}",res);
return(null);
}
}
/*
* Copyright (C) 2008-2012 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): David A. Lee
*/