/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* @author Neeraj Joshi <jneeraj@us.ibm.com>
*
* This class implements the Actuator interface for the JAVA binding
* of SPL
*
*/
package org.apache.imperius.javaspl;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.imperius.spl.core.Actuator;
import org.apache.imperius.spl.core.Argument;
import org.apache.imperius.spl.core.TypeInfo;
import org.apache.imperius.spl.parser.exceptions.SPLException;
public class JavaActuatorImpl implements Actuator {
//private static final String sourceClass="JavaActuatorImpl";
//private static Logger logger = SPLLogger.getCIMSPLLogger().getLogger();
private URL[] fUrls = null;
public JavaActuatorImpl() {
}
public JavaActuatorImpl(URL[] urls) {
fUrls = urls;
}
/**
* Invokes the given method on the given instance
*/
public Object invokeMethod(String className, String qualifier,
Object instance, String methodName, List arguments) throws SPLException {
Class c;
Object result = null;
try {
// Load class
//c = Class.forName(instance.getClass().getName());
// modified by naidu to enable URL class loading
if(fUrls == null) {
c = Class.forName(instance.getClass().getName());
} else {
URLClassLoader uc = new URLClassLoader(fUrls);
c = uc.loadClass(instance.getClass().getName());
}
// Get an array of formal parameter class types
Class[] arrayOfParameterTypes = _getParameterTypeArray(arguments);
// Load the method using reflection
Method method = c.getMethod(methodName, arrayOfParameterTypes);
// If No. of formal params > 0
if (arguments.size() != 0) {
List paramValues = new ArrayList();
Iterator it = arguments.iterator();
// Iterate over the passed parameters
while (it.hasNext()) {
Argument arg = (Argument) it.next();
//Add the values of the passed parameters to a list
paramValues.add(arg.getValue());
}
// Convert list to an array
Object[] arrayOfParameters = paramValues.toArray();
// Invoke the method on the passed object
result = method.invoke(instance, arrayOfParameters);
} else {
Object[] arrayOfParameters = new Object[0];
result = method.invoke(instance, arrayOfParameters);
}
} catch (ClassNotFoundException e) {
throw new SPLException(e.getMessage());
} catch (SecurityException e) {
throw new SPLException(e.getMessage());
} catch (NoSuchMethodException e) {
throw new SPLException(e.getMessage());
} catch (IllegalArgumentException e) {
throw new SPLException(e.getMessage());
} catch (IllegalAccessException e) {
throw new SPLException(e.getMessage());
} catch (InvocationTargetException e) {
throw new SPLException(e.getMessage());
}
return result;
}
/**
* @param className : fully qualified name of the class whoose instance is to be modified
* @param instance : instance to be modified
* @param memberMap: A map of the form (String member Name -> Object value to be set to)
*
*/
// public void modifyInstance(String className, String qualifier,
// Object instance, Map memberMap) throws SPLException {
// Class c;
// try {
// // Load class
// //c = Class.forName(className);
//
// // modified by naidu to enable URL class loading
// if(fUrls == null) {
// c = Class.forName(className);
// } else {
// URLClassLoader uc = new URLClassLoader(fUrls);
// c = uc.loadClass(className);
// }
//
// // Iterate over the property map for the instance
// Iterator keyIt = memberMap.keySet().iterator();
// while (keyIt.hasNext()) {
// String propName = (String) keyIt.next();
// // Retrieve value of the property
// Object value = memberMap.get(propName);
//
// // Load field
// Field member = c.getField(propName);
//
// // Set the value of the field
// member.set(instance, value);
//
// }
// } catch (ClassNotFoundException e) {
// throw new SPLException(e.getMessage());
//
// } catch (SecurityException e) {
// throw new SPLException(e.getMessage());
// } catch (NoSuchFieldException e) {
// throw new SPLException(e.getMessage());
// } catch (IllegalArgumentException e) {
// throw new SPLException(e.getMessage());
// } catch (IllegalAccessException e) {
// throw new SPLException(e.getMessage());
// }
//
// }
public void modifyInstance(String className, String qualifier,
Object instance, Map memberMap) throws SPLException {
Class c;
try {
// Load class
//c = Class.forName(className);
// modified by naidu to enable URL class loading
if(fUrls == null) {
c = Class.forName(className);
} else {
URLClassLoader uc = new URLClassLoader(fUrls);
c = uc.loadClass(className);
}
// Iterate over the property map for the instance
Iterator keyIt = memberMap.keySet().iterator();
while (keyIt.hasNext()) {
String propName = (String) keyIt.next();
// Retrieve value of the property
Object value = memberMap.get(propName);
try
{
// Load field
Field member = c.getField(propName);
// Set the value of the field
member.set(instance, value);
}
catch (NoSuchFieldException e)
{
boolean isMethodExists = false;
Method[] classMethods = c.getMethods();
if (classMethods != null) {
for (int i = 0; i < classMethods.length; i++)
{
if (classMethods[i].getName().equals(
getAccessorMethodName(propName)))
{
isMethodExists = true;
classMethods[i].invoke(instance,
new Object[] { value });
break;
}
}
if (!isMethodExists)
throw new NoSuchMethodException();
}
}
}
} catch (ClassNotFoundException e) {
throw new SPLException(e);
} catch (SecurityException e) {
throw new SPLException(e);
} catch(NoSuchMethodException e) {
throw new SPLException(e);
} catch(InvocationTargetException e) {
throw new SPLException(e);
} catch (IllegalArgumentException e) {
throw new SPLException(e);
} catch (IllegalAccessException e) {
throw new SPLException(e);
}
}
/**
* Iterate over the list of Argument objects to retrieve an
* array of the class types
* @param inParameterList
* @return
* @throws SPLException
*/
private Class[] _getParameterTypeArray(List inParameterList)
throws SPLException {
int listSize = inParameterList.size();
int i = 0;
Class[] paramTypeArray = new Class[listSize];
try {
Iterator it = inParameterList.iterator();
// Iterate over the arguments
while (it.hasNext()) {
Argument arg = (Argument) it.next();
TypeInfo tp = arg.getType();
boolean isArray = arg.getIsArray();
String referenceName = arg.getReferenceTypeName();
// convert internal type to java type
Class c = JavaSPLTypeConstants.convertInternalTypeToJavaType(tp.getType(), isArray, referenceName);
// Add to array
paramTypeArray[i++] = c;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new SPLException(e.getMessage());
}
return paramTypeArray;
}
private String getAccessorMethodName(String identifier)
{
if(Character.isLetter(identifier.charAt(0)))
{
identifier = Character.toUpperCase(identifier.charAt(0)) + identifier.substring(1);
}
identifier = "set"+identifier;
return identifier;
}
}