/* * Copyright (c) 2016 Vivid Solutions. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * * http://www.eclipse.org/org/documents/edl-v10.php. */ package org.locationtech.jtstest.geomop; import java.lang.reflect.*; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.util.Assert; import org.locationtech.jtstest.util.*; /** * A {@link GeometryFunction} which calls a static * {@link Method}. * * @author Martin Davis * */ public class StaticMethodGeometryFunction extends BaseGeometryFunction { private static final String FUNCTIONS_SUFFIX = "Functions"; private static final String PARAMETERS_SUFFIX = "Parameters"; private static final String DESCRIPTION_SUFFIX = "Description"; public static StaticMethodGeometryFunction createFunction(Method method) { Assert.isTrue(Geometry.class.isAssignableFrom((method.getParameterTypes())[0])); Class clz = method.getDeclaringClass(); String funcName = method.getName(); String description = "dummy"; String[] paramNames = new String[] { }; Class[] paramTypes = extractParamTypes(method); Class returnType = method.getReturnType(); return new StaticMethodGeometryFunction(funcName, description, paramNames, paramTypes, returnType, method); } private static Class[] extractParamTypes(Method method) { Class[] methodParamTypes = method.getParameterTypes(); Class[] types = new Class[methodParamTypes.length - 1]; for (int i = 1; i < methodParamTypes.length; i++) types[i-1] = methodParamTypes[i]; return types; } private Method method; public StaticMethodGeometryFunction( String name, String description, String[] parameterNames, Class[] parameterTypes, Class returnType, Method method) { super(name, description, parameterNames, parameterTypes, returnType); this.method = method; } public Object invoke(Geometry g, Object[] arg) { return invoke(method, null, createFullArgs(g, arg)); } /** * Creates an arg array which includes the target geometry as the first argument * * @param g * @param arg * @return */ private static Object[] createFullArgs(Geometry g, Object[] arg) { int fullArgLen = 1; if (arg != null) fullArgLen = arg.length + 1; Object[] fullArg = new Object[fullArgLen]; fullArg[0] = g; for (int i = 1; i < fullArgLen; i++) { fullArg[i] = arg[i-1]; } return fullArg; } public static Object invoke(Method method, Object target, Object[] args) { Object result; try { result = method.invoke(target, args); } catch (InvocationTargetException ex) { Throwable t = ex.getCause(); if (t instanceof RuntimeException) throw (RuntimeException) t; throw new RuntimeException(invocationErrMsg(ex)); } catch (Exception ex) { System.out.println(ex.getMessage()); throw new RuntimeException(ex.getMessage()); } return result; } private static String invocationErrMsg(InvocationTargetException ex) { Throwable targetEx = ex.getTargetException(); String msg = getClassname(targetEx.getClass()) + ": " + targetEx.getMessage(); return msg; } public static String getClassname(Class javaClass) { String jClassName = javaClass.getName(); int lastDotPos = jClassName.lastIndexOf("."); return jClassName.substring(lastDotPos + 1, jClassName.length()); } }