/*
* 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.parser;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import org.antlr.runtime.tree.CommonTree;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jactr.io.antlr3.builder.JACTRBuilder;
import org.jactr.io.antlr3.compiler.CompilationError;
import org.jactr.io.antlr3.misc.ASTSupport;
import org.jactr.io.participant.ASTParticipantRegistry;
import org.jactr.io.participant.IASTInjector;
import org.jactr.io.participant.IASTParticipant;
import org.jactr.io.participant.impl.BasicASTInjector;
import org.jactr.io.participant.impl.BasicASTParticipant;
/**
* @author developer
*/
public class DefaultParserImportDelegate implements IParserImportDelegate
{
static private final transient Log LOGGER = LogFactory
.getLog(DefaultParserImportDelegate.class);
private Set<URL> _importSources = new HashSet<URL>();
/**
* @see org.jactr.io.parser.IParserImportDelegate#importInto(org.antlr.runtime.tree.CommonTree,
* java.lang.String)
*/
public CommonTree importModuleInto(CommonTree modelDescriptor,
String moduleClassName, boolean importContents) throws Exception
{
if (!isValidClassName(moduleClassName))
throw new CompilationError("Could not find module class named "
+ moduleClassName, null);
/*
* first, find the reference or create it is it doesnt exist
*/
CommonTree moduleNode = new ASTSupport().createModuleTree(moduleClassName);
inject(moduleNode, modelDescriptor, importContents);
return moduleNode;
}
public CommonTree importExtensionInto(CommonTree modelDescriptor,
String extensionClassName, boolean importContents) throws Exception
{
if (!isValidClassName(extensionClassName))
throw new CompilationError("Could not find extension class named "
+ extensionClassName, null);
CommonTree extensionNode = new ASTSupport()
.createExtensionTree(extensionClassName);
inject(extensionNode, modelDescriptor, importContents);
return extensionNode;
}
private void inject(CommonTree classBasedNode, CommonTree modelDescriptor,
boolean importContents) throws Exception
{
String className = ASTSupport.getFirstDescendantWithType(classBasedNode,
JACTRBuilder.CLASS_SPEC).getText();
IASTParticipant participant = getASTParticipant(className);
// short term fix until new antlr can be tested
if (importContents)
{
IASTInjector injector = null;
if (participant != null)
injector = participant.getInjector(this);
else
// throw new CompilationWarning("Could not find IASTParticipant for "
// + className, null);
if (LOGGER.isDebugEnabled())
LOGGER.debug("Could not find IASTParticipant for " + className, null);
if (injector != null)
injector.inject(modelDescriptor, true);
else
// throw new CompilationWarning("Could not find IASTInjector for "
// + className, null);
if (LOGGER.isDebugEnabled())
LOGGER.debug("Could not find IASTInjector for " + className, null);
if (injector instanceof BasicASTInjector)
((BasicASTInjector) injector).injectParameters(classBasedNode);
}
}
/**
* return the IASTParticipant installed for this classname, if any
*
* @param moduleClassName
* @return
*/
protected IASTParticipant getASTParticipant(String moduleClassName)
{
return ASTParticipantRegistry.getParticipant(moduleClassName);
}
protected boolean isValidClassName(String moduleClassName)
{
try
{
getClass().getClassLoader().loadClass(moduleClassName);
}
catch (Exception e)
{
return false;
}
return true;
}
/**
* @see org.jactr.io.parser.IParserImportDelegate#importInto(org.antlr.runtime.tree.CommonTree,
* java.net.URL)
*/
public void importInto(CommonTree modelDescriptor, URL url,
boolean importBuffers)
{
if (!_importSources.contains(url))
{
BasicASTParticipant bap = new BasicASTParticipant(url);
bap.getInjector(this).inject(modelDescriptor, importBuffers);
_importSources.add(url);
}
}
/**
* checks classpath, absolute url, or relative url to base
*
* @param url
* @param baseURL
* @return
* @see org.jactr.io.parser.IParserImportDelegate#resolveURL(java.lang.String,
* java.net.URL)
*/
public URL resolveURL(String url, URL baseURL)
{
URL rtn = null;
try
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("Checking class path for " + url);
rtn = getClass().getClassLoader().getResource(url);
}
catch (Exception e)
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("Could not find resource " + url, e);
}
if (rtn == null)
try
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("Trying to make url of " + url);
rtn = new URL(url);
}
catch (Exception e)
{
if (LOGGER.isDebugEnabled())
LOGGER.debug(url + " is not a valid url ", e);
}
if (rtn == null)
try
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("Trying to resolve relative to " + baseURL);
rtn = baseURL.toURI().resolve(url).toURL();
}
catch (Exception e)
{
if (LOGGER.isDebugEnabled())
LOGGER.debug("Failed to resolve relative to " + baseURL, e);
}
return rtn;
}
public Set<URL> getImportSources()
{
return _importSources;
}
public void reset()
{
_importSources.clear();
}
}