/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.process.dem; import java.awt.RenderingHints.Key; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.data.Parameter; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.factory.Hints; import org.geotools.feature.FeatureCollection; import org.geotools.feature.NameImpl; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.process.Process; import org.geotools.process.ProcessException; import org.geotools.process.ProcessFactory; import org.geotools.process.impl.SingleProcessFactory; import org.geotools.text.Text; import org.geotools.util.KVP; import org.geotools.util.SimpleInternationalString; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.Name; import org.opengis.geometry.Envelope; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.util.InternationalString; import org.opengis.util.ProgressListener; import com.vividsolutions.jts.geom.Polygon; /** * ProcessFactory for several digital elevation model processes. * * @since 2.7 * * @source $URL: http://svn.osgeo.org/geotools/branches/2.7.x/build/maven/javadoc/../../../modules/unsupported/process/src/main/java/org/geotools/process/dem/DEMProcessFactory.java $ * http://svn.osgeo.org/geotools/trunk/modules/unsupported/process/src/main/java/org/geotools * /process/raster/RasterToVectorFactory.java $ */ public class DEMProcessFactory implements ProcessFactory { private static final String VERSION_STRING = "0.0.1"; Class<?> TARGET = DEMTools.class; String namespace = "http://localhost/dem/"; public Process create(Name name) { return new ProcessInvocation(DEMTools.class, name.getLocalPart()); } public InternationalString getTitle() { return new SimpleInternationalString( "DEM Tools" ); } public InternationalString getDescription(Name name) { Method method = method( name.getLocalPart() ); if( method == null ){ return null; } DescribeProcess info = method.getAnnotation( DescribeProcess.class ); if( info != null ){ return new SimpleInternationalString( info.description() ); } else { return null; } } public Method method( String name) { for( Method method : TARGET.getMethods() ){ DescribeProcess INFO = method.getAnnotation( DescribeProcess.class ); if( INFO != null ){ if( name.equalsIgnoreCase( method.getName() )){ return method; } } } return null; } // public DescribeProcess info( String name) { // for( Method method : TARGET.getMethods() ){ // DescribeProcess INFO = method.getAnnotation( DescribeProcess.class ); // if( INFO != null ){ // if( name.equalsIgnoreCase( method.getName() )){ // return INFO; // } // } // } // return null; // } public Set<Name> getNames() { Set<Name> names = new LinkedHashSet<Name>(); for( Method method : TARGET.getMethods() ){ DescribeProcess INFO = method.getAnnotation( DescribeProcess.class ); if( INFO != null ){ names.add( new NameImpl( namespace, method.getName() )); } } return names; } public Map<String, Parameter<?>> getParameterInfo(Name name) { Method method = method( name.getLocalPart() ); Map<String,Parameter<?>> input = new LinkedHashMap<String, Parameter<?>>(); Annotation[][] PARAM_INFO = method.getParameterAnnotations(); Class<?>[] PARAM_TYPE = method.getParameterTypes(); for( int i=0; i< PARAM_TYPE.length; i++ ){ Parameter<?> param = paramInfo( i, PARAM_TYPE[i], PARAM_INFO[i] ); input.put( param.key, param ); } return input; } @SuppressWarnings("unchecked") public Map<String, Parameter<?>> getResultInfo(Name name, Map<String, Object> parameters) throws IllegalArgumentException { Method method = method( name.getLocalPart() ); Map<String,Parameter<?>> result = new LinkedHashMap<String, Parameter<?>>(); for( Annotation annotation : method.getAnnotations() ){ if( annotation instanceof DescribeResult ){ DescribeResult info = (DescribeResult) annotation; Parameter<?> RESULT = new Parameter( info.name(), info.type(), info.name(), info.description() ); result.put( RESULT.key, RESULT ); } } if( result.isEmpty() ){ Parameter<?> VALUE = new Parameter( "value", Object.class, "Undefined Value", "No description is available" ); result.put( VALUE.key, VALUE ); } return result; } public InternationalString getTitle(Name name) { return null; } public String getVersion(Name name) { return null; } public boolean supportsProgress(Name name) { return false; } public boolean isAvailable() { return false; } public Map<Key, ?> getImplementationHints() { return null; } static class ProcessInvocation implements Process { private String name; private Class<DEMTools> target; public ProcessInvocation(Class<DEMTools> target, String method) { this.target = target; this.name = method; } Method method() { for (Method method : target.getMethods()) { if (name.equalsIgnoreCase(method.getName())) { return method; } } return null; } @SuppressWarnings("unchecked") public Map<String, Object> execute(Map<String, Object> input, ProgressListener monitor) throws ProcessException { Method method = method(); if (method == null) { return null; } TypeVariable<Method>[] PARAM_TYPE = method.getTypeParameters(); Annotation[][] PARAM_INFO = method.getParameterAnnotations(); Object args[] = new Object[PARAM_TYPE.length]; for (int i = 0; i < args.length; i++) { DescribeParameter PARAMETER = paramInfo(i, PARAM_INFO); String name = PARAMETER == null ? "arg"+i : PARAMETER.name(); Object value = input.get(name); args[i] = value; } Object value = null; try { value = method.invoke(null, args); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } if (value == null) { throw new IllegalArgumentException("Unable to encode null result for " + name); } if (value instanceof Object[]) { Object values[] = (Object[]) value; Map<String, Object> result = new LinkedHashMap<String, Object>(); int i = 0; for (Annotation annotation : method.getAnnotations()) { if (i >= values.length) break; // no more values to encode Object obj = values[i]; if (annotation instanceof DescribeResult) { DescribeResult RESULT = (DescribeResult) annotation; if (RESULT.type().isInstance(obj)) { result.put(RESULT.name(), obj); } else { throw new IllegalArgumentException(name + " unable to encode result " + obj + " as " + RESULT.type()); } } } return result; } else if (value instanceof Map) { return (Map<String, Object>) value; } else { Map<String, Object> result = new LinkedHashMap<String, Object>(); DescribeResult RESULT = method.getAnnotation(DescribeResult.class); if (RESULT != null) { result.put(RESULT.name(), value); } else { result.put("value", value); } } return null; } } @SuppressWarnings("unchecked") Parameter<?> paramInfo( int i, Class<?> TYPE, Annotation[] PARAM_INFO ){ DescribeParameter info = null; for( Annotation annotation : PARAM_INFO ){ if (annotation instanceof DescribeParameter) { info = (DescribeParameter) annotation; break; } } if( info != null ){ Parameter param = new Parameter(info.name(), TYPE, info.name(), info.description() ); return param; } else { Parameter param = new Parameter( "arg"+i, TYPE, "Argument "+i, "Input "+TYPE.getName()+" value"); return param; } } /** * Lookup a decent DescribeParameter for the indexed parameter. * * @param i * @param PARAM_INFO * @return */ static DescribeParameter paramInfo(int i, Annotation[][] PARAM_INFO) { for (Annotation annotation : PARAM_INFO[i]) { if (annotation instanceof DescribeParameter) { DescribeParameter PARAMETER = (DescribeParameter) annotation; return PARAMETER; } } return null; } }