org.xmlvm.proc.XmlvmProcessImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dragome-bytecode-js-compiler Show documentation
Show all versions of dragome-bytecode-js-compiler Show documentation
Dragome SDK module: bytecode to javascript compiler
/* Copyright (c) 2002-2011 by XMLVM.org
*
* Project Info: http://www.xmlvm.org
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
package org.xmlvm.proc;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.xmlvm.Log;
import org.xmlvm.main.Arguments;
import org.xmlvm.proc.out.OptimizationOutputProcess;
import org.xmlvm.proc.out.XmlvmToXmlvmProcess;
/**
* A collection of possible process IDs.
*/
enum XmlvmProcessId
{
XMLVM_JVM("xmlvmjvm"), XMLVM_CLR("xmlvmclr"), XMLVM_CLR_DFA("xmlvmclrdfa"), CLASS("class"), EXE("exe"), JS("js"), JAVA("java"), OBJC("objc"), CPP("cpp"), PYTHON("python"), IPHONE("iphone"), QOOXDOO("qooxdoo");
String name;
private XmlvmProcessId(String name)
{
this.name= name;
}
public String toString()
{
return name;
}
}
/**
* Common implementation for all XMLVM Processes. Actual processes extend this
* class.
*/
public abstract class XmlvmProcessImpl implements XmlvmProcess
{
/** A tag used for logging. */
private static final String TAG= XmlvmProcessImpl.class.getSimpleName();
/** The list of process instances that get executed BEFORE this process. */
private List preprocesses= new ArrayList();
/** The list of process instances that get executed AFTER this process. */
private Set postProcesses= new HashSet();
/** This list contains all the supported input processes. */
protected List> supportedInputs= new ArrayList>();
protected Arguments arguments;
protected boolean isProcessed= false;
/** Whether this process is the target process. */
protected boolean isTargetProcess= false;
public XmlvmProcessImpl(Arguments arguments)
{
// Log.debug("Instantiated: " + this.getClass().getName());
this.arguments= arguments;
}
public boolean postProcess()
{
return true;
}
public List> getSupportedInputs()
{
return supportedInputs;
}
@SuppressWarnings("unchecked")
protected void addSupportedInput(Class> inputProcessClass)
{
try
{
supportedInputs.add((Class) inputProcessClass);
}
catch (ClassCastException ex)
{
ex.printStackTrace();
Log.error("You tried to add a supported input that is not of the same type as the " + "generic type you've specified in the process.");
}
}
/**
* Adds all processes that emit XMLVM as potential input processes.
*/
protected void addAllXmlvmEmittingProcessesAsInput()
{
if (!arguments.option_use_jvm())
{
addSupportedInput(OptimizationOutputProcess.class);
}
else
{
// addSupportedInput(ClassToXmlvmProcess.class);
}
// addSupportedInput(ExeToXmlvmProcess.class);
addSupportedInput(XmlvmToXmlvmProcess.class);
}
public List createInputInstances()
{
List result= new ArrayList();
for (Class supportedClass : getSupportedInputs())
{
try
{
XmlvmProcess process= (XmlvmProcess) supportedClass.getConstructor(Arguments.class).newInstance(arguments);
result.add(process);
// Add this process to the list of pre-processes.
addPreprocess(process);
}
catch (InstantiationException e)
{
e.printStackTrace();
return null;
}
catch (IllegalAccessException e)
{
e.printStackTrace();
return null;
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (SecurityException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
e.printStackTrace();
}
catch (NoSuchMethodException e)
{
// This is ok. InputProcesses e.g. don't have such a
// constructor, so we don't want to create an instance.
Log.debug(TAG, "Not creating input instance of: " + supportedClass.getName());
}
}
return result;
}
public boolean supportsAsInput(XmlvmProcess process)
{
for (Class supportedClass : getSupportedInputs())
{
if (isOfType(process.getClass(), supportedClass))
{
return true;
}
}
return false;
}
/**
* Returns whether this process is a sub-class of a direct or indirect class
* of the type given.
*/
public boolean isOfSuperType(Class> type)
{
return isOfType(this.getClass(), type);
}
/**
* Returns true, if 'b' is either a direct or indirect superclass of 'a'.
*/
private static boolean isOfType(Class> a, Class> b)
{
if (a == null)
{
return false;
}
if (a.equals(b))
{
return true;
}
else
{
return isOfType(a.getSuperclass(), b);
}
}
public void addPreprocess(XmlvmProcess xmlvmProcess)
{
Log.debug("Adding preprocess " + xmlvmProcess.getClass().getName() + " to process " + this.getClass().getName());
preprocesses.add(xmlvmProcess);
xmlvmProcess.addPostProcess(this);
}
public void addPostProcess(XmlvmProcess xmlvmProcess)
{
postProcesses.add(xmlvmProcess);
}
public boolean forwardOrProcessPhase1(BundlePhase1 resources)
{
for (XmlvmProcess process : preprocesses)
{
if (!isProcessPreOfCorrectType(process))
{
return false;
}
if (process.isActive())
{
process.forwardOrProcessPhase1(resources);
}
}
return processPhase1(resources);
}
public boolean forwardOrProcessPhase2(BundlePhase2 resources)
{
for (XmlvmProcess process : preprocesses)
{
if (!isProcessPreOfCorrectType(process))
{
return false;
}
if (process.isActive())
{
process.forwardOrProcessPhase2(resources);
}
}
return processPhase2(resources);
}
public boolean postProcessPreProcesses()
{
for (XmlvmProcess process : preprocesses)
{
if (process.isActive())
{
if (!process.postProcessPreProcesses())
{
return false;
}
}
}
return postProcess();
}
public boolean isActive()
{
// A process is active only when at least one of his preprocesses is
// active.
for (XmlvmProcess preprocess : preprocesses)
{
if (preprocess.isActive())
{
return true;
}
}
return false;
}
public boolean hasCachedOutput(String inputResourceName, long lastModified)
{
return false;
}
public boolean isProcessingRequired(String inputResourceName, long lastModified)
{
// If we have it caches, we don't need to process.
if (hasCachedOutput(inputResourceName, lastModified))
{
return false;
}
// If this process doesn't have it cached and there are not
// post-processes, this process needs to process the resource.
if (postProcesses.size() == 0)
{
return true;
}
// If this process doesn't have it cached and one of the post processes
// doesn't, then this process needs to process.
for (XmlvmProcess postProcess : postProcesses)
{
if (postProcess.isProcessingRequired(inputResourceName, lastModified))
{
return true;
}
}
// If this process doesn't have the resource cached, and we have
// post-processes and all post-processes have it cached, then we don't
// have to process the resource.
return false;
}
public void setIsTargetProcess(boolean isTargetProcess)
{
this.isTargetProcess= isTargetProcess;
}
private boolean isProcessPreOfCorrectType(XmlvmProcess process)
{
// We test whether the pre-process type is a sub-type of the given
// generic type of the process.
try
{
process.toString();
return true;
}
catch (ClassCastException ex)
{
Log.error("A preprocess is not of the given generic type: " + process.getClass().getName());
return false;
}
}
}