// NAnt - A .NET build tool
// Copyright (C) 2001 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Gerry Shaw (gerry_shaw@yahoo.com)
// Scott Hernandez (ScottHernandez@hotmail.com)
using System;
using System.Collections;
using System.Globalization;
using NAnt.Core.Attributes;
using NAnt.Core.Util;
namespace NAnt.Core.Tasks {
///
/// Sets a property in the current project.
///
///
/// NAnt uses a number of predefined properties.
///
///
///
/// Define a debug property with value .
///
///
///
/// ]]>
///
///
///
///
/// Use the user-defined debug property.
///
///
///
/// ]]>
///
///
///
///
/// Define a read-only property. This is just like passing in the param
/// on the command line.
///
///
///
/// ]]>
///
///
///
///
/// Define a property, but do not overwrite the value if the property already exists (eg. it was specified on the command line).
///
///
///
///
///
///
/// ]]>
///
///
/// Executing this build file with the command line option -D:debug=false,
/// would cause the value specified on the command line to remain unaltered.
///
///
///
///
///
[TaskName("property")]
public class PropertyTask : Task {
#region Private Instance Fields
private string _name = null;
private string _value = string.Empty;
private bool _readOnly = false;
private bool _dynamic = false;
private bool _overwrite = true;
#endregion Private Instance Fields
#region Public Instance Properties
///
/// The name of the NAnt property to set.
///
[TaskAttribute("name", Required=true)]
[StringValidator(AllowEmpty=false)]
public string PropertyName {
get { return _name; }
set { _name = value; }
}
///
/// The value to assign to the NAnt property.
///
[TaskAttribute("value", Required=true, ExpandProperties=false)]
[StringValidator(AllowEmpty=true)]
public string Value {
get { return _value; }
set { _value = value; }
}
///
/// Specifies whether the property is read-only or not.
/// The default is .
///
[TaskAttribute("readonly", Required=false)]
[BooleanValidator()]
public bool ReadOnly {
get { return _readOnly; }
set { _readOnly = value; }
}
///
/// Specifies whether references to other properties should not be
/// expanded when the value of the property is set, but expanded when
/// the property is actually used. By default, properties will be
/// expanded when set.
///
[TaskAttribute("dynamic", Required=false)]
[BooleanValidator()]
public bool Dynamic {
get { return _dynamic; }
set { _dynamic = value; }
}
///
/// Specifies whether the value of a property should be overwritten if
/// the property already exists (unless the property is read-only).
/// The default is .
///
[TaskAttribute("overwrite", Required=false)]
[BooleanValidator()]
public bool Overwrite {
get { return _overwrite; }
set { _overwrite = value; }
}
#endregion Public Instance Properties
#region Override implementation of Task
protected override void ExecuteTask() {
string propertyValue;
if (!Dynamic) {
propertyValue = Project.ExpandProperties(Value, Location);
} else {
propertyValue = Value;
}
// Special check for framework setting.
if (PropertyName == "nant.settings.currentframework") {
FrameworkInfo newTargetFramework = Project.Frameworks[propertyValue];
// check if target framework exists
if (newTargetFramework != null) {
if (Project.TargetFramework != null) {
if (Project.TargetFramework != newTargetFramework) {
// only output message in build log if target
// framework is actually changed
Log(Level.Info, "Target framework changed to \"{0}\".",
newTargetFramework.Description);
}
} else {
Log(Level.Info, "Target framework set to \"{0}\".",
newTargetFramework.Description);
}
Project.TargetFramework = Project.Frameworks[propertyValue];
return;
} else {
ArrayList validvalues = new ArrayList();
foreach (FrameworkInfo framework in Project.Frameworks) {
validvalues.Add(framework.Name);
}
string validvaluesare = string.Empty;
if (validvalues.Count > 0) {
validvaluesare = string.Format(CultureInfo.InvariantCulture,
ResourceUtils.GetString("String_ValidValues"), string.Join(", ", (string[]) validvalues.ToArray(typeof(string))));
}
throw new BuildException(string.Format(CultureInfo.InvariantCulture,
ResourceUtils.GetString("NA1143"),
propertyValue, validvaluesare), Location);
}
}
if (!Project.Properties.Contains(PropertyName)) {
if (ReadOnly) {
Properties.AddReadOnly(PropertyName, propertyValue);
} else {
Properties[PropertyName] = propertyValue;
}
if (Dynamic) {
Properties.MarkDynamic(PropertyName);
}
} else {
if (Overwrite) {
if (Project.Properties.IsReadOnlyProperty(PropertyName)) {
// for now, just output a warning when attempting to
// overwrite a readonly property
//
// we should actually be throwing a BuildException here, but
// we currently don't have a good mechanism in place to allow
// users to specify properties on the command line and provide
// default values for these properties in the build file
//
// users could use either the "overwrite" property or a
// "property::exists(...)" unless condition on the
// task, but these do not seem to be intuitive for users
Log(Level.Warning, "Read-only property \"{0}\" cannot"
+ " be overwritten.", PropertyName);
} else {
Properties[PropertyName] = propertyValue;
if (Dynamic) {
Properties.MarkDynamic(PropertyName);
}
}
} else {
Log(Level.Verbose, "Property \"{0}\" already exists, and \"overwrite\" is set to false.", PropertyName);
}
}
}
#endregion Override implementation of Task
}
}