Package org.geoserver.wps.jts

Source Code of org.geoserver.wps.jts.SpringBeanProcessFactory

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wps.jts;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.FactoryIteratorProvider;
import org.geotools.feature.NameImpl;
import org.geotools.filter.FunctionFactory;
import org.geotools.process.ProcessFactory;
import org.geotools.process.Processors;
import org.geotools.process.factory.DescribeParameter;
import org.geotools.process.factory.DescribeProcess;
import org.geotools.process.factory.DescribeResult;
import org.geotools.process.factory.DescribeResults;
import org.geotools.process.function.ProcessFunctionFactory;
import org.geotools.util.SimpleInternationalString;
import org.opengis.feature.type.Name;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;

/**
* A {@link ProcessFactory} meant to be declared in a Spring context. It will look in the
* application context for beans implementing the specified marker interface and annotated with
* {@link DescribeProcess}, {@link DescribeParameter} and {@link DescribeResult}. Each bean will
* have a "execute" method taking the process parameters as arguments and returning the results
*/
public class SpringBeanProcessFactory extends org.geotools.process.factory.AnnotationDrivenProcessFactory implements
        ApplicationContextAware, ApplicationListener {

    Map<String, Class> classMap;

    Map<String, String> beanMap;

    Class markerInterface;

    ApplicationContext applicationContext;

    FactoryIteratorProvider iterator;

    public SpringBeanProcessFactory(String title, String namespace, Class markerInterface) {
        super(new SimpleInternationalString(title), namespace);
        this.markerInterface = markerInterface;

        // create an iterator that will register this factory into SPI
        iterator = new FactoryIteratorProvider() {

            public <T> Iterator<T> iterator(Class<T> category) {
                if (ProcessFactory.class.isAssignableFrom(category)) {
                    return (Iterator<T>) Collections.singletonList(SpringBeanProcessFactory.this)
                            .iterator();
                } else {
                    return null;
                }
            }
        };
       
        // register the new process and make the process function factory lookup again the processes
        Processors.addProcessFactory(this);
        for(FunctionFactory ff : CommonFactoryFinder.getFunctionFactories(null)) {
            if(ff instanceof ProcessFunctionFactory) {
                ProcessFunctionFactory pff = (ProcessFunctionFactory) ff;
                pff.clear();
            }
        }

    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;

        // loads all of the beans implementing the marker interface
        String[] beanNames = applicationContext.getBeanNamesForType(markerInterface, true, true);
        // build a name to class and name to bean name maps
        classMap = new HashMap<String, Class>();
        beanMap = new HashMap<String, String>();
        for (String beanName : beanNames) {
            Class c = applicationContext.getType(beanName);
            String name = c.getSimpleName();
            if (name.endsWith("Process")) {
                name = name.substring(0, name.indexOf("Process"));
            }
            classMap.put(name, c);
            beanMap.put(name, beanName);
        }

    }

    @Override
    protected DescribeProcess getProcessDescription(Name name) {
        Class c = classMap.get(name.getLocalPart());
        if (c == null) {
            return null;
        } else {
            return (DescribeProcess) c.getAnnotation(DescribeProcess.class);
        }
    }

    @Override
    protected Method method(String className) {
        Class c = classMap.get(className);
        Method lastExecute = null;
        if (c != null) {
            for (Method m : c.getMethods()) {
                if(m.getName().equals("execute")) {
                    if(lastExecute != null) {
                        lastExecute = m;
                    }
                    // if annotated return immediately, otherwise keep it aside
                    if(m.getAnnotation(DescribeResult.class) != null
                            || m.getAnnotation(DescribeResults.class) != null) {
                        return m;
                    }
                }
            }
        }
        return lastExecute;
    }

    public Set<Name> getNames() {
        Set<Name> result = new LinkedHashSet<Name>();
        List<String> names = new ArrayList<String>(classMap.keySet());
        Collections.sort(names);
        for (String name : names) {
            result.add(new NameImpl(namespace, name));
        }
        return result;
    }

    @Override
    protected Object createProcessBean(Name name) {
        String beanName = beanMap.get(name.getLocalPart());
        if (beanName == null) {
            return null;
        }
        return applicationContext.getBean(beanName);
    }

    public void onApplicationEvent(ApplicationEvent event) {
        // add and remove the process factory as necessary
        if (event instanceof ContextRefreshedEvent) {
            Processors.addProcessFactory(this);
        } else if (event instanceof ContextClosedEvent) {
            Processors.removeProcessFactory(this);
        }
    }
}
TOP

Related Classes of org.geoserver.wps.jts.SpringBeanProcessFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.