public void deploy(ForceProject project, ComponentList list, IProgressMonitor monitor) {
//TODO: Optimize for the case of a single save, where we can just use the ContainerAsyncRequest without MetadataContainer
try {
clearSaveLocallyOnlyMarkers(list);
ToolingStubExt stub = factoryLocator.getToolingFactory().getToolingStubExt(project);
MetadataContainer container = new MetadataContainer();
container.setName(constructProjectIdentifier(project));
SaveResult[] containerResults = stub.create(new SObject[] { container });
if (containerResults[0].isSuccess()) {
String containerId = containerResults[0].getId();
SObject[] classMembers = createContainerMembers(containerId, list);
SaveResult[] classMemberResults = stub.create(classMembers);
boolean allClassMembersCreatedSuccessfully =
Iterables.all(Lists.newArrayList(classMemberResults), new Predicate<SaveResult>() {
@Override
public boolean apply(SaveResult result) {
return result.isSuccess();
}
});
if (allClassMembersCreatedSuccessfully) {
ContainerAsyncRequest request = new ContainerAsyncRequest();
request.setIsCheckOnly(false);
request.setMetadataContainerId(containerId);
SaveResult[] requestResults = stub.create(new SObject[] { request });
if (requestResults[0].isSuccess()) {
ContainerAsyncRequest onGoingRequest = pollForStatus(stub, requestResults, monitor);
handleContainerAsyncMessages(list, onGoingRequest);
} else {
handleContainerAsyncRequestCreationFailure(list, requestResults);
}
} else {
handleClassMembersCreationFailure(list, classMemberResults);
}
// Clean up and delete the container member (this also deletes any ContainerMembers still referencing it)
// If deletion fails, we will see a duplicate container error the next time we deploy and handle it there.
stub.delete(new String[] { containerResults[0].getId() });
} else {
handleMetadataContainerCreationFailure(project, stub, list, containerResults);
}