package org.geoserver.python; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import org.geoserver.platform.GeoServerResourceLoader; import org.geoserver.python.datastore.PythonDataStoreFactory; import org.geotools.util.logging.Logging; import org.python.core.Py; import org.python.core.PyBoolean; import org.python.core.PyException; import org.python.core.PyFile; import org.python.core.PyFloat; import org.python.core.PyInteger; import org.python.core.PyLong; import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyType; import org.python.util.PythonInterpreter; public class Python { public static Logger LOGGER = Logging.getLogger("org.geoserver.jython"); static HashMap<Class<? extends PyObject>, Class> pyToJava = new HashMap(); static { pyToJava.put(PyString.class, String.class); pyToJava.put(PyInteger.class, Integer.class); pyToJava.put(PyLong.class, Long.class); pyToJava.put(PyFloat.class, Double.class); pyToJava.put(PyBoolean.class, Boolean.class); //pyToJava.put(PyFile.class, File.class); } public static Class toJavaClass(PyType type) { Class clazz = null; try { Object o = Py.tojava(type, Object.class); if (o != null && o instanceof Class) { clazz = (Class) o; } } catch(PyException e) {} if (clazz != null && PyObject.class.isAssignableFrom(clazz)) { try { PyObject pyobj = (PyObject) clazz.newInstance(); Object obj = pyobj.__tojava__(Object.class); if (obj != null) { clazz = obj.getClass(); } } catch(Exception e) {} } if (clazz != null && PyObject.class.isAssignableFrom(clazz)) { Class jclass = pyToJava.get(clazz); if (jclass != null) { clazz = jclass; } } if (clazz != null && clazz.getName().startsWith("org.python.proxies")) { //get base type PyType base = (PyType) type.getBase(); Class c = toJavaClass(base); if (c != null) { clazz = c; } } return clazz; } GeoServerResourceLoader resourceLoader; boolean initialized = false; public Python(GeoServerResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } public PythonInterpreter interpreter() { if (!initialized) { synchronized (this) { if (!initialized) { initialize(); initialized = true; } } } return new PythonInterpreter(); } void initialize() { //copy libs into <DATA_DIR>/python/lib try { initLibs(); } catch (IOException e) { throw new RuntimeException(e); } //initialize the python path ArrayList<String> pythonPath = new ArrayList(); //look for a jython installation on the system /*String jythonHome = System.getenv("JYTHON_HOME"); if (jythonHome != null) { pythonPath.add(jythonHome+File.separator+"/Lib"); }*/ //add <GEOSERVER_DATA_DIR>/jython/lib to path try { pythonPath.add(getLibRoot().getCanonicalPath()); pythonPath.add(getDataStoreRoot().getCanonicalPath()); } catch (IOException e) { LOGGER.log(Level.WARNING, "Unable to access Jython lib directory", e); } StringBuffer path = new StringBuffer(); for (String loc : pythonPath) { path.append(loc).append(File.pathSeparator); } path.setLength(path.length()-1); Properties props = new Properties(); props.put("python.path", path.toString()); PythonInterpreter.initialize(null, props, null); } void initLibs() throws IOException { File libRoot = getLibRoot(); //File gsPyRoot = resourceLoader.findOrCreateDirectory(libRoot, "geoserver"); ClassLoader cl = getClass().getClassLoader(); //IOUtils.copyStream(cl.getResourceAsStream("geoserver/__init__.py"), // new FileOutputStream(new File(gsPyRoot, "__init__.py")), true, true); //IOUtils.copyStream(cl.getResourceAsStream("geoserver/catalog.py"), // new FileOutputStream(new File(gsPyRoot, "catalog.py")), true, true); //IOUtils.copyStream(cl.getResourceAsStream("geoserver/layer.py"), // new FileOutputStream(new File(gsPyRoot, "layer.py")), true, true); //ZipFile f = new ZipFile(new File(cl.getResource("geoscript.zip").getFile())); //new File(libRoot, "geoscript").mkdir(); //IOUtils.inflate(f, libRoot, null); } public File getRoot() throws IOException { return resourceLoader.findOrCreateDirectory("python"); } public File getScriptRoot() throws IOException { return resourceLoader.findOrCreateDirectory("python", "script"); } public File getAppRoot() throws IOException { return resourceLoader.findOrCreateDirectory("python", "app"); } public String getLibPath() throws IOException { return "python" + File.separator + "lib"; } public File getLibRoot() throws IOException { return resourceLoader.findOrCreateDirectory(getLibPath()); } public File getDataStoreRoot() throws IOException { return resourceLoader.findOrCreateDirectory("python", "datastore"); } public File getProcessRoot() throws IOException { return resourceLoader.findOrCreateDirectory("python", "process"); } public File getFormatRoot() throws IOException { return resourceLoader.findOrCreateDirectory("python", "format"); } public File getFilterRoot() throws IOException { return resourceLoader.findOrCreateDirectory("python", "filter"); } }