namespace
Microsoft.TeamFoundation.WorkItemTracking.Client
{
using
Microsoft.TeamFoundation;
using
Microsoft.TeamFoundation.Client;
using
Microsoft.TeamFoundation.Common;
using
Microsoft.TeamFoundation.WorkItemTracking.Client.DataStore;
using
Microsoft.TeamFoundation.WorkItemTracking.Proxy;
using
System;
using
System.Collections;
using
System.Collections.Generic;
using
System.Globalization;
using
System.IO;
using
System.Reflection;
using
System.Runtime.InteropServices;
using
System.Threading;
using
System.Xml;
public
sealed
class
WorkItem : IRevisionInternal
{
internal
const
int
c_revisionHistory = -4;
internal
const
int
c_revisionLatest = -3;
internal
const
int
c_revisionNull = -1;
internal
const
int
c_revisionUpdate = -2;
private
DateTime? m_asof;
private
AttachmentCollection m_attachments;
private
int
m_dataVersion;
private
bool
? m_dirty;
private
FieldCollection m_fields;
private
WorkItemFieldData m_fieldsData;
private
int
m_id;
private
int
m_index;
private
bool
m_IsUpdating;
private
LinkCollection m_links;
private
WorkItemLinkData m_linksData;
private
WorkItemCollection m_list;
private
int
m_metadataVersion;
private
OpenState m_openState;
private
Microsoft.TeamFoundation.WorkItemTracking.Client.Project m_project;
private
bool
? m_readonly;
private
RevisionCollection m_revisions;
private
WorkItemStore m_store;
private
int
m_tempId;
private
WorkItemType m_type;
private
WorkItemLinkCollection m_wlinks;
private
WorkItemLinkCollection m_wlinksHistory;
private
static
int
[] s_areaDependentFieldIds =
new
int
[] { -12, -42, -43, -44, -45, -46, -47, -48, -49 };
internal
static
int
[] s_internallyCalculatedFieldIds =
new
int
[] {
-7, -12, -42, -43, -44, -45, -46, -47, -48, -49, -105, -50, -51, -52, -53, -54,
-55, -56
};
private
static
int
[] s_iterationDependentFieldIds =
new
int
[] { -50, -51, -52, -53, -54, -55, -56 };
private
static
int
s_tempId = 0;
public
event
WorkItemFieldChangeEventHandler FieldChanged;
public
WorkItem(WorkItemType type)
{
this
.m_dirty =
false
;
this
.m_readonly =
null
;
this
.m_asof =
null
;
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewBegin);
TeamFoundationTrace.Verbose(
"Entering WorkItem(WorkItemStore store, WorkItemType type)"
);
if
(type ==
null
)
{
throw
new
ArgumentNullException(
"type"
);
}
this
.m_fieldsData =
new
WorkItemFieldData(
this
);
this
.m_linksData =
new
WorkItemLinkData(
this
);
this
.m_store = type.Store;
this
.m_id = 0;
this
.m_tempId = Interlocked.Decrement(
ref
s_tempId);
this
.m_openState = OpenState.New;
this
.m_readonly =
false
;
this
.InitNew(type);
this
.ApplyRules();
this
.m_dirty =
true
;
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewEnd);
}
internal
WorkItem(WorkItemCollection list,
int
index)
{
this
.m_dirty =
false
;
this
.m_readonly =
null
;
this
.m_asof =
null
;
this
.m_store = list.Store;
this
.m_fieldsData =
new
WorkItemFieldData(
this
);
this
.m_linksData =
new
WorkItemLinkData(
this
);
this
.m_id = list.GetId(index);
this
.m_tempId =
this
.m_id;
this
.m_list = list;
this
.m_index = index;
this
.m_openState = OpenState.Queried;
if
(!list.Query.IsBatchReadMode)
{
this
.m_asof =
new
DateTime?(list.Query.AsOfUTC);
}
}
internal
WorkItem(WorkItemStore store,
int
id)
{
this
.m_dirty =
false
;
this
.m_readonly =
null
;
this
.m_asof =
null
;
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewBegin);
TeamFoundationTrace.Verbose(
"Entering WorkItem(WorkItemStore store, int id)"
);
if
(store ==
null
)
{
throw
new
ArgumentNullException(
"store"
);
}
if
(id <= 0)
{
throw
new
ArgumentOutOfRangeException(
"id"
);
}
this
.m_store = store;
this
.m_fieldsData =
new
WorkItemFieldData(
this
);
this
.m_linksData =
new
WorkItemLinkData(
this
);
this
.m_id = id;
this
.m_tempId = id;
this
.LoadWorkItem(id, 0,
null
);
this
.ApplyRules();
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewEnd);
}
internal
WorkItem(WorkItemStore store, System.Uri uri)
{
this
.m_dirty =
false
;
this
.m_readonly =
null
;
this
.m_asof =
null
;
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewBegin);
TeamFoundationTrace.Verbose(
"Entering WorkItem(WorkItemStore store, Uri uri)"
);
if
(store ==
null
)
{
throw
new
ArgumentNullException(
"store"
);
}
this
.m_store = store;
this
.m_fieldsData =
new
WorkItemFieldData(
this
);
this
.m_linksData =
new
WorkItemLinkData(
this
);
if
(!
this
.IsValidUri(uri))
{
throw
new
ArgumentException(
"uri"
);
}
ArtifactId artifact =
this
.GetArtifact(uri);
this
.m_id = Convert.ToInt32(artifact.ToolSpecificId, CultureInfo.InvariantCulture);
this
.m_tempId =
this
.m_id;
this
.LoadWorkItem(
this
.m_id, 0,
null
);
this
.ApplyRules();
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewEnd);
}
internal
WorkItem(WorkItemStore store,
int
id, DateTime at)
{
this
.m_dirty =
false
;
this
.m_readonly =
null
;
this
.m_asof =
null
;
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewBegin);
TeamFoundationTrace.Verbose(
"Entering WorkItem(WorkItemStore store, int id, DateTime at)"
);
if
(store ==
null
)
{
throw
new
ArgumentNullException(
"store"
);
}
if
(id <= 0)
{
throw
new
ArgumentOutOfRangeException(
"id"
);
}
DateTime time = store.ConvertToUniversalTime(at);
if
((time <
new
DateTime(0x76c, 1, 1)) || (time >= DateTime.MaxValue))
{
throw
new
ArgumentOutOfRangeException(
"at"
);
}
this
.m_store = store;
this
.m_fieldsData =
new
WorkItemFieldData(
this
);
this
.m_linksData =
new
WorkItemLinkData(
this
);
this
.m_id = id;
this
.m_tempId = id;
this
.LoadWorkItem(id, 0,
new
DateTime?(time));
this
.ApplyRules();
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewEnd);
}
internal
WorkItem(WorkItemStore store,
int
id,
int
revision)
{
this
.m_dirty =
false
;
this
.m_readonly =
null
;
this
.m_asof =
null
;
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewBegin);
TeamFoundationTrace.Verbose(
"Entering WorkItem(WorkItemStore store, int id, int revision)"
);
if
(store ==
null
)
{
throw
new
ArgumentNullException(
"store"
);
}
if
(id <= 0)
{
throw
new
ArgumentOutOfRangeException(
"id"
);
}
if
(revision <= 0)
{
throw
new
ArgumentOutOfRangeException(
"revision"
);
}
this
.m_store = store;
this
.m_fieldsData =
new
WorkItemFieldData(
this
);
this
.m_linksData =
new
WorkItemLinkData(
this
);
this
.m_id = id;
this
.m_tempId = id;
this
.LoadWorkItem(id, revision,
null
);
this
.ApplyRules();
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewEnd);
}
internal
WorkItem(WorkItemStore store, System.Uri uri, DateTime at)
{
this
.m_dirty =
false
;
this
.m_readonly =
null
;
this
.m_asof =
null
;
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewBegin);
TeamFoundationTrace.Verbose(
"Entering WorkItem(WorkItemStore store, Uri uri, DateTime at)"
);
if
(store ==
null
)
{
throw
new
ArgumentNullException(
"store"
);
}
DateTime time = store.ConvertToUniversalTime(at);
if
((time <
new
DateTime(0x76c, 1, 1)) || (time >= DateTime.MaxValue))
{
throw
new
ArgumentOutOfRangeException(
"at"
);
}
this
.m_store = store;
this
.m_fieldsData =
new
WorkItemFieldData(
this
);
this
.m_linksData =
new
WorkItemLinkData(
this
);
if
(!
this
.IsValidUri(uri))
{
throw
new
ArgumentException(
"uri"
);
}
ArtifactId artifact =
this
.GetArtifact(uri);
this
.m_id = Convert.ToInt32(artifact.ToolSpecificId, CultureInfo.InvariantCulture);
this
.m_tempId =
this
.m_id;
this
.LoadWorkItem(
this
.m_id, 0,
new
DateTime?(time));
this
.ApplyRules();
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewEnd);
}
internal
WorkItem(WorkItemStore store, System.Uri uri,
int
revision)
{
this
.m_dirty =
false
;
this
.m_readonly =
null
;
this
.m_asof =
null
;
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewBegin);
TeamFoundationTrace.Verbose(
"Entering WorkItem(WorkItemStore store, Uri uri, int revision)"
);
if
(store ==
null
)
{
throw
new
ArgumentNullException(
"store"
);
}
if
(revision <= 0)
{
throw
new
ArgumentOutOfRangeException(
"revision"
);
}
this
.m_store = store;
this
.m_fieldsData =
new
WorkItemFieldData(
this
);
this
.m_linksData =
new
WorkItemLinkData(
this
);
if
(!
this
.IsValidUri(uri))
{
throw
new
ArgumentException(
"uri"
);
}
ArtifactId artifact =
this
.GetArtifact(uri);
this
.m_id = Convert.ToInt32(artifact.ToolSpecificId, CultureInfo.InvariantCulture);
this
.m_tempId =
this
.m_id;
this
.LoadWorkItem(
this
.m_id, revision,
null
);
this
.ApplyRules();
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemNewEnd);
}
internal
void
ApplyFieldChange(
int
fieldId,
object
value)
{
BrieCallBack bc =
new
BrieCallBack(
this
);
WorkItemFieldData.FieldUpdate update =
new
WorkItemFieldData.FieldUpdate();
update.Value = value;
update.Flags = 0;
bc.FieldUpdates.Add(fieldId, update);
this
.ApplyFieldChange(fieldId, bc, 2);
bc.FieldUpdates.Remove(fieldId);
this
.FieldData.SetFieldValues(bc.FieldUpdates);
this
.Store.PsDatastore.BrieAccessCheck(bc, 1, fieldId);
this
.FieldData.SetFieldStates(bc.FieldStates);
}
private
void
ApplyFieldChange(
int
fieldId, BrieCallBack bc,
int
recursive)
{
if
(fieldId != 0)
{
this
.Store.PsDatastore.BrieInvalidateFields(bc, fieldId);
bc.SetFieldUpdateFlags(WorkItemFieldData.FieldFlags.SetByDefaultRule);
this
.Store.PsDatastore.BrieAccessCheck(bc, 0x80, fieldId);
bc.SetFieldUpdateFlags(0);
this
.Store.PsDatastore.BrieAccessCheck(bc, 0x40, fieldId);
}
Dictionary<
int
,
bool
=
""
>
dictionary = bc.ResetChanges();
if
(recursive > 0)
{
foreach
(
int
num
in
dictionary.Keys)
{
this
.ApplyFieldChange(num, bc, recursive - 1);
}
}
}
internal
void
ApplyRules()
{
this
.ApplyRules(
true
);
}
internal
void
ApplyRules(
bool
fSetChangedBy)
{
this
.FieldData.ResetChangedFields();
BrieCallBack callback =
new
BrieCallBack(
this
);
callback.SetFieldUpdateFlags(WorkItemFieldData.FieldFlags.SetByDefaultRule);
this
.Store.PsDatastore.BrieAccessCheck(callback, 0x80, 0);
callback.SetFieldUpdateFlags(0);
this
.Store.PsDatastore.BrieAccessCheck(callback, 0x20, 0);
this
.ApplyFieldChange(0, callback, 2);
this
.FieldData.SetFieldValues(callback.FieldUpdates);
this
.Store.PsDatastore.BrieAccessCheck(callback, 1, 0);
this
.FieldData.SetAllFieldStates(callback.FieldStates);
if
(fSetChangedBy)
{
int
id = 9;
string
userDisplayName =
this
.m_store.UserDisplayName;
if
(
this
.FieldData.SetUpdateFieldValue(id,
userDisplayName, WorkItemFieldData.FieldFlags.SetByRule))
{
this
.ApplyFieldChange(id, userDisplayName);
}
}
this
.FieldData.FireEvents();
}
private
object
CalculateAuthorizedAsField(
int
revision)
{
object
fieldValue =
this
.GetFieldValue(-6, revision);
if
(fieldValue
is
int
)
{
return
this
.m_store.GetPersonNameById((
int
)
fieldValue);
}
return
fieldValue;
}
internal
void
CalculateFieldLists(
int
fieldId)
{
BrieCallBack callback =
new
BrieCallBack(
this
);
this
.Store.PsDatastore.BrieAccessCheck(callback, 0x17, fieldId);
this
.FieldData.SetFieldStates(callback.FieldStates);
}
private
object
CalculateNodeNameField(
int
fname,
int
fid,
int
revision)
{
object
fieldValue =
this
.GetFieldValue(fid, revision);
if
(fieldValue
is
int
)
{
return
this
.m_store.TreeIdToNodeName((
int
)
fieldValue);
}
return
fieldValue;
}
private
object
CalculateTreeLevelField(
int
flevel,
int
flevel1,
int
fid,
int
revision)
{
object
fieldValue =
this
.GetFieldValue(fid, revision);
if
(fieldValue
is
int
)
{
return
this
.m_store.TreeIdToNodeLevel((
int
)
fieldValue, (flevel1 - flevel) + 1);
}
return
fieldValue;
}
private
object
CalculateTreePathField(
int
fpath,
int
fid,
int
revision)
{
object
fieldValue =
this
.GetFieldValue(fid, revision);
if
(fieldValue
is
int
)
{
return
this
.m_store.TreeIdToPath((
int
)
fieldValue);
}
return
fieldValue;
}
private
void
CheckType()
{
WorkItemType type =
this
.Type;
}
private
void
CheckUpdateCachedData()
{
bool
flag =
false
;
if
(
this
.m_store.MetadataVersion !=
this
.m_metadataVersion)
{
flag =
true
;
}
int
metadataVersion =
this
.m_store.MetadataVersion;
if
(
this
.m_project ==
null
)
{
object
fieldValue =
this
.GetFieldValue(-2, -2);
if
(fieldValue !=
null
)
{
this
.m_project =
this
.m_store.TreeIdToProject((
int
)
fieldValue);
}
}
else
if
(flag)
{
this
.m_project =
this
.m_store.Projects.GetById(
this
.m_project.Id);
this
.m_type =
null
;
}
if
((
this
.m_type ==
null
)
&& (
this
.m_project !=
null
))
{
string
str = (
string
)
this
.GetFieldValue(0x19,
-2);
if
(!
string
.IsNullOrEmpty(str) &&
this
.m_project.WorkItemTypes.Contains(str))
{
this
.m_type =
this
.m_project.WorkItemTypes[str];
}
}
this
.m_metadataVersion = metadataVersion;
}
public
void
Close()
{
if
(!
this
.IsNew)
{
this
.m_fieldsData =
new
WorkItemFieldData(
this
);
this
.m_linksData =
new
WorkItemLinkData(
this
);
this
.m_revisions =
null
;
this
.m_attachments =
null
;
this
.m_links =
null
;
this
.m_wlinks =
null
;
this
.m_wlinksHistory =
null
;
this
.m_fields =
null
;
if
(
this
.m_list !=
null
)
{
this
.m_openState = OpenState.Queried;
}
else
{
this
.m_openState = OpenState.Undefined;
}
}
}
internal
void
ConvertFieldValueToExternal(
ref
object
value, System.Type type)
{
if
((value ==
null
) && (type ==
typeof
(
string
)))
{
value =
string
.Empty;
}
else
if
(value
is
DateTime)
{
value =
this
.Store.ConvertToLocalTime((DateTime) value);
}
}
internal
WorkItemFieldData.FieldFlags ConvertFieldValueToInternal(
ref
object
value, System.Type type)
{
if
(value ==
null
)
{
return
0;
}
try
{
object
obj2 = value;
if
(value.GetType() != type)
{
if
((type ==
typeof
(Guid)) && (value
is
string
))
{
obj2 =
new
Guid((
string
) value);
}
else
{
obj2 = Convert.ChangeType(value, type,
this
.Store.CultureInfo);
}
}
if
(obj2
is
string
)
{
obj2 = ((
string
) obj2).Trim();
if
(
string
.IsNullOrEmpty((
string
)
obj2))
{
obj2 =
null
;
}
}
else
if
(obj2
is
DateTime)
{
DateTime time = (DateTime) obj2;
int
year = time.Year;
if
((year < 0x6d9) || (year > 0x270f))
{
return
WorkItemFieldData.FieldFlags.InvalidDate;
}
obj2 =
this
.Store.ConvertToUniversalTime((DateTime) obj2);
}
value = obj2;
return
0;
}
catch
(FormatException)
{
return
WorkItemFieldData.FieldFlags.InvalidType;
}
catch
(OverflowException)
{
return
WorkItemFieldData.FieldFlags.InvalidType;
}
catch
(InvalidCastException)
{
return
WorkItemFieldData.FieldFlags.InvalidType;
}
}
public
WorkItem Copy()
{
return
this
.Copy(
this
.Type);
}
public
WorkItem Copy(WorkItemType targetType)
{
return
this
.Copy(targetType, WorkItemCopyFlags.CopyLinks);
}
public
WorkItem Copy(WorkItemType targetType, WorkItemCopyFlags flags)
{
if
(targetType ==
null
)
{
throw
new
ArgumentNullException(
"targetType"
);
}
this
.CheckType();
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemCopyBegin);
WorkItem target =
new
WorkItem(targetType);
int
id = targetType.Project.Id;
foreach
(FieldDefinition definition
in
targetType.FieldDefinitions)
{
if
(!definition.IsCloneable)
{
continue
;
}
Field field =
this
.Fields.TryGetById(definition.Id);
if
((((field !=
null
) && (field.Value !=
null
)) && !
object
.Equals(field.Value,
string
.Empty))
&& (((definition.Id != -2) && (definition.Id != -104)) || ((field.Value
is
int
) && (
this
.m_store.TreeIdToProjectId((
int
) field.Value)
== id))))
{
target.FieldData.SetUpdateFieldValue(definition.Id, field.Value, 0);
}
}
target.History = HistoryBuilder.BuildHistoryFromItem(
this
);
if
((flags & WorkItemCopyFlags.CopyFiles) != WorkItemCopyFlags.None)
{
foreach
(Attachment attachment
in
this
.Attachments)
{
target.Attachments.Add(
new
Attachment(attachment));
}
}
if
(((flags & WorkItemCopyFlags.CopyLinks) != WorkItemCopyFlags.None) &&
this
.Store.Equals(target.Store))
{
foreach
(Link link
in
this
.Links)
{
Link link2 = link.Clone(target);
if
(link2 !=
null
)
{
target.Links.Add(link2);
}
}
foreach
(WorkItemLink link3
in
this
.WorkItemLinks)
{
Link link4 = link3.Clone(target);
if
(link4 !=
null
)
{
target.Links.Add(link4);
}
}
}
if
(!
this
.IsNew)
{
target.Links.Add(
new
RelatedLink(
this
.Id));
}
target.ApplyRules();
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemCopyEnd);
return
target;
}
private
void
CreateLocalCopy(TfsWebClient client, WorkItemLinkData.AttachmentInfo fi)
{
string
tempFileName = GetTempFileName(
this
.m_store.CacheDirectory);
UriBuilder builder =
new
UriBuilder(
this
.m_store.AttachmentServerUrl);
builder.Query =
string
.Format(CultureInfo.InvariantCulture,
"{0}={1}"
,
new
object
[] {
"FileID"
, fi.ExtId });
client.DownloadFile(builder.Uri.AbsoluteUri.ToString(), tempFileName);
File.SetCreationTimeUtc(tempFileName, fi.CreationDate);
File.SetLastWriteTimeUtc(tempFileName, fi.LastWriteDate);
fi.FileInfo =
new
FileInfo(tempFileName);
}
internal
XmlElement CreateUpdateElement(XmlDocument xdoc, SaveFlags saveFlags,
out
List<xmlelement> xlist,
out
List<workitemlinkdata.workitemlinkinfo> links)
{
xlist =
null
;
links =
null
;
XmlElement xwi =
null
;
xwi = xdoc.CreateElement(
this
.IsNew ?
"InsertWorkItem"
:
"UpdateWorkItem"
);
xwi.SetAttribute(
"ObjectType"
,
"WorkItem"
);
if
(
this
.IsNew)
{
xwi.SetAttribute(
"TempID"
, XmlConvert.ToString(-
this
.TemporaryId));
}
else
{
xwi.SetAttribute(
"WorkItemID"
, XmlConvert.ToString(
this
.Id));
xwi.SetAttribute(
"Revision"
, XmlConvert.ToString(
this
.Rev));
}
XmlElement xc = xdoc.CreateElement(
"Columns"
);
XmlElement xcc = xdoc.CreateElement(
"ComputedColumns"
);
this
.FieldData.AddUpdateElements(xdoc, xwi, xc, xcc);
this
.LinkData.AddUpdateElements(xdoc, xwi, saveFlags,
out
xlist,
out
links);
if
((xwi.ChildNodes.Count == 0) && (xc.ChildNodes.Count == 0))
{
return
null
;
}
xwi.AppendChild(xc);
xwi.AppendChild(xcc);
return
xwi;
}
internal
void
EnsureCollections()
{
if
((
this
.m_openState != OpenState.Opened)
&& (
this
.m_openState != OpenState.New))
{
int
rev = 0;
if
(!
this
.m_asof.HasValue && (
this
.m_list
!=
null
))
{
rev =
this
.m_list.GetAsOfRevision(
this
.m_index);
}
this
.LoadWorkItem(
this
.m_id, rev,
this
.m_asof);
}
}
private
static
EditAction FieldIdToAction(
int
fid)
{
switch
(fid)
{
case
50:
return
EditAction.AddAttachment;
case
0x33:
return
EditAction.AddHyperLink;
case
0x3a:
return
EditAction.AddExternalLink;
case
0x25:
return
EditAction.AddWorkItemLink;
}
throw
new
UnexpectedErrorException();
}
private
void
FinishConstruction(
ref
EditActionSet
set
)
{
if
((
set
.Flags & EditActionFlags.FieldChanges)
!= 0)
{
EditActionInfo info =
set
.Actions.Array[
set
.Actions.Offset];
set
.Tag = HistoryBuilder.BuildTagLine(
this
,
info.Index);
set
.Description = (
string
)
this
.GetFieldValue(0x36,
info.Index);
}
else
{
set
.Tag = HistoryBuilder.BuildTagLineLinks(
this
,
this
.m_store.GetPersonNameById(
set
.ChangedBy));
set
.Description =
string
.Empty;
}
}
internal
void
FireCollectionChangeEvent(
object
updatedCollection,
object
updatedItem, LinkAction action)
{
if
(!
this
.m_IsUpdating && (
this
.m_fieldEventHandler
!=
null
))
{
this
.m_fieldEventHandler(
this
,
new
WorkItemLinkEventArgs(updatedCollection, updatedItem, action));
}
}
internal
void
FireFieldChangeEvent(
int
id)
{
if
((!
this
.m_IsUpdating &&
this
.IsValidType)
&& (
this
.m_fieldEventHandler !=
null
))
{
Field o =
this
.Fields.TryGetById(id);
if
(o !=
null
)
{
this
.m_fieldEventHandler(
this
,
new
WorkItemEventArgs(o));
}
}
}
internal
void
FireWorkItemChangeEvent()
{
if
(!
this
.m_IsUpdating && (
this
.m_fieldEventHandler
!=
null
))
{
this
.m_fieldEventHandler(
this
,
new
WorkItemEventArgs(
null
));
}
}
internal
bool
GetAccessDenied()
{
return
(
this
.m_openState == OpenState.AccessDenied);
}
internal
object
GetActionObject(EditActionInfo a)
{
if
(a.Action == EditAction.None)
{
return
null
;
}
if
(a.Action == EditAction.Revision)
{
return
this
.Revisions[a.Index];
}
return
this
.LinkData.GetLinkInfo(a.Index);
}
internal
EditActionSet[] GetActionsHistory()
{
int
revisionCount =
this
.FieldData.GetRevisionCount();
int
linkInfoCount =
this
.LinkData.GetLinkInfoCount();
EditActionInfo[] array =
new
EditActionInfo[revisionCount + (linkInfoCount * 2)];
int
length = 0;
for
(
int
i = 0; i < revisionCount; i++)
{
EditActionInfo info =
new
EditActionInfo();
info.Action = EditAction.Revision;
info.ChangedDate = (DateTime)
this
.FieldData.GetFieldValue(-4, i);
info.ChangedBy = (
int
)
this
.FieldData.GetFieldValue(-6,
i);
info.Index = i;
array[length++] = info;
}
for
(
int
j = 0; j < linkInfoCount; j++)
{
WorkItemLinkData.LinkInfo linkInfo =
this
.LinkData.GetLinkInfo(j);
if
(linkInfo !=
null
)
{
WorkItemLinkData.WorkItemLinkInfo info3 = linkInfo
as
WorkItemLinkData.WorkItemLinkInfo;
if
(linkInfo.AddedDate != WorkItemStore.FutureDateTimeValue)
{
EditActionInfo info4 =
new
EditActionInfo();
info4.ChangedDate = linkInfo.AddedDate;
info4.Index = j;
info4.ChangedBy = (info3 !=
null
) ? info3.AddedBy : 0;
info4.Action = FieldIdToAction(linkInfo.FieldId);
array[length++] = info4;
}
if
(linkInfo.RemovedDate != WorkItemStore.FutureDateTimeValue)
{
EditActionInfo info5 =
new
EditActionInfo();
info5.ChangedDate = linkInfo.RemovedDate;
info5.Index = j;
info5.ChangedBy = (info3 !=
null
) ? info3.RemovedBy : 0;
info5.Action = FieldIdToAction(linkInfo.FieldId) + 1;
array[length++] = info5;
}
}
}
Array.Sort<editactioninfo>(array, 0, length,
new
EditActionInfoComparator(
this
));
EditActionSet
set
=
new
EditActionSet();
int
offset = -1;
List<editactionset> list =
new
List<editactionset>();
for
(
int
k = 0; k < length; k++)
{
EditActionInfo info6 = array[k];
if
((info6.ChangedDate !=
set
.ChangedDate) || ((info6.ChangedBy != 0) && (info6.ChangedBy !=
set
.ChangedBy)))
{
if
(offset >= 0)
{
set
.Actions =
new
ArraySegment<editactioninfo>(array, offset, k - offset);
this
.FinishConstruction(
ref
set
);
list.Add(
set
);
}
set
=
new
EditActionSet();
set
.ChangedDate = info6.ChangedDate;
set
.ChangedBy = info6.ChangedBy;
offset = k;
}
set
.Flags |= ((
int
) 1) << (info6.Action
/ 2);
}
if
(offset >= 0)
{
set
.Actions =
new
ArraySegment<editactioninfo>(array, offset, length - offset);
this
.FinishConstruction(
ref
set
);
list.Add(
set
);
}
return
list.ToArray();
}
private
ArtifactId GetArtifact(System.Uri uri)
{
TeamFoundationTrace.Verbose(
"Entering WorkItem.GetArtifact, id = {0}, uri = {1}"
,
new
object
[] {
this
.Id, uri });
return
LinkingUtilities.DecodeUri(uri.ToString());
}
internal
bool
GetCalculatedFieldValue(
int
id,
int
revision,
out
object
value)
{
switch
(id)
{
case
-12:
value =
this
.CalculateNodeNameField(id, -2, revision);
return
true
;
case
-7:
value =
this
.CalculateTreePathField(id, -2, revision);
return
true
;
case
-1:
value =
this
.CalculateAuthorizedAsField(revision);
return
true
;
case
-56:
case
-55:
case
-54:
case
-53:
case
-52:
case
-51:
case
-50:
value =
this
.CalculateTreeLevelField(id, -50, -104, revision);
return
true
;
case
-49:
case
-48:
case
-47:
case
-46:
case
-45:
case
-44:
case
-43:
value =
this
.CalculateTreeLevelField(id, -43, -2, revision);
return
true
;
case
-42:
value = (
this
.Project !=
null
)
?
this
.Project.Name :
string
.Empty;
return
true
;
case
-105:
value =
this
.CalculateTreePathField(id, -104, revision);
return
true
;
}
if
(
this
.IsOpen)
{
switch
(id)
{
case
-32:
value =
this
.LinkData.ComputeLinkCount(0x33, revision);
return
true
;
case
-31:
value =
this
.LinkData.ComputeLinkCount(50, revision);
return
true
;
case
0x4b:
value =
this
.LinkData.ComputeLinkCount(0x25, revision);
return
true
;
case
-57:
value =
this
.LinkData.ComputeLinkCount(0x3a, revision);
return
true
;
}
}
value =
null
;
return
false
;
}
internal
object
GetFieldValue(
int
id,
int
revision)
{
if
(id == -3)
{
return
this
.m_id;
}
return
this
.m_fieldsData.GetFieldValue(id, revision);
}
internal
object
GetFieldValueExternal(FieldDefinition fd,
int
revision)
{
object
fieldValue =
this
.GetFieldValue(fd.Id, revision);
if
(fieldValue
is
ServerDefaultFieldValue)
{
fieldValue =
this
.GetFieldValue(fd.Id, revision - 1);
}
this
.ConvertFieldValueToExternal(
ref
fieldValue,
fd.SystemType);
return
fieldValue;
}
public
string
GetNextState(
string
action)
{
return
this
.Type.GetNextState(
this
.State,
action);
}
private
static
string
GetTempFileName(
string
path)
{
return
Path.Combine(path, Guid.NewGuid().ToString());
}
internal
void
HandleLinkCollectionChange(WorkItemLinkData.LinkInfo li, LinkAction action)
{
this
.FieldData.ResetChangedFields();
switch
(li.FieldId)
{
case
50:
if
((action == LinkAction.Added) || (action == LinkAction.Removed))
{
this
.ApplyFieldChange(-31,
this
.LinkData.ComputeLinkCount(50,
-2));
this
.FireFieldChangeEvent(-31);
}
this
.Attachments.HandleChange(li, action);
break
;
case
0x33:
if
((action == LinkAction.Added) || (action == LinkAction.Removed))
{
this
.ApplyFieldChange(-32,
this
.LinkData.ComputeLinkCount(0x33,
-2));
this
.FireFieldChangeEvent(-32);
}
this
.Links.HandleChange(li, action);
break
;
case
0x3a:
if
((action == LinkAction.Added) || (action == LinkAction.Removed))
{
this
.ApplyFieldChange(-57,
this
.LinkData.ComputeLinkCount(0x3a,
-2));
this
.FireFieldChangeEvent(-57);
}
this
.Links.HandleChange(li, action);
break
;
case
0x25:
if
((action == LinkAction.Added) || (action == LinkAction.Removed))
{
this
.ApplyFieldChange(0x4b,
this
.LinkData.ComputeLinkCount(0x25,
-2));
this
.FireFieldChangeEvent(0x4b);
}
this
.Links.HandleChange(li, action);
this
.WorkItemLinks.HandleChange(li, action);
break
;
}
this
.FieldData.FireEvents();
}
private
void
InitNew(WorkItemType type)
{
int
id = type.Project.Id;
this
.FieldData.SetUpdateFieldValue(-2, id, 0);
this
.FieldData.SetUpdateFieldValue(-104, id, 0);
this
.FieldData.SetUpdateFieldValue(0x19, type.Name, 0);
this
.m_type = type;
this
.m_project = type.Project;
}
internal
bool
? IsChangedInRevision(
int
id,
int
revision)
{
switch
(id)
{
case
-7:
case
-49:
case
-48:
case
-47:
case
-46:
case
-45:
case
-44:
case
-43:
case
-42:
case
-12:
id = -2;
break
;
case
-1:
id = -6;
break
;
case
0x4b:
case
-57:
case
-32:
case
-31:
return
null
;
case
-56:
case
-55:
case
-54:
case
-53:
case
-52:
case
-51:
case
-50:
case
-105:
id = -104;
break
;
}
return
this
.m_fieldsData.IsChangedInRevision(id, revision);
}
internal
bool
IsFieldValueValid(
int
id)
{
return
((
this
.FieldData.GetFieldState(id).Flags
& WorkItemFieldData.FieldFlags.InvalidMask) == 0);
}
public
bool
IsValid()
{
return
this
.FieldData.IsValid();
}
private
bool
IsValidUri(System.Uri uri)
{
TeamFoundationTrace.Verbose(
"Entering WorkItem.IsValidUri, id = {0}, uri = {1}"
,
new
object
[] {
this
.Id, uri });
if
(uri !=
null
)
{
try
{
ArtifactId artifact =
this
.GetArtifact(uri);
if
((TFStringComparer.ArtifactType.Equals(artifact.ArtifactType,
"WorkItem"
)
&& TFStringComparer.ArtifactTool.Equals(artifact.Tool,
"WorkItemTracking"
)) && (Convert.ToInt32(artifact.ToolSpecificId, CultureInfo.InvariantCulture) > 0))
{
return
true
;
}
TeamFoundationTrace.Verbose(
"Invalid Work Item URI: {0}"
,
new
object
[] { uri.ToString() });
TeamFoundationTrace.Verbose(
" This: {0}, {1}, {2}"
,
new
object
[] { artifact.ArtifactType, artifact.Tool, artifact.ToolSpecificId });
TeamFoundationTrace.Verbose(
" Should be: {0}, {1}, #>0"
,
new
object
[] {
"WorkItem"
,
"WorkItemTracking"
});
}
catch
{
TeamFoundationTrace.Error(
"Exception while parsing URI: {0}"
,
new
object
[] { uri.ToString() });
}
}
return
false
;
}
private
void
LoadWorkItem(
int
id,
int
rev, DateTime? asof)
{
IWorkItemRowSets sets;
this
.m_store.LoadWorkItem(id, rev, asof,
out
sets);
this
.m_asof = asof;
if
(!
this
.FieldData.LoadData(sets))
{
throw
new
DeniedOrNotExistException(ResourceStrings.ErrorWorkItemNotExistOrNoAccess);
}
this
.LinkData.LoadData(sets);
if
(rev != 0)
{
this
.m_asof =
new
DateTime?((DateTime)
this
.GetFieldValue(-4, -3));
}
this
.m_openState = OpenState.Opened;
this
.m_readonly =
null
;
this
.m_dataVersion++;
}
object
IRevisionInternal.GetCurrentFieldValue(FieldDefinition fd)
{
return
this
.GetFieldValueExternal(fd, -2);
}
object
IRevisionInternal.GetOriginalFieldValue(FieldDefinition fd)
{
return
this
.GetFieldValueExternal(fd, -3);
}
void
IRevisionInternal.SetFieldValue(FieldDefinition fd,
object
value)
{
this
.SetFieldValueExternal(fd, value);
}
public
void
Open()
{
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemOpenBegin);
TeamFoundationTrace.Verbose(
"Entering WorkItem.Open, id = {0}"
,
new
object
[] {
this
.Id });
if
(!
this
.IsNew && !
this
.IsOpen)
{
this
.LoadWorkItem(
this
.m_id,
0,
null
);
this
.ApplyRules();
this
.RefreshCachedData();
this
.FireWorkItemChangeEvent();
}
TeamFoundationTrace.Verbose(
"Exiting WorkItem.Open, id = {0}"
,
new
object
[] {
this
.Id });
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemOpenEnd);
}
public
void
PartialOpen()
{
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemPartialOpenBegin);
TeamFoundationTrace.Verbose(
"Entering WorkItem.PartialOpen, id = {0}"
,
new
object
[] {
this
.Id });
if
((!
this
.IsNew && !
this
.IsOpen)
&& !
this
.IsPartialOpen)
{
if
(
this
.m_list ==
null
)
{
throw
new
ValidationException(ResourceStrings.ErrorWorkItemNeedCollection);
}
if
(!
this
.m_list.QueryFieldValues(
this
.m_index,
null
))
{
throw
new
DeniedOrNotExistException();
}
this
.m_openState = OpenState.PartiallyOpened;
this
.ApplyRules();
this
.RefreshCachedData();
this
.FireWorkItemChangeEvent();
this
.CheckType();
}
TeamFoundationTrace.Verbose(
"Exiting WorkItem.Open, id = {0}"
,
new
object
[] {
this
.Id });
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemPartialOpenEnd);
}
internal
void
PostSave()
{
this
.LinkData.ProcessResultQueue();
this
.RefreshCachedData();
this
.FieldData.Reset();
this
.ApplyRules(
false
);
this
.m_IsUpdating =
false
;
this
.FireWorkItemChangeEvent();
}
internal
void
PostSaveError()
{
this
.m_IsUpdating =
false
;
}
internal
void
PreSave()
{
this
.m_IsUpdating =
true
;
this
.LinkData.Check();
this
.LinkData.ResetResultQueue();
this
.UploadAttachments();
}
internal
void
ProcessFieldChange(
int
id)
{
if
(
this
.m_fields !=
null
)
{
this
.m_fields.DropCachedData();
}
if
(
this
.IsValidType)
{
int
num = id;
switch
(num)
{
case
-105:
this
.ProcessTreePathField(-105, -104, Microsoft.TeamFoundation.WorkItemTracking.Client.DataStore.PsCSSType.CSSTypeIteration);
break
;
case
-104:
this
.ProcessTreeIdField(-104, -105, s_iterationDependentFieldIds);
break
;
case
-7:
this
.ProcessTreePathField(-7, -2, Microsoft.TeamFoundation.WorkItemTracking.Client.DataStore.PsCSSType.CSSTypeArea);
break
;
default
:
if
(num == -2)
{
this
.ProcessTreeIdField(-2, -7, s_areaDependentFieldIds);
}
break
;
}
this
.FieldData.RegisterChangedField(id);
}
}
private
void
ProcessTreeIdField(
int
fid,
int
fpath,
int
[] affected)
{
if
(
this
.IsFieldValueValid(fid))
{
object
fieldValue =
this
.GetFieldValue(fid, -2);
if
((fieldValue ==
null
) || (fieldValue
is
int
))
{
if
(!
this
.FieldData.ResetUpdateFieldValue(fpath))
{
this
.FieldData.RegisterChangedField(fpath);
}
if
(affected !=
null
)
{
for
(
int
i = 0; i < affected.Length; i++)
{
this
.FieldData.RegisterChangedField(affected[i]);
}
}
}
}
}
private
void
ProcessTreePathField(
int
fpath,
int
fid, Microsoft.TeamFoundation.WorkItemTracking.Client.DataStore.PsCSSType csstype)
{
if
(
this
.IsFieldValueValid(fpath))
{
object
fieldValue =
this
.GetFieldValue(fpath, -2);
if
(fieldValue ==
null
)
{
this
.FieldData.SetUpdateFieldValue(fpath, fieldValue, WorkItemFieldData.FieldFlags.InvalidPath);
}
else
if
(fieldValue
is
string
)
{
int
num =
this
.m_store.TreeIdFromPath(
this
.Project.Id, (
string
)
fieldValue, csstype);
if
(num != 0)
{
this
.SetFieldValue(fid, num, 0);
this
.FieldData.ResetUpdateFieldValue(fpath);
}
else
{
this
.FieldData.SetUpdateFieldValue(fpath, fieldValue, WorkItemFieldData.FieldFlags.InvalidPath);
}
}
}
}
internal
bool
QueryFieldValue(
int
field)
{
if
(
this
.m_list ==
null
)
{
return
false
;
}
if
(
this
.IsAccessDenied || !
this
.m_list.QueryFieldValues(
this
.m_index,
new
int
[] { field }))
{
throw
new
DeniedOrNotExistException();
}
return
true
;
}
private
void
RefreshCachedData()
{
if
(
this
.IsValidType)
{
if
(
this
.m_revisions !=
null
)
{
this
.m_revisions.Refresh();
}
if
(
this
.m_attachments !=
null
)
{
this
.m_attachments.Refresh();
}
if
(
this
.m_links !=
null
)
{
this
.m_links.Refresh();
}
if
(
this
.m_wlinks !=
null
)
{
this
.m_wlinks.Refresh();
}
if
(
this
.m_wlinksHistory !=
null
)
{
this
.m_wlinksHistory.Refresh();
}
if
(
this
.m_fields !=
null
)
{
this
.m_fields.DropCachedData();
}
}
this
.m_dirty =
null
;
}
public
void
Reset()
{
TeamFoundationTrace.Verbose(
"Entering WorkItem.Reset, id = {0}"
,
new
object
[] {
this
.Id });
this
.FieldData.Reset();
this
.LinkData.Reset();
if
(
this
.IsNew)
{
this
.InitNew(
this
.Type);
}
this
.ApplyRules();
this
.RefreshCachedData();
this
.FireWorkItemChangeEvent();
this
.CheckType();
}
internal
void
ResetDirty()
{
this
.m_dirty =
null
;
}
public
void
Save()
{
this
.Save(SaveFlags.None);
}
public
void
Save(SaveFlags saveFlags)
{
if
(
this
.IsDirty)
{
if
(!
this
.IsValid())
{
throw
new
ValidationException(ResourceStrings.ErrorWorkItemIsNotReadyToSave);
}
Node node =
null
;
object
fieldValue =
this
.GetFieldValue(-2, -2);
if
(fieldValue
is
int
)
{
node =
this
.m_store.TreeIdToNode((
int
)
fieldValue);
}
if
(node ==
null
)
{
throw
new
ValidationException(ResourceStrings.ErrorWorkItemIsNotReadyToSave);
}
if
(!node.HasWorkItemWriteRights)
{
throw
new
ValidationException(ResourceStrings.ErrorNoAreaWriteAccess);
}
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemSaveBegin);
TeamFoundationTrace.Verbose(
"Entering WorkItem.Save, id = {0}"
,
new
object
[] {
this
.Id });
try
{
this
.Store.SaveWorkItems(
new
WorkItem[]
{
this
},
false
, saveFlags);
}
catch
(WorkItemLinkValidationException exception)
{
throw
OME.TranslateLinkingValidationException(exception,
this
.m_store,
this
);
}
finally
{
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMWorkItemSaveEnd);
}
}
}
internal
void
SetAccessDenied()
{
this
.m_openState = OpenState.AccessDenied;
}
internal
void
SetFieldValue(
int
id,
object
value, WorkItemFieldData.FieldFlags flags)
{
if
(id == -3)
{
throw
new
ValidationException(ResourceStrings.ErrorCantModifyIdField);
}
bool
flag = (flags & (WorkItemFieldData.FieldFlags.SetByDefaultRule | WorkItemFieldData.FieldFlags.SetByRule))
== 0;
if
(
this
.FieldData.SetUpdateFieldValue(id,
value, flags) && flag)
{
this
.ApplyFieldChange(id, value);
}
}
internal
void
SetFieldValueExternal(FieldDefinition fd,
object
value)
{
this
.CheckType();
WorkItemFieldData.FieldFlags flags =
this
.ConvertFieldValueToInternal(
ref
value,
fd.SystemType);
if
(fd.Id == -2)
{
if
(!(value
is
int
) || !
this
.m_store.VerifyTreeId(
this
.Project.Id,
(
int
) value, Microsoft.TeamFoundation.WorkItemTracking.Client.DataStore.PsCSSType.CSSTypeArea))
{
throw
new
InvalidTreeNodeException();
}
}
else
if
((fd.Id == -104) && (!(value
is
int
) || !
this
.m_store.VerifyTreeId(
this
.Project.Id, (
int
)
value, Microsoft.TeamFoundation.WorkItemTracking.Client.DataStore.PsCSSType.CSSTypeIteration)))
{
throw
new
InvalidTreeNodeException();
}
object
fieldValue =
this
.GetFieldValue(fd.Id, -2);
if
((fd.Id == 9) || !
object
.Equals(value,
fieldValue))
{
if
(!fd.IsEditable)
{
throw
new
ValidationException(
string
.Format(CultureInfo.CurrentCulture, ResourceStrings.ErrorReadOnlyField,
new
object
[] { fd.Name }));
}
if
(fieldValue
is
ServerDefaultFieldValue)
{
if
((value !=
null
) && (!(value
is
string
) || (((
string
) value).Length != 0)))
{
throw
new
ValidationException(
string
.Format(CultureInfo.CurrentCulture, ResourceStrings.ErrorReadOnlyField,
new
object
[] { fd.Name }));
}
}
else
{
if
((fd.SystemType ==
typeof
(
string
)) && (value
is
string
))
{
string
s = (
string
) value;
if
((fd.FieldType == FieldType.String) && (s.Length >= 0x100))
{
flags |= WorkItemFieldData.FieldFlags.InvalidTooLong;
}
if
(!OMStringUtil.IsValidFieldValueString(s, fd.IsLongText))
{
flags |= WorkItemFieldData.FieldFlags.InvalidSpecialChars;
}
}
this
.FieldData.ResetChangedFields();
this
.SetFieldValue(fd.Id, value, flags);
this
.FieldData.FireEvents();
}
}
}
internal
void
SetListIndex(WorkItemCollection list,
int
index)
{
this
.m_list = list;
this
.m_index = index;
}
public
void
SyncToLatest()
{
TeamFoundationTrace.Verbose(
"Entering WorkItem.SyncToLatest, id = {0}"
,
new
object
[] {
this
.Id });
if
(!
this
.IsNew)
{
this
.FieldData.Reset();
this
.LinkData.Reset();
this
.LoadWorkItem(
this
.m_id,
0,
null
);
this
.ApplyRules();
this
.RefreshCachedData();
this
.FireWorkItemChangeEvent();
}
}
internal
void
TakeUpdateLinkResult(WorkItemLinkData.WorkItemLinkInfo li, XmlElement result)
{
this
.LinkData.TakeUpdateLinkResult(li, result);
this
.m_dataVersion++;
}
internal
void
TakeUpdateResult(XmlElement result)
{
int
num = XmlConvert.ToInt32(result.GetAttribute(
"ID"
));
int
newRev = XmlConvert.ToInt32(result.GetAttribute(
"Revision"
));
if
((
this
.IsNew ? (num == 0) : (num
!=
this
.m_id)) || (newRev == 0))
{
throw
new
UnexpectedErrorException(ResourceStrings.UnrecognizedServerData);
}
if
(
this
.m_id == 0)
{
this
.m_id = num;
this
.m_tempId =
this
.m_id;
}
this
.FieldData.TakeUpdateResult(result, newRev);
this
.LinkData.TakeUpdateResult(result);
this
.m_asof =
null
;
if
(
this
.m_openState == OpenState.New)
{
this
.m_openState = OpenState.Opened;
}
this
.m_readonly =
null
;
this
.m_dataVersion++;
}
private
void
UploadAttachments()
{
if
(
this
.LinkData.GetAddedLinksCount()
!= 0)
{
string
str =
this
.Project.Uri.ToString();
string
str2 =
string
.Empty;
if
(
this
.Project.Id ==
this
.AreaId)
{
str2 =
this
.Project.AreaRootNodeUri.ToString();
}
else
{
foreach
(Node node
in
this
.Project.AreaRootNodes)
{
if
(node.Id ==
this
.AreaId)
{
str2 = node.Uri.ToString();
break
;
}
try
{
str2 = node.FindNodeInSubTree(
this
.AreaId).Uri.ToString();
break
;
}
catch
(DeniedOrNotExistException)
{
continue
;
}
}
}
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMAttachmentUploadBegin);
WorkItemServer clientService =
this
.Store.ClientService;
TfsWebClient client =
null
;
foreach
(WorkItemLinkData.AttachmentInfo info
in
this
.LinkData.GetAddedLinks(50))
{
if
(info.IsUploaded)
{
continue
;
}
if
(info.FileInfo ==
null
)
{
if
(!info.IsLocalCopy)
{
continue
;
}
if
(client ==
null
)
{
client =
new
TfsWebClient(
this
.m_store.TeamProjectCollection);
}
this
.CreateLocalCopy(client, info);
}
try
{
info.FileInfo.Refresh();
if
(!info.FileInfo.Exists || (info.LastWriteDate.Ticks != info.FileInfo.LastWriteTimeUtc.Ticks))
{
throw
new
FileAttachmentException(
string
.Format(CultureInfo.CurrentCulture, ResourceStrings.AttachmentChangedException,
new
object
[] { info.FileInfo.FullName }),
new
Attachment(
this
, info));
}
if
(info.FileInfo.Length > clientService.MaxAttachmentSize)
{
clientService.UpdateMaxAttachmentSize();
if
(info.FileInfo.Length > clientService.MaxAttachmentSize)
{
throw
new
FileAttachmentException(
string
.Format(CultureInfo.CurrentCulture, ResourceStrings.FileUploadedExceededMax,
new
object
[] { info.Attribute, clientService.MaxAttachmentSize }),
new
Attachment(
this
, info));
}
}
using
(Stream stream = info.FileInfo.OpenRead())
{
FileAttachment fileAttachment =
new
FileAttachment();
fileAttachment.FileNameGUID =
new
Guid(info.Path);
fileAttachment.AreaNodeUri = str2;
fileAttachment.ProjectUri = str;
fileAttachment.LocalFile = stream;
clientService.UploadFile(fileAttachment);
}
info.IsUploaded =
true
;
}
catch
(FileAttachmentException)
{
throw
;
}
catch
(FileNotFoundException exception)
{
throw
new
FileAttachmentException(
string
.Format(CultureInfo.CurrentCulture, ResourceStrings.AttachmentNotFoundException,
new
object
[] { info.FileInfo.FullName }),
new
Attachment(
this
, info), exception);
}
catch
(Exception exception2)
{
throw
new
FileAttachmentException(
string
.Format(CultureInfo.CurrentCulture, ResourceStrings.ErrorAttachmentUploadFailed,
new
object
[] { exception2.Message }), exception2);
}
finally
{
if
(info.IsLocalCopy && (info.FileInfo !=
null
))
{
info.FileInfo.Delete();
info.FileInfo =
null
;
}
if
(client !=
null
)
{
client.Dispose();
}
}
info.IsLocalCopy =
false
;
}
Microsoft.TeamFoundation.Common.Marker.Process(Microsoft.TeamFoundation.Common.Mark.OMAttachmentUploadEnd);
}
}
public
ArrayList Validate()
{
return
this
.FieldData.Validate();
}
public
int
AreaId
{
get
{
object
obj2 =
this
[CoreField.AreaId];
if
(obj2 !=
null
)
{
return
(
int
) obj2;
}
return
0;
}
set
{
this
[CoreField.AreaId] = value;
}
}
public
string
AreaPath
{
get
{
return
(
string
)
this
[CoreField.AreaPath];
}
set
{
this
[CoreField.AreaPath] = value;
}
}
internal
DateTime? AsOfUTC
{
get
{
return
this
.m_asof;
}
}
public
int
AttachedFileCount
{
get
{
object
obj2 =
this
[CoreField.AttachedFileCount];
if
(obj2 !=
null
)
{
return
(
int
) obj2;
}
return
0;
}
}
public
AttachmentCollection Attachments
{
get
{
if
(
this
.m_attachments ==
null
)
{
this
.m_attachments =
new
AttachmentCollection(
this
, -2);
}
return
this
.m_attachments;
}
}
public
string
ChangedBy
{
get
{
return
(
string
)
this
[CoreField.ChangedBy];
}
}
public
DateTime ChangedDate
{
get
{
object
obj2 =
this
[CoreField.ChangedDate];
if
(obj2 !=
null
)
{
return
(DateTime) obj2;
}
return
DateTime.MinValue;
}
}
public
string
CreatedBy
{
get
{
return
(
string
)
this
[CoreField.CreatedBy];
}
}
public
DateTime CreatedDate
{
get
{
object
obj2 =
this
[CoreField.CreatedDate];
if
(obj2 !=
null
)
{
return
(DateTime) obj2;
}
return
DateTime.MinValue;
}
}
public
string
Description
{
get
{
return
(
string
)
this
[CoreField.Description];
}
set
{
this
[CoreField.Description] = value;
}
}
public
string
DisplayForm
{
get
{
return
this
.Type.DisplayForm;
}
}
public
int
ExternalLinkCount
{
get
{
object
obj2 =
this
[CoreField.ExternalLinkCount];
if
(obj2 !=
null
)
{
return
(
int
) obj2;
}
return
0;
}
}
internal
WorkItemFieldData FieldData
{
get
{
return
this
.m_fieldsData;
}
}
public
FieldCollection Fields
{
get
{
if
(
this
.m_fields ==
null
)
{
this
.m_fields =
new
FieldCollection(
this
,
this
.Type.FieldDefinitions);
}
return
this
.m_fields;
}
}
public
string
History
{
get
{
return
(
string
)
this
[CoreField.History];
}
set
{
this
[CoreField.History] = value;
}
}
public
int
HyperLinkCount
{
get
{
object
obj2 =
this
[CoreField.HyperLinkCount];
if
(obj2 !=
null
)
{
return
(
int
) obj2;
}
return
0;
}
}
public
int
Id
{
get
{
return
this
.m_id;
}
}
internal
int
InternalVersion
{
get
{
return
this
.m_dataVersion;
}
}
internal
bool
IsAccessDenied
{
get
{
if
((
this
.m_openState == OpenState.Queried)
&& (
this
.m_list !=
null
))
{
this
.m_list.QueryFieldValues(
this
.m_index,
new
int
[] { -2 });
}
return
(
this
.m_openState == OpenState.AccessDenied);
}
}
public
bool
IsDirty
{
get
{
if
(!
this
.m_dirty.HasValue)
{
this
.m_dirty =
false
;
bool
? dirty =
this
.m_dirty;
this
.m_dirty =
this
.FieldData.IsDirty()
? ((
bool
?)
true
) : dirty;
bool
? nullable2 =
this
.m_dirty;
this
.m_dirty =
this
.LinkData.IsDirty()
? ((
bool
?)
true
) : nullable2;
}
return
this
.m_dirty.Value;
}
}
public
bool
IsNew
{
get
{
return
(
this
.m_id == 0);
}
}
public
bool
IsOpen
{
get
{
if
(
this
.m_openState != OpenState.New)
{
return
(
this
.m_openState ==
OpenState.Opened);
}
return
true
;
}
}
public
bool
IsPartialOpen
{
get
{
return
(
this
.m_openState == OpenState.PartiallyOpened);
}
}
public
bool
IsReadOnly
{
get
{
if
(!
this
.m_readonly.HasValue)
{
object
fieldValue =
this
.GetFieldValue(-2, -3);
if
(fieldValue
is
int
)
{
Node node =
this
.m_store.TreeIdToNode((
int
)
fieldValue);
if
(node !=
null
)
{
this
.m_readonly =
new
bool
?(!node.HasWorkItemWriteRights);
}
}
}
if
(
this
.m_readonly.HasValue &&
!
this
.m_readonly.Value)
{
return
!
this
.IsValidType;
}
return
true
;
}
}
public
bool
IsReadOnlyOpen
{
get
{
if
(!
this
.IsOpen && !
this
.IsPartialOpen)
{
return
false
;
}
return
this
.IsReadOnly;
}
}
internal
bool
IsRevised
{
get
{
DateTime revisedDate =
this
.RevisedDate;
return
((revisedDate != DateTime.MinValue) && (revisedDate < WorkItemStore.FutureDateTimeValue));
}
}
private
bool
IsValidType
{
get
{
this
.CheckUpdateCachedData();
return
(
this
.m_type !=
null
);
}
}
public
object
this
[
string
name]
{
get
{
if
(name ==
null
)
{
throw
new
ArgumentNullException(
"name"
);
}
return
this
.Fields[name].Value;
}
set
{
if
(name ==
null
)
{
throw
new
ArgumentNullException(
"name"
);
}
this
.Fields[name].Value = value;
}
}
public
object
this
[CoreField id]
{
get
{
return
this
.Fields[id].Value;
}
set
{
this
.Fields[id].Value = value;
}
}
public
int
IterationId
{
get
{
object
obj2 =
this
[CoreField.IterationId];
if
(obj2 !=
null
)
{
return
(
int
) obj2;
}
return
0;
}
set
{
this
[CoreField.IterationId] = value;
}
}
public
string
IterationPath
{
get
{
return
(
string
)
this
[CoreField.IterationPath];
}
set
{
this
[CoreField.IterationPath] = value;
}
}
internal
WorkItemLinkData LinkData
{
get
{
return
this
.m_linksData;
}
}
public
LinkCollection Links
{
get
{
if
(
this
.m_links ==
null
)
{
this
.m_links =
new
LinkCollection(
this
, -2);
}
return
this
.m_links;
}
}
bool
IRevisionInternal.IsReadOnly
{
get
{
return
false
;
}
}
int
IRevisionInternal.Number
{
get
{
return
-2;
}
}
WorkItem IRevisionInternal.WorkItem
{
get
{
return
this
;
}
}
public
string
NodeName
{
get
{
return
(
string
)
this
[CoreField.NodeName];
}
}
public
Microsoft.TeamFoundation.WorkItemTracking.Client.Project Project
{
get
{
this
.CheckUpdateCachedData();
if
(
this
.m_project ==
null
)
{
throw
new
DeniedOrNotExistException(
string
.Format(CultureInfo.CurrentCulture, ResourceStrings.ErrorProjectNotExist,
new
object
[] {
string
.Empty }));
}
return
this
.m_project;
}
}
public
string
Reason
{
get
{
return
(
string
)
this
[CoreField.Reason];
}
set
{
this
[CoreField.Reason] = value;
}
}
public
int
RelatedLinkCount
{
get
{
object
obj2 =
this
[CoreField.RelatedLinkCount];
if
(obj2 !=
null
)
{
return
(
int
) obj2;
}
return
0;
}
}
public
int
Rev
{
get
{
return
this
.Revision;
}
}
public
DateTime RevisedDate
{
get
{
object
obj2 =
this
[CoreField.RevisedDate];
if
(obj2 !=
null
)
{
return
(DateTime) obj2;
}
return
DateTime.MinValue;
}
}
public
int
Revision
{
get
{
object
obj2 =
this
[CoreField.Rev];
if
(obj2 !=
null
)
{
return
(
int
) obj2;
}
return
0;
}
}
public
RevisionCollection Revisions
{
get
{
if
(
this
.m_revisions ==
null
)
{
this
.m_revisions =
new
RevisionCollection(
this
);
}
return
this
.m_revisions;
}
}
public
string
State
{
get
{
return
(
string
)
this
[CoreField.State];
}
set
{
this
[CoreField.State] = value;
}
}
public
WorkItemStore Store
{
get
{
return
this
.m_store;
}
}
public
int
TemporaryId
{
get
{
return
this
.m_tempId;
}
}
public
string
Title
{
get
{
return
(
string
)
this
[CoreField.Title];
}
set
{
this
[CoreField.Title] = value;
}
}
public
WorkItemType Type
{
get
{
this
.CheckUpdateCachedData();
if
(
this
.m_type ==
null
)
{
throw
new
WorkItemTypeDeniedOrNotExistException(
string
.Format(CultureInfo.CurrentCulture, ResourceStrings.ErrorWorkItemTypeNotExist,
new
object
[] {
string
.Empty }));
}
return
this
.m_type;
}
}
public
System.Uri Uri
{
get
{
TeamFoundationTrace.Verbose(
"Entering WorkItem.Uri/Get, id = {0}"
,
new
object
[] {
this
.Id });
ArtifactId artifactId =
new
ArtifactId();
artifactId.ArtifactType =
"WorkItem"
;
artifactId.Tool =
"WorkItemTracking"
;
artifactId.ToolSpecificId =
this
.Id.ToString(CultureInfo.InvariantCulture);
artifactId.VisualStudioServerNamespace =
this
.Store.TeamProjectCollection.Uri.AbsoluteUri;
return
new
System.Uri(LinkingUtilities.EncodeUri(artifactId));
}
}
public
WorkItemLinkCollection WorkItemLinkHistory
{
get
{
if
(
this
.m_wlinksHistory ==
null
)
{
this
.m_wlinksHistory =
new
WorkItemLinkCollection(
this
, -4);
}
return
this
.m_wlinksHistory;
}
}
public
WorkItemLinkCollection WorkItemLinks
{
get
{
if
(
this
.m_wlinks ==
null
)
{
this
.m_wlinks =
new
WorkItemLinkCollection(
this
, -2);
}
return
this
.m_wlinks;
}
}
private
class
BrieCallBack : IBrieCallBack
{
private
Dictionary<
int
,
bool
=
""
>
m_changes;
private
WorkItemFieldData.FieldFlags m_flags;
private
Dictionary<
int
, workitemfielddata.fieldinfo=
""
>
m_states;
private
Dictionary<
int
, workitemfielddata.fieldupdate=
""
>
m_updates;
private
WorkItem m_workitem;
public
BrieCallBack(WorkItem wi)
{
this
.m_workitem = wi;
this
.m_states =
new
Dictionary<
int
, workitemfielddata.fieldinfo=
""
>();
this
.m_updates =
new
Dictionary<
int
, workitemfielddata.fieldupdate=
""
>();
this
.m_changes =
new
Dictionary<
int
,
bool
=
""
>();
this
.m_flags = WorkItemFieldData.FieldFlags.SetByRule;
}
int
IBrieCallBack.GetTreeId(
bool
oldValue)
{
object
fieldValue =
this
.m_workitem.GetFieldValue(-2, oldValue ? -3 : -2);
if
(fieldValue ==
null
)
{
return
-1;
}
return
(
int
) fieldValue;
}
object
IBrieCallBack.GetValue(
int
fieldId,
bool
oldValue)
{
object
fieldValue;
WorkItemFieldData.FieldUpdate update;
if
(!oldValue && (
this
.m_updates.TryGetValue(fieldId,
out
update) ||
this
.m_workitem.FieldData.GetUpdateFieldValue(fieldId,
out
update)))
{
fieldValue = update.Value;
}
else
{
fieldValue =
this
.m_workitem.GetFieldValue(fieldId, oldValue ?
-3 : -2);
}
if
(fieldValue
is
Guid)
{
fieldValue = ((Guid) fieldValue).ToString();
}
return
fieldValue;
}
void
IBrieCallBack.InvalidateField(
int
fieldId)
{
}
void
IBrieCallBack.SetProperties(
int
fieldId,
BrieComputedFieldFlags externalFlags, BrieComputedFieldFlags suggestedFlags, BrieComputedFieldFlags requiredFlags, BrieComputedFieldFlags forbiddenFlags, BrieComputedFieldFlags requiredStatus, BrieComputedFieldFlags forbiddenStatus,
string
[]
values,
string
[] formats,
string
[] forbiddenValues)
{
WorkItemFieldData.FieldFlags readOnly = 0;
FieldDefinition definition =
this
.m_workitem.Store.FieldDefinitions.TryGetById(fieldId);
if
(definition !=
null
)
{
if
(definition.IsComputed)
{
readOnly = WorkItemFieldData.FieldFlags.ReadOnly;
}
else
{
if
((requiredFlags & BrieComputedFieldFlags.ComputedFieldFlagSameAsBefore) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.ReadOnly;
}
if
((requiredFlags & BrieComputedFieldFlags.ComputedFieldFlagEmpty) != 0)
{
object
fieldValue =
this
.m_workitem.GetFieldValue(fieldId, -2);
if
((fieldValue ==
null
) || ((fieldValue
is
string
) &&
string
.IsNullOrEmpty((
string
) fieldValue)))
{
readOnly |= WorkItemFieldData.FieldFlags.ReadOnly;
}
}
if
((requiredFlags & BrieComputedFieldFlags.ComputedFieldFlagPattern) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.HasFormats;
}
if
((requiredFlags & BrieComputedFieldFlags.ComputedFieldFlagList) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.LimitedToValues;
if
((requiredFlags & BrieComputedFieldFlags.ComputedFieldFlagKeepEmpty) == 0)
{
readOnly |= WorkItemFieldData.FieldFlags.Required;
}
}
if
((requiredFlags & BrieComputedFieldFlags.ComputedFieldFlagPattern) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.LimitedToFormats;
if
((requiredFlags & BrieComputedFieldFlags.ComputedFieldFlagKeepEmpty) == 0)
{
readOnly |= WorkItemFieldData.FieldFlags.Required;
}
}
if
((forbiddenFlags & BrieComputedFieldFlags.ComputedFieldFlagEmpty) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.Required;
}
if
((externalFlags & BrieComputedFieldFlags.ComputedFieldFlagList) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.HasValues;
}
if
((externalFlags & BrieComputedFieldFlags.ComputedFieldFlagPattern) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.HasFormats;
}
if
((externalFlags & BrieComputedFieldFlags.ComputedFieldFlagIncludeOldValue) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.AllowsOldValue;
}
if
((requiredStatus | forbiddenStatus) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidRule;
if
((requiredStatus & BrieComputedFieldFlags.ComputedFieldFlagEmpty) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidNotEmpty;
}
if
((forbiddenStatus & BrieComputedFieldFlags.ComputedFieldFlagEmpty) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidEmpty;
}
if
((requiredStatus & BrieComputedFieldFlags.ComputedFieldFlagList) != 0)
{
if
((requiredStatus & BrieComputedFieldFlags.ComputedFieldFlagKeepEmpty) == 0)
{
object
obj3 =
this
.m_workitem.GetFieldValue(fieldId, -2);
if
((obj3 ==
null
) || ((obj3
is
string
) &&
string
.IsNullOrEmpty((
string
) obj3)))
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidEmpty;
}
else
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidListValue;
}
}
else
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidListValue;
}
}
if
((forbiddenStatus & BrieComputedFieldFlags.ComputedFieldFlagList) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidListValue;
}
if
((requiredStatus & BrieComputedFieldFlags.ComputedFieldFlagPattern) != 0)
{
if
((requiredStatus & BrieComputedFieldFlags.ComputedFieldFlagKeepEmpty) == 0)
{
object
obj4 =
this
.m_workitem.GetFieldValue(fieldId, -2);
if
((obj4 ==
null
) || ((obj4
is
string
) &&
string
.IsNullOrEmpty((
string
) obj4)))
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidEmpty;
}
else
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidFormat;
}
}
else
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidFormat;
}
}
if
((forbiddenStatus & BrieComputedFieldFlags.ComputedFieldFlagPattern) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidFormat;
}
if
((requiredStatus & BrieComputedFieldFlags.ComputedFieldFlagSameAsBefore) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidNotOldValue;
}
if
((forbiddenStatus & BrieComputedFieldFlags.ComputedFieldFlagSameAsBefore) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidOldValue;
}
if
((requiredStatus & BrieComputedFieldFlags.ComputedFieldFlagEmptyOrSameAsBefore) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidNotEmptyOrOldValue;
}
if
((forbiddenStatus & BrieComputedFieldFlags.ComputedFieldFlagEmptyOrSameAsBefore) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidEmptyOrOldValue;
}
if
((requiredStatus & BrieComputedFieldFlags.ComputedFieldFlagValueInOtherField) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidValueNotInOtherField;
}
if
((forbiddenStatus & BrieComputedFieldFlags.ComputedFieldFlagValueInOtherField) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidValueInOtherField;
}
if
((requiredStatus & BrieComputedFieldFlags.ComputedFieldFlagUnderlying) != 0)
{
readOnly |= WorkItemFieldData.FieldFlags.InvalidComputedField;
}
}
}
WorkItemFieldData.FieldInfo info =
new
WorkItemFieldData.FieldInfo();
info.Id = fieldId;
info.Flags = readOnly;
info.Values = values;
info.Formats = formats;
info.ProhibitedValues = forbiddenValues;
this
.m_states[fieldId] = info;
}
}
bool
IBrieCallBack.SetValue(
int
fieldId,
object
value)
{
WorkItemFieldData.FieldUpdate update;
WorkItemFieldData.FieldFlags flags = WorkItemFieldData.FieldFlags.SetByRule |
this
.m_flags;
FieldDefinition definition =
this
.m_workitem.Store.FieldDefinitions.TryGetById(fieldId);
if
((definition ==
null
) || definition.IsComputed)
{
return
false
;
}
if
((value
is
string
) && (definition.SystemType != value.GetType()))
{
try
{
value =
this
.m_workitem.FieldData.ConvertFromXml((
string
)
value, definition.SystemType);
}
catch
(FormatException)
{
flags |= WorkItemFieldData.FieldFlags.InvalidType;
}
catch
(OverflowException)
{
flags |= WorkItemFieldData.FieldFlags.InvalidType;
}
}
if
(
this
.m_updates.TryGetValue(fieldId,
out
update) && ((update.Flags & WorkItemFieldData.FieldFlags.SetByDefaultRule) == 0))
{
return
false
;
}
update =
new
WorkItemFieldData.FieldUpdate();
update.Value = value;
update.Flags = flags;
this
.m_updates[fieldId] = update;
this
.m_changes[fieldId] =
true
;
return
true
;
}
public
Dictionary<
int
,
bool
=
""
>
ResetChanges()
{
Dictionary<
int
,
bool
=
""
>
changes =
this
.m_changes;
this
.m_changes =
new
Dictionary<
int
,
bool
=
""
>();
return
changes;
}
public
void
SetFieldUpdateFlags(WorkItemFieldData.FieldFlags fieldFlags)
{
this
.m_flags = fieldFlags;
}
public
Dictionary<
int
, workitemfielddata.fieldinfo=
""
>
FieldStates
{
get
{
return
this
.m_states;
}
}
public
Dictionary<
int
, workitemfielddata.fieldupdate=
""
>
FieldUpdates
{
get
{
return
this
.m_updates;
}
}
}
internal
enum
EditAction
{
None,
Revision,
AddAttachment,
DelAttachment,
AddHyperLink,
DelHyperLink,
AddExternalLink,
DelExternalLink,
AddWorkItemLink,
DelWorkItemLink
}
[Flags]
internal
enum
EditActionFlags
{
AttachmentChanges = 2,
ExternalLinkChanges = 8,
FieldChanges = 1,
HyperLinkChanges = 4,
WorkItemLinkChanges = 0x10
}
[StructLayout(LayoutKind.Sequential)]
internal
struct
EditActionInfo
{
public
WorkItem.EditAction Action;
public
DateTime ChangedDate;
public
int
ChangedBy;
public
int
Index;
}
private
class
EditActionInfoComparator : IComparer<workitem.editactioninfo>
{
private
WorkItem m_item;
public
EditActionInfoComparator(WorkItem w)
{
this
.m_item = w;
}
public
int
Compare(WorkItem.EditActionInfo x, WorkItem.EditActionInfo y)
{
int
num = DateTime.Compare(x.ChangedDate, y.ChangedDate);
if
(num == 0)
{
num = (
int
) (x.Action - y.Action);
}
if
(((num == 0) && (x.ChangedBy != 0)) && (y.ChangedBy != 0))
{
num = x.ChangedBy - y.ChangedBy;
}
if
((num == 0) && ((x.Action == WorkItem.EditAction.AddWorkItemLink) || (x.Action == WorkItem.EditAction.DelWorkItemLink)))
{
WorkItemLinkData.WorkItemLinkInfo actionObject = (WorkItemLinkData.WorkItemLinkInfo)
this
.m_item.GetActionObject(x);
WorkItemLinkData.WorkItemLinkInfo info2 = (WorkItemLinkData.WorkItemLinkInfo)
this
.m_item.GetActionObject(y);
num = actionObject.LinkType - info2.LinkType;
if
(num == 0)
{
num = actionObject.TargetId - info2.TargetId;
}
}
return
num;
}
}
[StructLayout(LayoutKind.Sequential)]
internal
struct
EditActionSet
{
public
DateTime ChangedDate;
public
int
ChangedBy;
public
string
Tag;
public
string
Description;
public
WorkItem.EditActionFlags Flags;
public
ArraySegment<workitem.editactioninfo> Actions;
}
private
enum
OpenState
{
Undefined,
New,
Queried,
PartiallyOpened,
Opened,
AccessDenied
}
}
}
[tfs] workitemtracking source code,布布扣,bubuko.com
[tfs] workitemtracking source code
原文:http://blog.csdn.net/wzhiu/article/details/21008959