/*
* #%L
* Native ARchive plugin for Maven
* %%
* Copyright (C) 2002 - 2014 NAR Maven Plugin developers.
* %%
* 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.
* #L%
*/
package com.github.maven_nar.cpptasks.ide;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.DataType;
import com.github.maven_nar.cpptasks.CCTask;
import com.github.maven_nar.cpptasks.CUtil;
import com.github.maven_nar.cpptasks.TargetInfo;
/**
* Requests the creation of an IDE project file. Experimental.
*
* Implementation status: msdev5, msdev6 and cbuilderx
* generate reasonable project files for simple projects,
* xcode and msdev7 and msdev71 capture source file lists and
* a few settings.
*
* @author Curt Arnold
*/
public final class ProjectDef extends DataType {
/**
* Name of property that must be present or definition will be ignored. May
* be null.
*/
private String ifProp;
/**
* Name of property that must be absent or definition will be ignored. May
* be null.
*/
private String unlessProp;
/**
* Project file name.
*/
private File outFile;
/**
* Project name.
*/
private String name;
/**
* Fail on error.
*/
private boolean failOnError = true;
/**
* Overwrite existing project file.
*/
private boolean overwrite = true;
/**
* Project writer.
*/
private ProjectWriter projectWriter;
/**
* Object directory.
*
*/
private File objDir;
/**
* List of dependency definitions.
*/
private final List<DependencyDef> dependencies = new ArrayList<>();
/**
* List of comments.
*/
private final List<CommentDef> comments = new ArrayList<>();
/**
* Constructor.
*
*/
public ProjectDef() {
}
/**
* Add comment for the generated project file.
*
* @param comment
* comment, may not be null.
*/
public void addComment(final CommentDef comment) {
this.comments.add(comment);
}
/**
* Add a dependency definition to the project.
*
* @param dependency
* dependency.
*/
public void addDependency(final DependencyDef dependency) {
this.dependencies.add(dependency);
}
/**
* Required by documentation generator.
*/
public void execute() {
throw new org.apache.tools.ant.BuildException("Not an actual task, but looks like one for documentation purposes");
}
/**
* Executes the task. Compiles the given files.
*
* @param task
* cc task
* @param sources
* source files (includes headers)
* @param targets
* compilation targets
* @param linkTarget
* link target
*/
public void execute(final CCTask task, final List<File> sources, final Map<String, TargetInfo> targets,
final TargetInfo linkTarget) {
try {
this.projectWriter.writeProject(this.outFile, task, this, sources, targets, linkTarget);
} catch (final BuildException ex) {
if (this.failOnError) {
throw ex;
} else {
task.log(ex.toString());
}
} catch (final Exception ex) {
if (this.failOnError) {
throw new BuildException(ex);
} else {
task.log(ex.toString());
}
}
}
public List<CommentDef> getComments() {
return new ArrayList<>(this.comments);
}
public List<DependencyDef> getDependencies() {
return new ArrayList<>(this.dependencies);
}
/**
* Get name.
*
* @return String name
*/
public String getName() {
return this.name;
}
/**
* Gets the object files directory.
*
* @return directory, may be null.
*/
public File getObjdir() {
return this.objDir;
}
/**
* Sets the directory used for object files. If not specified,
* the object files directory from cc task will be used.
*
* @param oDir
* object file directory.
*/
public void getObjdir(final File oDir) {
this.objDir = oDir;
}
/**
* Gets whether an existing project file should be overwritten,
* default is true. If false and the project file exists,
* the value of failonerror will determine if the task fails.
*
* @return value
*/
public boolean getOverwrite() {
return this.overwrite;
}
/**
* Determine if this def should be used.
*
* Definition will be active if the "if" variable (if specified) is set and
* the "unless" variable (if specified) is not set and that all reference
* or extended definitions are active
*
* @return true if processor is active
*/
public boolean isActive() {
final Project project = getProject();
if (!CUtil.isActive(project, this.ifProp, this.unlessProp)) {
return false;
}
return true;
}
/**
* Class name for a user-supplied project writer. Use the "type"
* attribute to specify built-in project writer implementations.
*
* @param className
* full class name
*
*/
public void setClassname(final String className) {
Object proc = null;
try {
final Class<?> implClass = ProjectDef.class.getClassLoader().loadClass(className);
try {
final Method getInstance = implClass.getMethod("getInstance");
proc = getInstance.invoke(null);
} catch (final Exception ex) {
proc = implClass.newInstance();
}
} catch (final Exception ex) {
throw new BuildException(ex);
}
this.projectWriter = (ProjectWriter) proc;
}
/**
* Sets whether a failure to write the project file should cause the
* task to fail. Default is true.
*
* @param value
* new value
*/
public void setFailonerror(final boolean value) {
this.failOnError = value;
}
/**
* Sets the property name for the 'if' condition.
*
* The configuration will be ignored unless the property is defined.
*
* The value of the property is insignificant, but values that would imply
* misinterpretation ("false", "no") will throw an exception when
* evaluated.
*
* @param propName
* name of property
*/
public void setIf(final String propName) {
this.ifProp = propName;
}
/**
* Set name.
*
* @param value
* String name
*/
public void setName(final String value) {
this.name = value;
}
/**
* Sets the name for the generated project file.
*
* @param outfile
* output file name
*/
public void setOutfile(final File outfile) {
//
// if file name was empty, skip link step
//
if (outfile == null || outfile.toString().length() > 0) {
this.outFile = outfile;
}
}
/**
* Sets whether an existing project file should be overwritten,
* default is true. If false and the project file exists,
* the value of failonerror will determine if the task fails.
*
* @param value
* new value
*/
public void setOverwrite(final boolean value) {
this.overwrite = value;
}
/**
* Set project type.
*
*
* <table width="100%" border="1">
* <thead>Supported project formats </thead>
* <tr>
* <td>cbuilderx</td>
* <td>Borland C++BuilderX</td>
* </tr>
* <tr>
* <td>msvc5</td>
* <td>Microsoft Visual C++ 97</td>
* </tr>
* <tr>
* <td>msvc6</td>
* <td>Microsoft Visual C++ 6</td>
* </tr>
* <tr>
* <td>msvc7</td>
* <td>Microsoft Visual C++.NET</td>
* </tr>
* <tr>
* <td>msvc71</td>
* <td>Microsoft Visual C++.NET 2003</td>
* </tr>
* <tr>
* <td>msvc8</td>
* <td>Microsoft Visual C++ 2005</td>
* </tr>
* <tr>
* <td>msvc9</td>
* <td>Microsoft Visual C++ 2008</td>
* </tr>
* <tr>
* <td>xcode</td>
* <td>Apple Xcode</td>
* </tr>
* </table>
*
* @param value
* new value
*/
public void setType(final ProjectWriterEnum value) {
this.projectWriter = value.getProjectWriter();
}
/**
* Set the property name for the 'unless' condition.
*
* If named property is set, the configuration will be ignored.
*
* The value of the property is insignificant, but values that would imply
* misinterpretation ("false", "no") of the behavior will throw an
* exception when evaluated.
*
* @param propName
* name of property
*/
public void setUnless(final String propName) {
this.unlessProp = propName;
}
}