1 // Copyright (c) Microsoft. All rights reserved.
2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 
4 using System;
5 using System.Collections.Generic;
6 using System.Text;
7 using System.Xml;
8 
9 using Microsoft.Build.Framework;
10 using Microsoft.Build.BuildEngine.Shared;
11 
12 namespace Microsoft.Build.BuildEngine
13 {
14     /// <summary>
15     /// This class is used to wrap the context within which the task is executed. This includes the
16     /// project within which the task is being executed, the target, the task success
17     /// or failure and task outputs. This class is instantiated inside the engine and is directly
18     /// accessed outside of the engine domain. It is used for sharing data between the engine domain
19     /// and the TEM.
20     /// </summary>
21     internal class TaskExecutionContext : ExecutionContext
22     {
23         #region Constructors
24         /// <summary>
25         /// Default constructor for creation of task execution wrapper
26         /// </summary>
TaskExecutionContext( Project parentProject, Target parentTarget, XmlElement taskNode, ProjectBuildState buildContext, int handleId, int nodeIndex, BuildEventContext taskBuildEventContext )27         internal TaskExecutionContext
28         (
29             Project parentProject,
30             Target  parentTarget,
31             XmlElement taskNode,
32             ProjectBuildState buildContext,
33             int handleId,
34             int nodeIndex,
35             BuildEventContext taskBuildEventContext
36         )
37             :base(handleId, nodeIndex, taskBuildEventContext)
38         {
39             this.parentProject = parentProject;
40             this.parentTarget = parentTarget;
41             this.taskNode = taskNode;
42             this.buildContext = buildContext;
43             this.thrownException = null;
44         }
45         #endregion
46 
47         #region Properties
48 
49         /// <summary>
50         /// Returns true if the task completed successfully
51         /// </summary>
52         internal bool TaskExecutedSuccessfully
53         {
54             get
55             {
56                 return this.taskExecutedSuccessfully;
57             }
58         }
59 
60         /// <summary>
61         /// Returns the exception thrown during the task execution. The exception will either be
62         /// InvalidProjectException or some unexpected exception that occured in the engine code,
63         /// because unexpected task exceptions are converted to logged errors.
64         /// </summary>
65         internal Exception ThrownException
66         {
67             get
68             {
69                 return this.thrownException;
70             }
71         }
72 
73         /// <summary>
74         /// Project within which this task exists
75         /// </summary>
76         internal Project ParentProject
77         {
78             get
79             {
80                 return this.parentProject;
81             }
82         }
83 
84         /// <summary>
85         /// Target within which this task exists
86         /// </summary>
87         internal Target ParentTarget
88         {
89             get
90             {
91                 return this.parentTarget;
92             }
93         }
94 
95         /// <summary>
96         /// Project build context within which this task is executing
97         /// </summary>
98         internal ProjectBuildState BuildContext
99         {
100             get
101             {
102                 return this.buildContext;
103             }
104         }
105 
106         /// <summary>
107         /// XML node for the task
108         /// </summary>
109         internal XmlElement TaskNode
110         {
111             get
112             {
113                 return this.taskNode;
114             }
115         }
116 
117         /// <summary>
118         /// The build request that triggered the execution of this task
119         /// </summary>
120         internal BuildRequest TriggeringBuildRequest
121         {
122             get
123             {
124                 BuildRequest buildRequest = buildContext.BuildRequest;
125                 ErrorUtilities.VerifyThrow(buildRequest != null, "There must be a non-null build request");
126                 return buildRequest;
127             }
128         }
129 
130         #endregion
131 
132         #region Methods
133         /// <summary>
134         /// This method is used to set the outputs of the task once the execution is complete
135         /// </summary>
SetTaskOutputs( bool taskExecutedSuccessfully, Exception thrownException, long executionTime )136         internal void SetTaskOutputs
137         (
138             bool taskExecutedSuccessfully,
139             Exception thrownException,
140             long executionTime
141         )
142         {
143             this.taskExecutedSuccessfully = taskExecutedSuccessfully;
144             this.thrownException = thrownException;
145             this.buildContext.BuildRequest.AddTaskExecutionTime(executionTime);
146         }
147         #endregion
148 
149         #region Member Data
150         /// <summary>
151         /// The project within which the target containing the task was run
152         /// </summary>
153         private Project parentProject;
154         /// <summary>
155         /// The target withing which the task is contained
156         /// </summary>
157         private Target parentTarget;
158         /// <summary>
159         /// The XML node for the task
160         /// </summary>
161         private XmlElement taskNode;
162         /// <summary>
163         /// Context within which the task execution was requested
164         /// </summary>
165         private ProjectBuildState buildContext;
166 
167         /// <summary>
168         /// Task outputs
169         /// </summary>
170         bool                taskExecutedSuccessfully;
171         Exception           thrownException;
172 
173         #endregion
174     }
175 }
176