All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xmlvm.proc.XmlvmProcessImpl Maven / Gradle / Ivy

There is a newer version: 0.96-beta4
Show newest version
/* 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;
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy