Package org.geoserver.python.process

Source Code of org.geoserver.python.process.PythonProcessAdapter

package org.geoserver.python.process;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.geoserver.platform.FileWatcher;
import org.geoserver.python.Python;
import org.geotools.data.Parameter;
import org.python.core.Py;
import org.python.core.PyException;
import org.python.core.PyFunction;
import org.python.core.PyList;
import org.python.core.PyObject;
import org.python.core.PySequenceList;
import org.python.core.PyStringMap;
import org.python.core.PyType;
import org.python.util.PythonInterpreter;

public class PythonProcessAdapter {

    Map<String,PyObject> processes;
    FileWatcher<Map<String,PyObject>> fw;
   
    public PythonProcessAdapter(File module, final Python py){
        fw = new FileWatcher<Map<String,PyObject>>(module) {
            @Override
            protected Map<String,PyObject> parseFileContents(InputStream in) throws IOException {
                PythonInterpreter pi = py.interpreter();
                pi.execfile(in);

                Map<String,PyObject> processes = new LinkedHashMap();
                PyStringMap locals = (PyStringMap) pi.getLocals();
                for (Object o : locals.keys()) {
                    String key = (String) o;
                    PyObject obj = locals.__getitem__(key);
                    if (obj instanceof PyFunction ) {
                        try {
                            if (obj.__getattr__("__process__") != null) {
                                processes.put(key, obj);
                            }
                        }
                        catch(PyException e) {}
                    }
                }
                return processes;
            }
        };
    }
   
    public List<String> getNames() {
        return new ArrayList(processes().keySet());
    }
   
    public String getTitle(String name) {
        return process(name).__getattr__("title").toString();
    }
   
    public String getDescription(String name) {
        return process(name).__getattr__("description").toString();
    }
   
    public String getVersion(String name) {
        return process(name).__getattr__("version").toString();
    }
   
    public Map<String,Parameter<?>> getInputParameters(String name) {
        try {
            PyList args = (PyList) process(name).__getattr__("args");
            return parameters(args);
        }
        catch(Exception e) {
            throw new RuntimeException("Error occurred looking up inputs for process " + name, e);
        }
    }
   
    public Map<String,Parameter<?>> getOutputParameters(String name) {
        try {
            PySequenceList args = (PySequenceList) process(name).__getattr__("result");
            PyList list = new PyList();
            list.add(args);
            return parameters(list);
        }
        catch(Exception e) {
            throw new RuntimeException("Error occurred looking up result for process " + name, e);
        }
    }
   
    public Map<String,Object> run(String name, Map<String,Object> inputs) throws Exception {
        PyObject run = process(name);
       
        List<PyObject> args = new ArrayList();
        List<String> kw = new ArrayList();
       
        for (Map.Entry<String,Object> input : inputs.entrySet()) {
            args.add(Py.java2py(input.getValue()));
            kw.add(input.getKey());
        }
       
        PyObject r = run.__call__(args.toArray(new PyObject[args.size()]),
            kw.toArray(new String[kw.size()]));
        Collection result = null;
     
        if (r instanceof Collection) {
            result = (Collection) r;
        }
        else {
            result = new ArrayList();
            result.add(r);
        }
       
        Map<String,Parameter<?>> outputs = getOutputParameters(name);
        if (result.size() != outputs.size()) {
            throw new IllegalStateException(String.format("Process returned %d values, should have " +
                "returned %d", result.size(), outputs.size()));
        }
       
        Map<String,Object> results = new LinkedHashMap<String, Object>();
        Iterator it = result.iterator();
        for (Parameter output : outputs.values()) {
            results.put(output.key, ((PyObject)it.next()).__tojava__(output.type));
        }
           
        return results;
    }
   
    protected Map<String,Parameter<?>> parameters(PyList list) {
        LinkedHashMap<String, Parameter<?>> inputs = new LinkedHashMap();
       
        for (PyObject obj : (List<PyObject>) list) {
            String arg = obj.__getitem__(0).toString();
          
            Object type = null;
            try {
                type = obj.__getitem__(1);
            }
            catch(PyException e) {}
           
            Object desc = null;
            try {
                desc = obj.__getitem__(2);
            }
            catch(PyException e) {}
            
            Class clazz = null;
            if (type != null && type instanceof PyType) {
                clazz = Python.toJavaClass((PyType)type);
            }
            if (clazz == null) {
                clazz = Object.class;
            }

            if (desc != null) {
                desc = desc.toString();
            }
            else {
                desc = arg;
            }
           
            inputs.put(arg, new Parameter(arg, clazz, arg, desc.toString()));
        }
        return inputs;
    }
  
   
    protected Map<String,PyObject> processes() {
        if (fw.isModified()) {
            synchronized(this) {
                if (fw.isModified()) {
                    try {
                        processes = fw.read();
                    }
                    catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
       
        return processes;
    }
   
    protected PyObject process(String name) {
        PyObject obj = processes().get(name);
        if (obj == null) {
            throw new IllegalArgumentException("No such process '" + name + "'");
        }
       
        return obj;
    }
}
TOP

Related Classes of org.geoserver.python.process.PythonProcessAdapter

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.