/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.plugin.pullrequest.client.steps; import org.eclipse.che.plugin.pullrequest.client.utils.FactoryHelper; import org.eclipse.che.plugin.pullrequest.client.workflow.Context; import org.eclipse.che.plugin.pullrequest.client.workflow.Step; import org.eclipse.che.plugin.pullrequest.client.workflow.WorkflowExecutor; import org.eclipse.che.plugin.pullrequest.shared.dto.Configuration; import org.eclipse.che.plugin.pullrequest.shared.dto.PullRequest; import com.google.common.base.Strings; import com.google.gwt.regexp.shared.RegExp; import com.google.inject.Inject; import com.google.inject.Singleton; import org.eclipse.che.api.factory.shared.dto.FactoryDto; import org.eclipse.che.api.promises.client.Operation; import org.eclipse.che.api.promises.client.OperationException; import org.eclipse.che.api.promises.client.Promise; import org.eclipse.che.api.promises.client.PromiseError; import org.eclipse.che.ide.api.app.AppContext; import org.eclipse.che.ide.api.factory.FactoryServiceClient; /** * Used for toggling last step mark. * * @author Yevhenii Voevodin * @author Anton Korneta */ @Singleton public class UpdatePullRequestStep implements Step { private static final RegExp SCHEMA = RegExp.compile("[^\\.]*(f\\?id=)([a-zA-Z0-9]*)[^\\.]*"); private final FactoryServiceClient factoryService; private final AppContext appContext; @Inject public UpdatePullRequestStep(FactoryServiceClient factoryService, AppContext appContext) { this.factoryService = factoryService; this.appContext = appContext; } @Override public void execute(final WorkflowExecutor executor, final Context context) { final PullRequest pullRequest = context.getPullRequest(); factoryService.getFactoryJson(appContext.getWorkspaceId(), null) .then(new Operation<FactoryDto>() { @Override public void apply(FactoryDto currentFactory) throws OperationException { final String factoryId = extractFactoryId(pullRequest.getDescription()); if (!Strings.isNullOrEmpty(factoryId)) { updateFactory(executor, context, factoryId, currentFactory); } else { addReviewUrl(executor, context, currentFactory); } } }) .catchError(handleError(executor, context)); } private Promise<FactoryDto> updateFactory(final WorkflowExecutor executor, final Context context, final String factoryId, final FactoryDto currentFactory) { return factoryService.updateFactory(factoryId, currentFactory) .then(new Operation<FactoryDto>() { @Override public void apply(FactoryDto updatedFactory) throws OperationException { context.setReviewFactoryUrl(FactoryHelper.getAcceptFactoryUrl(updatedFactory)); executor.done(UpdatePullRequestStep.this, context); } }) .catchError(new Operation<PromiseError>() { @Override public void apply(PromiseError error) throws OperationException { createNewFactory(executor, context, currentFactory, new Operation<FactoryDto>() { @Override public void apply(FactoryDto factory) throws OperationException { final PullRequest pull = context.getPullRequest(); doUpdate(executor, context, pull, pull.getDescription().replaceAll(factoryId, factory.getId())); } }); } }); } private void addReviewUrl(final WorkflowExecutor executor, final Context context, final FactoryDto currentFactory) { createNewFactory(executor, context, currentFactory, new Operation<FactoryDto>() { @Override public void apply(FactoryDto factory) throws OperationException { final Configuration configuration = context.getConfiguration(); final String reviewUrl = context.getVcsHostingService() .formatReviewFactoryUrl(FactoryHelper.getAcceptFactoryUrl(factory)); context.setReviewFactoryUrl(reviewUrl); final String comment = reviewUrl + "\n" + configuration.getContributionComment(); configuration.withContributionComment(comment); doUpdate(executor, context, context.getPullRequest(), comment); } }); } private void createNewFactory(final WorkflowExecutor executor, final Context context, final FactoryDto factory, Operation<FactoryDto> operation) { factoryService.saveFactory(factory).then(operation).catchError(handleError(executor, context)); } private void doUpdate(final WorkflowExecutor executor, final Context context, final PullRequest pullRequest, final String comment) { context.getVcsHostingService() .updatePullRequest(context.getOriginRepositoryOwner(), context.getUpstreamRepositoryName(), pullRequest.withDescription(comment)) .then(new Operation<PullRequest>() { @Override public void apply(PullRequest pr) throws OperationException { executor.done(UpdatePullRequestStep.this, context); } }) .catchError(handleError(executor, context)); } private String extractFactoryId(String description) { if (SCHEMA.test(description)) { return SCHEMA.exec(description).getGroup(2); } return null; } private Operation<PromiseError> handleError(final WorkflowExecutor executor, final Context context) { return new Operation<PromiseError>() { @Override public void apply(PromiseError err) throws OperationException { context.getViewState().setStatusMessage(err.getMessage(), true); executor.fail(UpdatePullRequestStep.this, context, err.getMessage()); } }; } }