Package honeycrm.server

Source Code of honeycrm.server.PluginStore$FooClassLoader

package honeycrm.server;

import honeycrm.client.misc.PluginClassBytecode;
import honeycrm.client.misc.PluginDescription;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.logging.Logger;

import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Query;

public class PluginStore {
  private static final Logger log = Logger.getLogger(PluginStore.class.getSimpleName());
  private static final DatastoreService db = DatastoreServiceFactory.getDatastoreService();
  private final FooClassLoader loader = new FooClassLoader();

  public FooClassLoader loadPlugin(final String pluginName) {
    // TODO do this only for the given plugin

    for (final Entity pluginBytecode : db.prepare(new Query(PluginClassBytecode.class.getSimpleName())).asIterable()) {
      final String className = String.valueOf(pluginBytecode.getProperty("className"));
      final Blob bytecode = (Blob) pluginBytecode.getProperty("bytecode");

      if (className.contains(".class") || className.contains("/")) {
        continue; // invalid class name
      }
     
      try {
        loader.defineClass(className, bytecode.getBytes());
      } catch (ClassFormatError e) {
        log.warning("Could not load class " + className + ". A ClassFormatError occured.");
      } catch (LinkageError e) {
        log.warning("LinkageError asdasd while trying to load " + className);
      }
    }
   
    return loader;
  }

  public void createPlugin(final PluginDescription plugin, final InputStream is) throws IOException {
    final ArrayList<Entity> entities = new ArrayList<Entity>();
    entities.add(getPluginDescriptionEntity(plugin));

    for (final Map.Entry<String, byte[]> entry : getBytecodeMapFromJarInputStream(is).entrySet()) {
      final Entity pluginBytecode = new Entity(PluginClassBytecode.class.getSimpleName());

      pluginBytecode.setProperty("className", entry.getKey());
      pluginBytecode.setProperty("bytecode", new Blob(entry.getValue()));

      entities.add(pluginBytecode);

      System.out.println("class name = " + entry.getKey());
    }

    db.put(entities);
  }

  public Entity getPluginDescriptionEntity(final PluginDescription plugin) {
    final Entity pluginDescription = new Entity(PluginDescription.class.getSimpleName());
    pluginDescription.setProperty("name", plugin.getName());
    pluginDescription.setProperty("description", plugin.getDescription());
    return pluginDescription;
  }

  public HashMap<String, byte[]> getBytecodeMapFromJarInputStream(final InputStream is) throws IOException {
    final HashMap<String, byte[]> map = new HashMap<String, byte[]>();
    final JarInputStream in = new JarInputStream(is);

    JarEntry e;
    while (null != (e = in.getNextJarEntry())) {
      final String sanatizedClassName = e.getName().replace("/", ".").replace(".class", "");

      final ByteArrayOutputStream out = new ByteArrayOutputStream();
      int bytecode;

      while ((bytecode = in.read()) != -1) {
        out.write(bytecode);
      }

      map.put(sanatizedClassName, out.toByteArray());
    }
    return map;
  }

  class FooClassLoader extends ClassLoader {
    public void defineClass(String className, byte[] bytecode) throws ClassFormatError {
      try {
        // if this class already has been loaded by this class loader Class.forName will not throw an Exception
        // otherwise it will and we know we have to define this class first.
        Class.forName(className, true, this);
      } catch (ClassNotFoundException e) {
        // define this class since it could not be resolved yet.
        super.defineClass(className, bytecode, 0, bytecode.length);
      }
    }
  }
}
TOP

Related Classes of honeycrm.server.PluginStore$FooClassLoader

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.