blob: fe59c54655b4e27eb312c8b27eb8ce7575f94911 [file] [log] [blame]
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.execution;
import java.io.File;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.List;
import java.util.ArrayList;
import org.apache.ant.antcore.config.AntConfig;
import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.event.BuildListener;
import org.apache.ant.common.event.MessageLevel;
import org.apache.ant.common.model.BuildElement;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.model.Target;
import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.service.DataService;
import org.apache.ant.common.service.EventService;
import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.service.FileService;
import org.apache.ant.common.service.InputService;
import org.apache.ant.common.service.MagicProperties;
import org.apache.ant.common.util.DemuxOutputReceiver;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.FileUtils;
import org.apache.ant.init.InitConfig;
/**
* An Frame maintains the state of a project during an execution. The Frame
* contains the data values set by Ant tasks as they are executed, including
* task definitions, property values, etc.
*
* @author Conor MacNeill
* @created 14 January 2002
*/
public class Frame implements DemuxOutputReceiver {
/** the base dir of the project */
private File baseDir;
/** The Project that this execution frame is processing */
private Project project = null;
/** The referenced frames corresponding to the referenced projects */
private Map referencedFrames = new HashMap();
/**
* The property overrides for the referenced frames. This map is indexed
* by the reference names of the frame. Each entry is another Map of
* property values indexed by their relative name.
*/
private Map overrides = new HashMap();
/**
* The context of this execution. This contains all data object's created
* by tasks that have been executed
*/
private Map dataValues = new HashMap();
/**
* Ant's initialization configuration with information on the location of
* Ant and its libraries.
*/
private InitConfig initConfig;
/** BuildEvent support used to fire events and manage listeners */
private BuildEventSupport eventSupport = new BuildEventSupport();
/**
* The services map is a map of service interface classes to instances
* which provide the service.
*/
private Map services = new HashMap();
/**
* The configuration to be used in this execution of Ant. It is formed
* from the system, user and any runtime configs.
*/
private AntConfig config;
/**
* The Data Service instance used by the frame for data management
*/
private DataService dataService;
/** The execution file service instance */
private FileService fileService;
/**
* the Component Manager used to manage the importing of library
* components from the Ant libraries
*/
private ComponentManager componentManager;
/** The core's execution Service */
private CoreExecService execService;
/**
* Create an Execution Frame for the given project
*
* @param config the user config to use for this execution of Ant
* @param initConfig Ant's initialisation config
* @exception ExecutionException if a component of the library cannot be
* imported
*/
protected Frame(InitConfig initConfig,
AntConfig config) throws ExecutionException {
this.config = config;
this.initConfig = initConfig;
}
/**
* Replace ${} style constructions in the given value with the string
* value of the corresponding data values in the frame
*
* @param value the string to be scanned for property references.
* @return the string with all property references replaced
* @exception ExecutionException if any of the properties do not exist
*/
protected String replacePropertyRefs(String value)
throws ExecutionException {
return dataService.replacePropertyRefs(value);
}
/**
* Sets the Project of the Frame
*
* @param project The new Project value
* @exception ExecutionException if any required sub-frames cannot be
* created and configured
*/
protected void setProject(Project project) throws ExecutionException {
this.project = project;
referencedFrames.clear();
}
/**
* get the name of the project associated with this frame.
*
* @return the project's name
*/
protected String getProjectName() {
if (project != null) {
return project.getName();
}
return null;
}
/**
* Set a value in this frame or any of its imported frames.
*
* @param name the name of the value
* @param value the actual value
* @param mutable if true, existing values can be changed
* @exception ExecutionException if the value name is invalid
*/
protected void setDataValue(String name, Object value, boolean mutable)
throws ExecutionException {
Frame frame = getContainingFrame(name);
if (frame == null) {
setOverrideProperty(name, value, mutable);
return;
}
if (frame == this) {
if (dataValues.containsKey(name) && !mutable) {
log("Ignoring oveeride for data value " + name,
MessageLevel.MSG_VERBOSE);
} else {
dataValues.put(name, value);
}
} else {
frame.setDataValue(getNameInFrame(name), value, mutable);
}
}
/**
* When a frame has not yet been referenced, this method is used
* to set the initial properties for the frame when it is introduced.
*
* @param name the name of the value
* @param value the actual value
* @param mutable if true, existing values can be changed
* @exception ExecutionException if attempting to override a property in
* the current frame.
*/
private void setOverrideProperty(String name, Object value,
boolean mutable)
throws ExecutionException {
int refIndex = name.indexOf(Project.REF_DELIMITER);
if (refIndex == -1) {
throw new ExecutionException("Property overrides can only be set"
+ " for properties in referenced projects - not "
+ name);
}
String firstFrameName = name.substring(0, refIndex);
String relativeName
= name.substring(refIndex + Project.REF_DELIMITER.length());
Map frameOverrides = (Map) overrides.get(firstFrameName);
if (frameOverrides == null) {
frameOverrides = new HashMap();
overrides.put(firstFrameName, frameOverrides);
}
if (mutable || !frameOverrides.containsKey(relativeName)) {
frameOverrides.put(relativeName, value);
}
}
/**
* Get a value which exists in the frame property overrides awaiting
* the frame to be introduced.
*
* @param name the name of the value
* @return the value of the property or null if the property does not
* exist.
* @exception ExecutionException if attempting to get an override in
* the current frame.
*/
private Object getOverrideProperty(String name) throws ExecutionException {
int refIndex = name.indexOf(Project.REF_DELIMITER);
if (refIndex == -1) {
throw new ExecutionException("Property overrides can only be"
+ " returned for properties in referenced projects - not "
+ name);
}
String firstFrameName = name.substring(0, refIndex);
String relativeName
= name.substring(refIndex + Project.REF_DELIMITER.length());
Map frameOverrides = (Map) overrides.get(firstFrameName);
if (frameOverrides == null) {
return null;
}
return frameOverrides.get(relativeName);
}
/**
* Get a value which exists in the frame property overrides awaiting
* the frame to be introduced.
*
* @param name the name of the value
* @return the value of the property or null if the property does not
* exist.
* @exception ExecutionException if attempting to check an override in
* the current frame.
*/
private boolean isOverrideSet(String name) throws ExecutionException {
int refIndex = name.indexOf(Project.REF_DELIMITER);
if (refIndex == -1) {
throw new ExecutionException("Property overrides can only be"
+ " returned for properties in referenced projects - not "
+ name);
}
String firstFrameName = name.substring(0, refIndex);
String relativeName
= name.substring(refIndex + Project.REF_DELIMITER.length());
Map frameOverrides = (Map) overrides.get(firstFrameName);
if (frameOverrides == null) {
return false;
}
return frameOverrides.containsKey(relativeName);
}
/**
* Set the initial properties to be used when the frame starts execution
*
* @param properties a Map of named properties which may in fact be any
* object
* @exception ExecutionException if the properties cannot be set
*/
protected void setInitialProperties(Map properties)
throws ExecutionException {
if (properties != null) {
addProperties(properties);
}
// add in system properties
addProperties(System.getProperties());
}
/**
* Set the values of various magic properties
*
* @exception ExecutionException if the properties cannot be set
*/
protected void setMagicProperties() throws ExecutionException {
URL antHomeURL = initConfig.getAntHome();
String antHomeString = null;
if (antHomeURL.getProtocol().equals("file")) {
File antHome = new File(antHomeURL.getFile());
antHomeString = antHome.getAbsolutePath();
} else {
antHomeString = antHomeURL.toString();
}
setDataValue(MagicProperties.ANT_HOME, antHomeString, true);
}
/**
* Get a definition from a referenced frame
*
* @param definitionName the name of the definition relative to this frame
* @return the appropriate import info object from the referenced frame's
* imports
* @exception ExecutionException if the referenced definition cannot be
* found
*/
protected ImportInfo getReferencedDefinition(String definitionName)
throws ExecutionException {
Frame containingFrame = getContainingFrame(definitionName);
String localName = getNameInFrame(definitionName);
if (containingFrame == null) {
throw new ExecutionException("There is no project corresponding "
+ "to the name \"" + definitionName + "\"");
}
if (containingFrame == this) {
return componentManager.getDefinition(localName);
} else {
return containingFrame.getReferencedDefinition(localName);
}
}
/**
* Gets the project model this frame is working with
*
* @return the project model
*/
protected Project getProject() {
return project;
}
/**
* Get all the properties from the frame and any references frames. This
* is an expensive operation since it must clone all of the property
* stores in all frames
*
* @return a Map containing the frames properties indexed by their full
* name.
*/
protected Map getAllProperties() {
Map allProperties = new HashMap(dataValues);
Iterator i = referencedFrames.keySet().iterator();
while (i.hasNext()) {
String refName = (String) i.next();
Frame refFrame = getReferencedFrame(refName);
Map refProperties = refFrame.getAllProperties();
Iterator j = refProperties.keySet().iterator();
while (j.hasNext()) {
String name = (String) j.next();
Object value = refProperties.get(name);
allProperties.put(refName + Project.REF_DELIMITER + name,
value);
}
}
return allProperties;
}
/**
* Get the Ant initialization configuration for this frame.
*
* @return Ant's initialization configuration
*/
protected InitConfig getInitConfig() {
return initConfig;
}
/**
* Get the config instance being used by this frame.
*
* @return the config associated with this frame.
*/
protected AntConfig getConfig() {
return config;
}
/**
* Get the core's implementation of the given service interface.
*
* @param serviceInterfaceClass the service interface for which an
* implementation is require
* @return the core's implementation of the service interface
* @exception ExecutionException if the core does not provide an
* implementatin of the requested interface
*/
protected Object getCoreService(Class serviceInterfaceClass)
throws ExecutionException {
Object service = services.get(serviceInterfaceClass);
if (service == null) {
throw new ExecutionException("No service of interface class "
+ serviceInterfaceClass);
}
return service;
}
/**
* Get the EventSupport instance for this frame. This tracks the build
* listeners on this frame
*
* @return the EventSupport instance
*/
protected BuildEventSupport getEventSupport() {
return eventSupport;
}
/**
* Gets the baseDir of the Frame
*
* @return the baseDir value
*/
protected File getBaseDir() {
return baseDir;
}
/**
* Get a referenced frame by its reference name
*
* @param referenceName the name under which the frame was imported.
* @return the Frame asscociated with the given reference name or null if
* there is no such project.
*/
protected Frame getReferencedFrame(String referenceName) {
return (Frame) referencedFrames.get(referenceName);
}
/**
* Get the frames representing referenced projects.
*
* @return an iterator which returns the referenced ExeuctionFrames..
*/
protected Iterator getReferencedFrames() {
return referencedFrames.values().iterator();
}
/**
* Get the name of an object in its frame
*
* @param fullname The name of the object
* @return the name of the object within its containing frame
*/
protected String getNameInFrame(String fullname) {
int index = fullname.lastIndexOf(Project.REF_DELIMITER);
if (index == -1) {
return fullname;
}
return fullname.substring(index + Project.REF_DELIMITER.length());
}
/**
* Get a value from this frame or any imported frame
*
* @param name the name of the data value - may contain reference
* delimiters
* @return the data value fetched from the appropriate frame
* @exception ExecutionException if the value is not defined
*/
protected Object getDataValue(String name) throws ExecutionException {
Frame frame = getContainingFrame(name);
if (frame == null) {
return getOverrideProperty(name);
}
if (frame == this) {
return dataValues.get(name);
} else {
return frame.getDataValue(getNameInFrame(name));
}
}
/**
* Indicate if a data value has been set
*
* @param name the name of the data value - may contain reference
* delimiters
* @return true if the value exists
* @exception ExecutionException if the containing frame for the value
* does not exist
*/
protected boolean isDataValueSet(String name) throws ExecutionException {
Frame frame = getContainingFrame(name);
if (frame == null) {
return isOverrideSet(name);
}
if (frame == this) {
return dataValues.containsKey(name);
} else {
return frame.isDataValueSet(getNameInFrame(name));
}
}
/**
* Get the execution frame which contains, directly, the named element
* where the name is relative to this frame
*
* @param elementName The name of the element
* @return the execution frame for the project that contains the given
* target
*/
protected Frame getContainingFrame(String elementName) {
int index = elementName.lastIndexOf(Project.REF_DELIMITER);
if (index == -1) {
return this;
}
Frame currentFrame = this;
String relativeName = elementName.substring(0, index);
StringTokenizer tokenizer
= new StringTokenizer(relativeName, Project.REF_DELIMITER);
while (tokenizer.hasMoreTokens()) {
String refName = tokenizer.nextToken();
currentFrame = currentFrame.getReferencedFrame(refName);
if (currentFrame == null) {
return null;
}
}
return currentFrame;
}
/**
* Add a collection of properties to this frame
*
* @param properties the collection of property values, indexed by their
* names
* @exception ExecutionException if the frame cannot be created.
*/
protected void addProperties(Map properties) throws ExecutionException {
for (Iterator i = properties.keySet().iterator(); i.hasNext();) {
String name = (String) i.next();
Object value = properties.get(name);
setDataValue(name, value, false);
}
}
/**
* Create a project reference.
*
* @param name the name under which the project will be
* referenced.
* @param project the project model.
* @param initialData the project's initial data load.
* @exception ExecutionException if the project cannot be referenced.
*/
protected void createProjectReference(String name, Project project,
Map initialData)
throws ExecutionException {
Frame referencedFrame = createFrame(project);
if (initialData != null) {
referencedFrame.setInitialProperties(initialData);
}
// does the frame have any overrides?
Map initialProperties = (Map) overrides.get(name);
if (initialProperties != null) {
referencedFrame.setInitialProperties(initialProperties);
overrides.remove(name);
}
referencedFrames.put(name, referencedFrame);
referencedFrame.initialize();
}
/**
* Create a new frame for a given project
*
* @param project the project model the frame will deal with
* @return an Frame ready to build the project
* @exception ExecutionException if the frame cannot be created.
*/
protected Frame createFrame(Project project)
throws ExecutionException {
Frame newFrame
= new Frame(initConfig, config);
newFrame.setProject(project);
for (Iterator j = eventSupport.getListeners(); j.hasNext();) {
BuildListener listener = (BuildListener) j.next();
newFrame.addBuildListener(listener);
}
return newFrame;
}
/**
* Log a message as a build event
*
* @param message the message to be logged
* @param level the priority level of the message
*/
protected void log(String message, int level) {
eventSupport.fireMessageLogged(project, message, level);
}
/**
* Add a build listener to this execution frame
*
* @param listener the listener to be added to the frame
*/
protected void addBuildListener(BuildListener listener) {
for (Iterator i = getReferencedFrames(); i.hasNext();) {
Frame referencedFrame = (Frame) i.next();
referencedFrame.addBuildListener(listener);
}
eventSupport.addBuildListener(listener);
}
/**
* Remove a build listener from the execution
*
* @param listener the listener to be removed
*/
protected void removeBuildListener(BuildListener listener) {
for (Iterator i = getReferencedFrames(); i.hasNext();) {
Frame subFrame = (Frame) i.next();
subFrame.removeBuildListener(listener);
}
eventSupport.removeBuildListener(listener);
}
/**
* Run the given list of targets
*
* @param targets a list of target names which are to be evaluated
* @exception ExecutionException if there is a problem in the build
*/
protected void runBuild(List targets) throws ExecutionException {
initialize();
if (targets.isEmpty()) {
// we just execute the default target if any
String defaultTarget = project.getDefaultTarget();
if (defaultTarget != null) {
log("Executing default target: " + defaultTarget,
MessageLevel.MSG_DEBUG);
executeTarget(defaultTarget);
}
} else {
for (Iterator i = targets.iterator(); i.hasNext();) {
String targetName = (String) i.next();
log("Executing target: " + targetName, MessageLevel.MSG_DEBUG);
executeTarget(targetName);
}
}
}
/**
* Given a fully qualified target name, this method returns the fully
* qualified name of the project
*
* @param fullTargetName the full qualified target name
* @return the full name of the containing project
*/
private String getFullProjectName(String fullTargetName) {
int index = fullTargetName.lastIndexOf(Project.REF_DELIMITER);
if (index == -1) {
return null;
}
return fullTargetName.substring(0, index);
}
/**
* Flatten the dependencies to the given target
*
* @param flattenedList the List of targets that must be executed before
* the given target
* @param fullTargetName the fully qualified name of the target
* @exception ExecutionException if the given target does not exist in the
* project hierarchy
*/
private void flattenDependency(List flattenedList, String fullTargetName)
throws ExecutionException {
if (flattenedList.contains(fullTargetName)) {
return;
}
String fullProjectName = getFullProjectName(fullTargetName);
Frame frame = getContainingFrame(fullTargetName);
String localTargetName = getNameInFrame(fullTargetName);
Target target = frame.getProject().getTarget(localTargetName);
if (target == null) {
throw new ExecutionException("Target " + fullTargetName
+ " does not exist");
}
for (Iterator i = target.getDependencies(); i.hasNext();) {
String localDependencyName = (String) i.next();
String fullDependencyName = localDependencyName;
if (fullProjectName != null) {
fullDependencyName = fullProjectName + Project.REF_DELIMITER
+ localDependencyName;
}
flattenDependency(flattenedList, fullDependencyName);
if (!flattenedList.contains(fullDependencyName)) {
flattenedList.add(fullDependencyName);
}
}
}
/**
* get the list of dependent targets which must be evaluated for the
* given target.
*
* @param fullTargetName the full name (in reference space) of the
* target
* @return the flattened list of targets
* @exception ExecutionException if the given target could not be found
*/
protected List getTargetDependencies(String fullTargetName)
throws ExecutionException {
List flattenedList = new ArrayList();
flattenDependency(flattenedList, fullTargetName);
flattenedList.add(fullTargetName);
return flattenedList;
}
/**
* Execute the tasks of a target in this frame with the given name
*
* @param targetName the name of the target whose tasks will be evaluated
* @exception ExecutionException if there is a problem executing the tasks
* of the target
*/
protected void executeTarget(String targetName) throws ExecutionException {
// to execute a target we must determine its dependencies and
// execute them in order.
// firstly build a list of fully qualified target names to execute.
List dependencyOrder = getTargetDependencies(targetName);
for (Iterator i = dependencyOrder.iterator(); i.hasNext();) {
String fullTargetName = (String) i.next();
Frame frame = getContainingFrame(fullTargetName);
String localTargetName = getNameInFrame(fullTargetName);
frame.executeTargetTasks(localTargetName);
}
}
/**
* Run the tasks returned by the given iterator
*
* @param taskIterator the iterator giving the tasks to execute
* @exception ExecutionException if there is execution problem while
* executing tasks
*/
protected void executeTasks(Iterator taskIterator)
throws ExecutionException {
while (taskIterator.hasNext()) {
BuildElement model = (BuildElement) taskIterator.next();
// what sort of element is this.
try {
Object component = componentManager.createComponent(model);
if (component instanceof Task) {
execService.executeTask((Task) component);
} else {
String typeId
= model.getAspectValue(Constants.ANT_ASPECT, "id");
if (typeId != null) {
setDataValue(typeId, component, true);
}
}
} catch (ExecutionException e) {
e.setLocation(model.getLocation(), false);
throw e;
} catch (RuntimeException e) {
ExecutionException ee =
new ExecutionException(e, model.getLocation());
throw ee;
}
}
}
/**
* Execute the given target's tasks. The target must be local to this
* frame's project
*
* @param targetName the name of the target within this frame that is to
* be executed.
* @exception ExecutionException if there is a problem executing tasks
*/
protected void executeTargetTasks(String targetName)
throws ExecutionException {
Throwable failureCause = null;
Target target = project.getTarget(targetName);
String ifCondition = target.getIfCondition();
String unlessCondition = target.getUnlessCondition();
if (ifCondition != null) {
ifCondition = dataService.replacePropertyRefs(ifCondition.trim());
if (!isDataValueSet(ifCondition)) {
return;
}
}
if (unlessCondition != null) {
unlessCondition
= dataService.replacePropertyRefs(unlessCondition.trim());
if (isDataValueSet(unlessCondition)) {
return;
}
}
try {
Iterator taskIterator = target.getTasks();
eventSupport.fireTargetStarted(target);
executeTasks(taskIterator);
} catch (ExecutionException e) {
e.setLocation(target.getLocation(), false);
failureCause = e;
throw e;
} catch (RuntimeException e) {
ExecutionException ee =
new ExecutionException(e, target.getLocation());
failureCause = ee;
throw ee;
} finally {
eventSupport.fireTargetFinished(target, failureCause);
}
}
/**
* Initialize the frame by executing the project level tasks if any
*
* @exception ExecutionException if the top level tasks of the frame
* failed
*/
protected void initialize() throws ExecutionException {
configureServices();
setMagicProperties();
determineBaseDir();
try {
// load system ant lib
URL systemLibs
= new URL(initConfig.getLibraryURL(), "syslibs/");
componentManager.loadLib(systemLibs.toString(), true, true);
// execute any config tasks
executeTasks(config.getTasks());
// now load other system libraries
URL antLibs = new URL(initConfig.getLibraryURL(), "antlibs/");
componentManager.loadLib(antLibs.toString(), false, true);
executeTasks(project.getTasks());
} catch (MalformedURLException e) {
throw new ExecutionException("Unable to initialize antlibs", e);
}
}
/**
* Determine the base directory for each frame in the frame hierarchy
*
* @exception ExecutionException if the base directories cannot be
* determined
*/
private void determineBaseDir() throws ExecutionException {
if (isDataValueSet(MagicProperties.BASEDIR)) {
baseDir
= new File(getDataValue(MagicProperties.BASEDIR).toString());
} else {
URL projectURL = project.getSourceURL();
if (projectURL.getProtocol().equals("file")) {
File projectFile = new File(projectURL.getFile());
File projectFileParent = projectFile.getParentFile();
String base = project.getBase();
if (base == null) {
baseDir = projectFileParent;
} else {
FileUtils fileUtils = FileUtils.newFileUtils();
baseDir = fileUtils.resolveFile(projectFileParent, base);
}
} else {
baseDir = new File(".");
}
}
setDataValue(MagicProperties.BASEDIR, baseDir.getAbsolutePath(), true);
}
/**
* Configure the services that the frame makes available to its library
* components
*/
private void configureServices() {
// create services and make them available in our services map
fileService = new CoreFileService(this);
componentManager = new ComponentManager(this);
dataService = new CoreDataService(this,
config.isUnsetPropertiesAllowed());
execService = new CoreExecService(this);
services.put(FileService.class, fileService);
services.put(ComponentService.class, componentManager);
services.put(DataService.class, dataService);
services.put(EventService.class, new CoreEventService(this));
services.put(ExecService.class, execService);
services.put(InputService.class, new CoreInputService(this));
}
/**
* Handle the content from a single thread. This method will be called by
* the thread producing the content. The content is broken up into
* separate lines
*
* @param line the content produce by the current thread.
* @param isErr true if this content is from the thread's error stream.
*/
public void threadOutput(String line, boolean isErr) {
eventSupport.threadOutput(line, isErr);
}
}