/*
* Created on Mar 19, 2007 Copyright (C) 2001-6, Anthony Harrison anh23@pitt.edu
* (jactr.org) This library 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., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.jactr.io.compiler;
import java.util.Arrays;
import java.util.Collection;
import org.antlr.runtime.tree.CommonTree;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jactr.core.extensions.IExtension;
import org.jactr.core.module.IModule;
import org.jactr.core.production.action.IAction;
import org.jactr.core.production.condition.ICondition;
import org.jactr.io.antlr3.builder.JACTRBuilder;
import org.jactr.io.antlr3.compiler.CompilationError;
import org.jactr.io.antlr3.compiler.CompilationWarning;
import org.jactr.io.antlr3.misc.ASTSupport;
import org.jactr.io.antlr3.misc.CommonTreeException;
/**
* verifies that all class_spec references are valid. specifically MODULE,
* EXTENSION, PROXY_ACTION, PROXY_CONDITION
*
* @author developer
*/
public class ClassVerifyingUnitCompiler implements IUnitCompiler
{
/**
* logger definition
*/
static private final Log LOGGER = LogFactory
.getLog(ClassVerifyingUnitCompiler.class);
/**
* @see org.jactr.io.compiler.IUnitCompiler#compile(org.antlr.runtime.tree.CommonTree,
* java.util.Collection, java.util.Collection)
*/
public void compile(CommonTree node, Collection<Exception> info, Collection<Exception> warnings,
Collection<Exception> errors)
{
CommonTree classSpecNode = ASTSupport.getFirstDescendantWithType(node,
JACTRBuilder.CLASS_SPEC);
if (classSpecNode == null)
errors.add(new CompilationError("Could not find class spec child of "
+ node, node));
else
try
{
Class type = Object.class;
switch (node.getType())
{
case JACTRBuilder.MODULE:
type = IModule.class;
break;
case JACTRBuilder.EXTENSION:
type = IExtension.class;
break;
case JACTRBuilder.PROXY_ACTION:
type = IAction.class;
break;
case JACTRBuilder.PROXY_CONDITION:
type = ICondition.class;
break;
}
tryToLoadClass(classSpecNode, classSpecNode.getText(), type);
}
catch (Exception e)
{
String message = "Could not load " + classSpecNode.getText() + " for "
+ node;
if (LOGGER.isDebugEnabled()) LOGGER.debug(message, e);
if (!(e instanceof CommonTreeException))
errors.add(new CompilationError(message, classSpecNode, e));
else if (e instanceof CompilationWarning)
warnings.add(e);
else
errors.add(e);
}
}
/**
* will throw an exception if it doesn't work
*
* @param className
*/
protected void tryToLoadClass(CommonTree classSpecNode, String className,
Class ofType) throws Exception
{
Class loadedClass = getClass().getClassLoader().loadClass(className);
if (ofType != null)
if (!ofType.isAssignableFrom(loadedClass))
throw new RuntimeException("Loaded class " + loadedClass
+ " does not match required type " + ofType.getName());
}
/**
* @see org.jactr.io.compiler.IUnitCompiler#getRelevantTypes()
*/
public Collection<Integer> getRelevantTypes()
{
Integer[] types = { JACTRBuilder.MODULE, JACTRBuilder.EXTENSION,
JACTRBuilder.PROXY_ACTION, JACTRBuilder.PROXY_CONDITION };
return Arrays.asList(types);
}
/**
* @see org.jactr.io.compiler.IUnitCompiler#postCompile()
*/
public void postCompile()
{
}
/**
* @see org.jactr.io.compiler.IUnitCompiler#preCompile()
*/
public void preCompile()
{
}
}