
org.codehaus.gant.AbstractInclude.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gant_groovy1.8 Show documentation
Show all versions of gant_groovy1.8 Show documentation
A framework for programming dependencies.
The newest version!
// Gant -- A Groovy way of scripting Ant tasks.
//
// Copyright © 2006–2010, 2013 Russel Winder
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing permissions and limitations under the
// License.
package org.codehaus.gant
/**
* This class is for code sharing between classes doing include activity.
*
* @see IncludeTargets
* @see IncludeTool
* @author Russel Winder
*/
abstract class AbstractInclude {
/**
* The GantBinding
for this run.
*/
protected Binding binding
/**
* The list of loaded classes.
*/
protected final List> loadedClasses = []
/**
* When using the ** * operator there is a need to not instantiate the class immediately so information
* has to be buffered. This variable holds a reference to the class ready for instantiation once all the
* constructor parameters are known.
*/
protected Class> pendingClass = null
/**
* Constructor.
*
* @param binding The GantBinding
to associate with.
*/
protected AbstractInclude(final GantBinding binding) { this.binding = binding }
/**
* Implementation of the << operator taking a Class
parameter.
*
* @param theClass The Class
to load and instantiate.
* @return The includer object to allow for << chaining.
*/
public abstract leftShift(Class> theClass)
/**
* Implementation of the << operator taking a File
parameter.
*
* @param file The File
to load, compile, and instantiate.
* @return The includer object to allow for << chaining.
*/
public abstract leftShift(File file)
/**
* Implementation of the << operator taking a String
parameter.
*
* @param s The String
to compile and instantiate.
* @return The includer object to allow for << chaining.
*/
public abstract leftShift(String s)
/**
* Implementation of the << operator taking a List
parameter.
*
* @param l The List
of things to load (, compile) and instantiate.
* @return The includer object to allow for << chaining.
*/
public leftShift(final List> l) { l.each { item -> this << item } ; this }
/**
* Implementation of the << operator taking a Object
parameter. This always throws an
* exception, it is here to avoid using a type other than Class
, File
,
* String
or List
(of Class
, File
, or
* String
).
*
* @param theClass The Class
to load and instantiate.
* @throw RuntimeException always.
*/
public leftShift(final Object o) { throw new RuntimeException('Ignoring include of type ' + o.class.name) }
/**
* Implementation of the ** operator taking a Class
parameter.
*
* @param theClass The Class
to load and instantiate.
* @return The includer object to allow for * operator.
*/
public power(final Class> theClass) { pendingClass = theClass ; this }
/**
* Implementation of the * operator taking a Map
parameter. This operator only makes
* sense immediately after a ** operator, since only then is there a Class
to instantiate.
*
* @param keywordParameter The Map
of parameters to the constructor.
* @return The includer object to allow for ** * operator chaining.
*/
public abstract multiply(Map keywordParameters)
/**
* Create an instance of a class included using the << operator.
*
* @param theClass The Class
to instantiate.
* @throws NoSuchMethodException if the required constructor cannot be found.
*/
protected createInstance(Class> theClass) {
if (Script.isAssignableFrom(theClass)) {
// We need to ensure that the script runs so that it populates the binding.
def script = theClass.newInstance()
script.binding = binding
script.run()
return script
}
else {
try { return theClass.getConstructor(GantBinding).newInstance([ binding ] as Object[]) }
catch (NoSuchMethodException nsme) { throw new RuntimeException('Could not initialize ' + theClass.name, nsme) }
}
null // Be explicit about the return value to keep IntelliJ IDEA's inspectors happy.
}
/**
* Create an instance of a class included with the ** * operator.
*
* @param theClass The Class
to instantiate.
* @param keywordParameter The Map
containing the parameters for construction.
* @throws NoSuchMethodException if the required constructor cannot be found.
*/
protected createInstance(Class> theClass, Map,?> keywordParameters) {
try { return theClass.getConstructor(GantBinding, Map).newInstance([ binding, keywordParameters ] as Object[]) }
catch (NoSuchMethodException nsme) { throw new RuntimeException('Could not initialize ' + theClass.name, nsme) }
}
/**
* Make an attempt to evaluate a file, possible as a class.
*
* @param file The File
to read.
* @param asClass Specify whether the file is to be treated as a class.
* @return The class read or null if the file is not to be treated as a class.
*/
private attemptEvaluate(File file, boolean asClass) {
if (asClass) { return binding.groovyShell.evaluate(file.text + " ; return ${file.name.replace('.groovy', '')}") }
//
// GANT-58 raised the issue of reporting errors correctly. This means catching and processing
// exceptions so as to capture the original location of the error.
//
try { binding.groovyShell.evaluate(file) }
catch (Exception e) {
def errorSource = ''
for (stackEntry in e.stackTrace) {
if ((stackEntry.fileName == file.name) && (stackEntry.lineNumber != -1)) {
errorSource += file.absolutePath + ', line ' + stackEntry.lineNumber + ' -- '
}
}
throw new RuntimeException(errorSource + e.toString(), e)
}
null
}
/**
* Read a file which may or may not be a class, searching the Gant library path if the file cannot
* be found at first.
*
* @param file The File
to read.
* @param asClass Specify whether this is supposed to be a class.
* @throws FileNotFoundException when the file cannot be found.
*/
protected readFile(File file, boolean asClass = false) {
try { return attemptEvaluate(file, asClass) }
catch (FileNotFoundException fnfe) {
for (directory in binding.gantLib) {
def possible = new File((String)directory, file.name)
if (possible.isFile() && possible.canRead()) { return attemptEvaluate(possible, asClass) }
}
throw fnfe
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy