Package org.python.core

Source Code of org.python.core.SyspathJavaLoader

// Copyright (c) Corporation for National Research Initiatives
// Copyright 2000 Samuele Pedroni

package org.python.core;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.StringTokenizer;
import java.util.zip.ZipEntry;

import org.python.core.util.RelativeFile;

public class SyspathJavaLoader extends ClassLoader {

    private static final char SLASH_CHAR = '/';

    public SyspathJavaLoader(ClassLoader parent) {
      super(parent);
    }
   

    /**
     * Returns a byte[] with the contents read from an InputStream.
     *
     * The stream is closed after reading the bytes.
     * 
     * @param input The input stream
     * @param size The number of bytes to read
     *  
     * @return an array of byte[size] with the contents read
     * */
    private byte[] getBytesFromInputStream(InputStream input, int size) {
      try {
        byte[] buffer = new byte[size];
          int nread = 0;
          while(nread < size) {
              nread += input.read(buffer, nread, size - nread);
          }
          return buffer;
      } catch (IOException exc) {
            return null;
      } finally {
            try {
                input.close();
            } catch (IOException e) {
              // Nothing to do
            }
      }
    }
    
    private byte[] getBytesFromDir(String dir, String name) {
      try {
        File file = getFile(dir, name);
          if (file == null) {
              return null;
          }
          return getBytesFromInputStream(new FileInputStream(file), (int)file.length());
        } catch (FileNotFoundException e) {
            return null;
        } catch(SecurityException e) {
            return null;
        }

    }
   
    private byte[] getBytesFromArchive(SyspathArchive archive, String name) {
        String entryname = name.replace('.', SLASH_CHAR) + ".class";
        ZipEntry ze = archive.getEntry(entryname);
        if (ze == null) {
            return null;
        }
        try {
      return getBytesFromInputStream(archive.getInputStream(ze),
                                 (int)ze.getSize());
    } catch (IOException e) {
      return null;
    }
    }

    protected Package definePackageForClass(String name) {
      int lastDotIndex = name.lastIndexOf('.');
      if (lastDotIndex < 0) {
        return null;
      }
        String pkgname = name.substring(0, lastDotIndex);
        Package pkg = getPackage(pkgname);
        if (pkg == null) {
            pkg = definePackage(pkgname, null, null, null, null, null, null, null);
        }
        return pkg;
    }
   
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
      PySystemState sys = Py.getSystemState();
      ClassLoader sysClassLoader = sys.getClassLoader();
      if (sysClassLoader != null) {
        // sys.classLoader overrides this class loader!
        return sysClassLoader.loadClass(name);
      }
        // Search the sys.path for a .class file matching the named class.
      PyList path = sys.path;
        for (int i = 0; i < path.__len__(); i++) {
          byte[] buffer;
            PyObject entry = replacePathItem(sys, i, path);
            if (entry instanceof SyspathArchive) {
                SyspathArchive archive = (SyspathArchive)entry;
                buffer = getBytesFromArchive(archive, name);               
            } else {
                if (!(entry instanceof PyUnicode)) {
                    entry = entry.__str__();
                }
                String dir = entry.toString();
              buffer = getBytesFromDir(dir, name);
            }
            if (buffer != null) {
              definePackageForClass(name);
              return defineClass(name, buffer, 0, buffer.length);
            }
        }
        // couldn't find the .class file on sys.path
        throw new ClassNotFoundException(name);
    }
      
    @Override
    protected URL findResource(String res) {
      PySystemState sys = Py.getSystemState();
     
      if (res.charAt(0) == SLASH_CHAR) {
            res = res.substring(1);
        }
      String entryRes = res;
        if (File.separatorChar != SLASH_CHAR) {
            res = res.replace(SLASH_CHAR, File.separatorChar);
            entryRes = entryRes.replace(File.separatorChar, SLASH_CHAR);
        }

        PyList path = sys.path;
        for (int i = 0; i < path.__len__(); i++) {
            PyObject entry = replacePathItem(sys, i, path);
            if (entry instanceof SyspathArchive) {
                SyspathArchive archive = (SyspathArchive) entry;
                ZipEntry ze = archive.getEntry(entryRes);
                if (ze != null) {
                  try {
            return new URL("jar:file:" + entry.__str__().toString() + "!/" + entryRes);
          } catch (MalformedURLException e) {
            throw new RuntimeException(e);
          }
                }
                continue;
            }
            if (!(entry instanceof PyUnicode)) {
                entry = entry.__str__();
            }
            String dir = sys.getPath(entry.toString());
            try {
        File resource = new File(dir, res);
        if (!resource.exists()) {
          continue;
        }
        return resource.toURI().toURL();
      } catch (MalformedURLException e) {
        throw new RuntimeException(e);
      }
        }
        return null;
    }


    static PyObject replacePathItem(PySystemState sys, int idx, PyList paths) {
        PyObject path = paths.__getitem__(idx);
        if (path instanceof SyspathArchive) {
            // already an archive
            return path;
        }

        try {
            // this has the side affect of adding the jar to the PackageManager during the
            // initialization of the SyspathArchive
            path = new SyspathArchive(sys.getPath(path.toString()));
        } catch (Exception e) {
            return path;
        }
        paths.__setitem__(idx, path);
        return path;
    }

    private File getFile(String dir, String name) {
        String accum = "";
        boolean first = true;
        for (StringTokenizer t = new StringTokenizer(name, "."); t
                .hasMoreTokens();) {
            String token = t.nextToken();
            if (!first) {
                accum += File.separator;
            }
            accum += token;
            first = false;
        }
        return new RelativeFile(dir, accum + ".class");
    }


}
TOP

Related Classes of org.python.core.SyspathJavaLoader

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.