in source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/clients/versioncontrol/soapextensions/Workspace.java [3552:3780]
public int pendAdd(
final String[] paths,
final boolean recursive,
final LockLevel lockLevel,
final GetOptions getOptions,
PendChangesOptions pendOptions,
final Map<String, FileEncoding> encodingHints,
final FileEncoding defaultEncoding) {
Check.notNullOrEmpty(paths, "paths"); //$NON-NLS-1$
Check.notNull(lockLevel, "lockLevel"); //$NON-NLS-1$
Check.notNull(getOptions, "getOptions"); //$NON-NLS-1$
Check.notNull(pendOptions, "pendOptions"); //$NON-NLS-1$
/*
* Determine if we want to show errors around files already exsiting in
* source control. We only want to show those errors if the user
* explicitly passed that path in. As a heuristic we won't show errors
* if any wildcard or recursion is passed in.
*/
boolean showItemExistsFailures = !recursive;
if (!recursive) {
// Check for wildcards since there is no recursion.
for (final String path : paths) {
showItemExistsFailures &= !ItemPath.isWildcard(path);
}
}
if (!showItemExistsFailures) {
pendOptions = pendOptions.combine(PendChangesOptions.SUPPRESS_ITEM_NOT_FOUND_FAILURES);
}
// Walk the file system and find the files matching fileSpecs.
final FileSystemWalker walker = new FileSystemWalker(
this,
paths,
recursive,
true,
pendOptions.contains(PendChangesOptions.TREAT_MISSING_ITEMS_AS_FILES),
pendOptions.contains(PendChangesOptions.APPLY_LOCAL_ITEM_EXCLUSIONS));
final List<ChangeRequest> requests = new ArrayList<ChangeRequest>();
final List<ChangeRequest> propertyRequests = new ArrayList<ChangeRequest>();
final List<ItemSpec> itemSpecs = new ArrayList<ItemSpec>();
// Ugh
final PendChangesOptions finalPendChangesOptions = pendOptions;
walker.walk(new FileSystemVisitor() {
@Override
public void visit(final String path) {
final ItemType missingItemsItemType =
finalPendChangesOptions.contains(PendChangesOptions.TREAT_MISSING_ITEMS_AS_FILES) ? ItemType.FILE
: ItemType.ANY;
final FileSystemAttributes attrs = FileSystemUtils.getInstance().getAttributes(path);
// Detect the item type and code page
final ItemType itemType;
final int codePage;
if (!attrs.exists()) {
if (missingItemsItemType == ItemType.ANY) {
// The file disappeared.
throw new VersionControlException(
MessageFormat.format(Messages.getString("Workspace.FileOrFolderNotFoundFormat"), path)); //$NON-NLS-1$
} else {
itemType = missingItemsItemType;
// Use binary code page for missing files
codePage = VersionControlConstants.ENCODING_BINARY;
}
} else {
if (attrs.isSymbolicLink()) {
itemType = ItemType.FILE;
// Encoding for a symbolic link doesn't matter
codePage = VersionControlConstants.ENCODING_BINARY;
} else if (!attrs.isDirectory()) {
itemType = ItemType.FILE;
FileEncoding encoding = encodingHints != null ? encodingHints.get(path) : defaultEncoding;
if (encoding == null) {
encoding = FileEncoding.AUTOMATICALLY_DETECT;
}
codePage = FileEncodingDetector.detectEncoding(path, encoding).getCodePage();
} else {
itemType = ItemType.FOLDER;
// Encoding for a directory doesn't matter
codePage = VersionControlConstants.ENCODING_BINARY;
}
}
try {
final ItemSpec spec = new ItemSpec(path, RecursionType.NONE);
itemSpecs.add(spec);
final ChangeRequest cr =
new ChangeRequest(spec, null, RequestType.ADD, itemType, codePage, lockLevel, 0, null, true);
/*
* TEE-specific code to detect Unix execute bit. We can only
* pend one type of change at a time, so this is a separate
* request.
*/
if (Platform.isCurrentPlatform(Platform.GENERIC_UNIX)) {
if (PlatformMiscUtils.getInstance().getEnvironmentVariable(
EnvironmentVariables.DISABLE_SYMBOLIC_LINK_PROP) == null && attrs.isSymbolicLink()) {
if (isLocalWorkspace()) {
cr.setProperties(new PropertyValue[] {
PropertyConstants.IS_SYMLINK
});
} else {
final ChangeRequest r = new ChangeRequest(
spec,
null,
RequestType.PROPERTY,
itemType,
codePage,
lockLevel,
0,
null,
true);
r.setProperties(new PropertyValue[] {
PropertyConstants.IS_SYMLINK
});
propertyRequests.add(r);
}
} else if (!attrs.isDirectory()
&& attrs.isExecutable()
&& PlatformMiscUtils.getInstance().getEnvironmentVariable(
EnvironmentVariables.DISABLE_DETECT_EXECUTABLE_PROP) == null) {
if (isLocalWorkspace()) {
cr.setProperties(new PropertyValue[] {
PropertyConstants.EXECUTABLE_ENABLED_VALUE
});
} else {
final ChangeRequest r = new ChangeRequest(
spec,
null,
RequestType.PROPERTY,
itemType,
codePage,
lockLevel,
0,
null,
false);
r.setProperties(new PropertyValue[] {
PropertyConstants.EXECUTABLE_ENABLED_VALUE
});
propertyRequests.add(r);
}
}
}
requests.add(cr);
} catch (final ChangeRequestValidationException e) {
log.info("Cannot create change request:", e); //$NON-NLS-1$
// Shouldn't happen for adds
client.getEventEngine().fireNonFatalError(
new NonFatalErrorEvent(EventSource.newFromHere(), Workspace.this, e));
}
}
});
// Return now if there's nothing left to do.
if (requests.size() == 0) {
// No items matched.
return 0;
}
final int numPended =
pendChanges(requests.toArray(new ChangeRequest[requests.size()]), getOptions, pendOptions, null);
if (numPended > 0 && propertyRequests.size() > 0) {
if (getClient().getServiceLevel().getValue() >= WebServiceLevel.TFS_2012.getValue()) {
final PendingSet set = getPendingChanges(itemSpecs.toArray(new ItemSpec[itemSpecs.size()]), false);
if (set != null && set.getPendingChanges() != null && set.getPendingChanges().length > 0) {
final HashSet<String> newAdds = new HashSet<String>();
final PendingChange[] pendingChanges = set.getPendingChanges();
for (final PendingChange pc : pendingChanges) {
if (pc.isAdd()) {
newAdds.add(pc.getLocalItem());
}
}
final List<ChangeRequest> propRequests = new ArrayList<ChangeRequest>();
for (final ChangeRequest r : propertyRequests) {
if (newAdds.contains(r.getItemSpec().getItem())) {
propRequests.add(r);
}
}
if (propRequests.size() > 0) {
pendChanges(
propRequests.toArray(new ChangeRequest[propRequests.size()]),
GetOptions.NONE,
pendOptions,
null);
}
}
} else {
client.getEventEngine().fireNonFatalError(
new NonFatalErrorEvent(
EventSource.newFromHere(),
this,
new VersionControlException(Messages.getString("Workspace.PropertyNotSupportedText")))); //$NON-NLS-1$
}
}
// Report warnings for any applied exclusions
final String[] exclusionsApplied = walker.getExclusionsApplied();
if (exclusionsApplied.length > 0) {
final String exclusionsList = StringUtil.join(exclusionsApplied, ";"); //$NON-NLS-1$
client.getEventEngine().fireNonFatalError(
new NonFatalErrorEvent(
EventSource.newFromHere(),
this,
new Exception(
MessageFormat.format(
Messages.getString("Workspace.ItemsIgnoredBecauseOfExclusionsFormat"), //$NON-NLS-1$
exclusionsList))));
}
return numPended;
}