package org.visico.neighborhoodpss.plugin;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.visico.neighborhoodpss.domain.project.ProjectDTO;
import org.visico.neighborhoodpss.plugin.domain.BuildingProperty;
import org.visico.neighborhoodpss.plugin.domain.Plugin;
public class IndicatorManager {
HashMap<String, IndicatorPlugin> plugins = new HashMap<String, IndicatorPlugin>();
ProjectDTO project = null;
public IndicatorManager(ProjectDTO project) {
this.project = project;
}
@SuppressWarnings("unchecked")
public void initIndicatorByFileName(String xmlInfoName, String pathToIndicator, ClassLoader classLoader) throws JAXBException, MalformedURLException, ClassNotFoundException, InstantiationException, IllegalAccessException, FileNotFoundException {
System.out.println("IndicatorManager:initIndicatorByFileName - Path to indicator: " + pathToIndicator);
System.out.println("IndicatorManager:initIndicatorByFileName - XML file name: " + xmlInfoName);
// read Indicator Plugin information from xml
File file= new File(xmlInfoName);
JAXBContext jaxbContext = JAXBContext.newInstance(Plugin.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Plugin indPlugInfo = (Plugin) jaxbUnmarshaller.unmarshal(file);
// initialize class
File jarfile = new File(pathToIndicator + indPlugInfo.getJar());
System.out.println("IndicatorManager:initIndicatorByFileName - Will load file from " + pathToIndicator + indPlugInfo.getJar());
URL jarfileurl = new URL("jar", "","file:" + jarfile.getAbsolutePath()+"!/");
System.out.println("IndicatorManager:initIndicatorByFileName- Tried to load file from " + jarfileurl.getPath());
URLClassLoader cl = URLClassLoader.newInstance(new URL[]{jarfileurl}, classLoader);
Class<IndicatorPlugin> indPlugClass = (Class<IndicatorPlugin>) cl.loadClass(indPlugInfo.getClassName());
IndicatorPlugin indPlug = indPlugClass.newInstance();
indPlug.setPluginInfo(indPlugInfo);
// add to map
plugins.put(indPlugInfo.getClassName(), indPlug);
}
@SuppressWarnings("unchecked")
public void initIndicatorByIndicatorName(String indicatorName, String pathToIndicator, ClassLoader parentCL) throws JAXBException, MalformedURLException, ClassNotFoundException, InstantiationException, IllegalAccessException, FileNotFoundException {
System.out.println("IndicatorManager:initIndicatorByIndicatorName - Path to indicator: " + pathToIndicator);
for (Plugin p : availableIndicators(pathToIndicator)) {
if (p.getName().equals(indicatorName)) {
// initialize class
System.out.println("Will load file from " + pathToIndicator + "/" + p.getJar());
JarFile jarfile = new JarFile(pathToIndicator);
Enumeration e = jarfile.entries();
URL[] urls = { new URL("jar:file" + pathToIndicator +"!/") };
URLClassLoader cl = URLClassLoader.newInstance(urls);
while (e.hasMoreElements()) {
JarEntry je = (JarEntry) e.nextElement();
if(je.isDirectory() || !je.getName().endsWith(".class")){
continue;
}
// -6 because of .class
String className = je.getName().substring(0,je.getName().length()-6);
className = className.replace('/', '.');
Class c = cl.loadClass(className);
}
Class<? extends IndicatorPlugin> indPlugClass = IndicatorPlugin cl..getClass();
IndicatorPlugin indPlug = indPlugClass.newInstance();
indPlug.setPluginInfo(p);
// add to map
plugins.put(p.getClassName(), indPlug);
}
}
}
public void removeIndicator(Plugin indPlugInfo)
{
plugins.remove(indPlugInfo);
}
public ArrayList<Plugin> availableIndicators(String pathToIndicator)
{
ArrayList<Plugin> indicators = new ArrayList<Plugin>();
System.out.println("IndicatorManager:availableIndicators - Path for indicator plugins " + pathToIndicator );
File folder = new File(pathToIndicator);
for (final File entry : folder.listFiles())
{
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Plugin.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Plugin indPlugInfo = (Plugin) jaxbUnmarshaller.unmarshal(entry);
indicators.add(indPlugInfo);
}
catch(JAXBException ex)
{
System.out.println("IndicatorManager:availableIndicators - File " + entry.getName() + " is not a valid xml indicator file!");
}
}
return indicators;
}
public HashMap<String, IndicatorPlugin> getPlugins() {
return plugins;
}
public void unregisterIndicatorByIndicatorName(String indicatorName,
String pathToIndicators) {
for (Plugin p : availableIndicators(pathToIndicators)) {
if (p.getName().equals(indicatorName)) {
// remove from map
plugins.remove(p.getClassName());
}
}
}
public Set<String> getBuildingDataTypes() {
Set<String> buildingData = new HashSet<String>();
for (String name : plugins.keySet())
{
IndicatorPlugin p = plugins.get(name);
Plugin pluginInfo = p.getPluginInfo();
for (BuildingProperty property : pluginInfo.getData().getBuildingProperty())
{
buildingData.add(property.getName());
}
}
return buildingData;
}
}