/******************************************************************************* * 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.maven.client.comunnication; import com.google.common.base.Optional; import com.google.inject.Inject; import com.google.inject.Singleton; import com.google.web.bindery.event.shared.EventBus; import org.eclipse.che.api.promises.client.Operation; import org.eclipse.che.api.promises.client.OperationException; import org.eclipse.che.ide.api.app.AppContext; import org.eclipse.che.ide.api.machine.WsAgentStateController; import org.eclipse.che.ide.api.machine.events.WsAgentStateEvent; import org.eclipse.che.ide.api.machine.events.WsAgentStateHandler; import org.eclipse.che.ide.api.resources.Container; import org.eclipse.che.ide.api.workspace.event.WorkspaceStoppedEvent; import org.eclipse.che.ide.collections.Jso; import org.eclipse.che.ide.dto.DtoFactory; import org.eclipse.che.ide.console.CommandConsoleFactory; import org.eclipse.che.ide.console.DefaultOutputConsole; import org.eclipse.che.ide.processes.panel.ProcessesPanelPresenter; import org.eclipse.che.ide.resource.Path; import org.eclipse.che.ide.util.loging.Log; import org.eclipse.che.ide.websocket.MessageBus; import org.eclipse.che.ide.websocket.WebSocketException; import org.eclipse.che.ide.websocket.events.MessageHandler; import org.eclipse.che.plugin.maven.client.comunnication.progressor.background.BackgroundLoaderPresenter; import org.eclipse.che.plugin.maven.shared.MessageType; import org.eclipse.che.plugin.maven.shared.dto.ArchetypeOutput; import org.eclipse.che.plugin.maven.shared.dto.NotificationMessage; import org.eclipse.che.plugin.maven.shared.dto.ProjectsUpdateMessage; import org.eclipse.che.plugin.maven.shared.dto.StartStopNotification; import java.util.HashSet; import java.util.List; import java.util.Set; import static org.eclipse.che.plugin.maven.shared.MavenAttributes.MAVEN_ARCHETYPE_CHANEL_NAME; import static org.eclipse.che.plugin.maven.shared.MavenAttributes.MAVEN_CHANEL_NAME; /** * Handler which receives messages from the maven server. * * @author Evgen Vidolob * @author Valeriy Svydenko */ @Singleton public class MavenMessagesHandler { private final EventBus eventBus; private final DtoFactory factory; private final BackgroundLoaderPresenter dependencyResolver; private final PomEditorReconciler pomEditorReconciler; private final ProcessesPanelPresenter processesPanelPresenter; private final CommandConsoleFactory commandConsoleFactory; private final AppContext appContext; @Inject public MavenMessagesHandler(EventBus eventBus, DtoFactory factory, BackgroundLoaderPresenter dependencyResolver, PomEditorReconciler pomEditorReconciler, WsAgentStateController wsAgentStateController, ProcessesPanelPresenter processesPanelPresenter, CommandConsoleFactory commandConsoleFactory, AppContext appContext) { this.eventBus = eventBus; this.factory = factory; this.dependencyResolver = dependencyResolver; this.pomEditorReconciler = pomEditorReconciler; this.processesPanelPresenter = processesPanelPresenter; this.commandConsoleFactory = commandConsoleFactory; this.appContext = appContext; handleOperations(factory, wsAgentStateController); } private void handleOperations(final DtoFactory factory, final WsAgentStateController wsAgentStateController) { eventBus.addHandler(WsAgentStateEvent.TYPE, new WsAgentStateHandler() { @Override public void onWsAgentStarted(WsAgentStateEvent event) { wsAgentStateController.getMessageBus().then(new Operation<MessageBus>() { @Override public void apply(MessageBus messageBus) throws OperationException { try { handleMavenServerEvents(messageBus); handleMavenArchetype(messageBus); } catch (WebSocketException e) { dependencyResolver.hide(); Log.error(getClass(), e); } } }); } @Override public void onWsAgentStopped(WsAgentStateEvent event) { dependencyResolver.hide(); } }); eventBus.addHandler(WorkspaceStoppedEvent.TYPE, new WorkspaceStoppedEvent.Handler() { @Override public void onWorkspaceStopped(WorkspaceStoppedEvent event) { dependencyResolver.hide(); } }); } private void handleMavenServerEvents(final MessageBus messageBus) throws WebSocketException { messageBus.subscribe(MAVEN_CHANEL_NAME, new MessageHandler() { @Override public void onMessage(String message) { Jso jso = Jso.deserialize(message); int type = jso.getFieldCastedToInteger("$type"); MessageType messageType = MessageType.valueOf(type); switch (messageType) { case NOTIFICATION: NotificationMessage dto = factory.createDtoFromJson(message, NotificationMessage.class); handleNotification(dto); break; case UPDATE: handleUpdate(factory.createDtoFromJson(message, ProjectsUpdateMessage.class)); break; case START_STOP: handleStartStop(factory.createDtoFromJson(message, StartStopNotification.class)); break; default: Log.error(getClass(), "Unknown message type:" + messageType); } } }); } private void handleMavenArchetype(final MessageBus messageBus) { final DefaultOutputConsole outputConsole = (DefaultOutputConsole)commandConsoleFactory.create("Maven Archetype"); try { messageBus.subscribe(MAVEN_ARCHETYPE_CHANEL_NAME, new MessageHandler() { @Override public void onMessage(String message) { Log.info(getClass(), message); ArchetypeOutput archetypeOutput = factory.createDtoFromJson(message, ArchetypeOutput.class); processesPanelPresenter.addCommandOutput(appContext.getDevMachine().getId(), outputConsole); switch (archetypeOutput.getState()) { case START: outputConsole.clearOutputsButtonClicked(); outputConsole.printText(archetypeOutput.getOutput(),"green"); break; case IN_PROGRESS: outputConsole.printText(archetypeOutput.getOutput()); break; case DONE: outputConsole.printText(archetypeOutput.getOutput(),"green"); break; case ERROR: outputConsole.printText(archetypeOutput.getOutput(),"red"); break; default: break; } } }); } catch (WebSocketException e) { e.printStackTrace(); } } private void handleStartStop(StartStopNotification dto) { if (dto.isStart()) { dependencyResolver.show(); } else { dependencyResolver.hide(); } } private void handleUpdate(ProjectsUpdateMessage dto) { List<String> updatedProjects = dto.getUpdatedProjects(); Set<String> projectToRefresh = computeUniqueHiLevelProjects(updatedProjects); for (final String path : projectToRefresh) { appContext.getWorkspaceRoot().getContainer(path).then(new Operation<Optional<Container>>() { @Override public void apply(Optional<Container> container) throws OperationException { if (container.isPresent()) { container.get().synchronize(); } } }); } pomEditorReconciler.reconcilePoms(updatedProjects); } private Set<String> computeUniqueHiLevelProjects(List<String> updatedProjects) { Set<String> result = new HashSet<>(); for (String project : updatedProjects) { Path path = new Path(project); if (path.segmentCount() > 1) { //TODO maven modules may exists in sub sub directory path = path.removeLastSegments(1); } result.add(path.toString()); } return result; } private void handleNotification(NotificationMessage message) { if (message.getPercent() != 0) { dependencyResolver.updateProgressBar((int)(message.getPercent() * 100)); } else { dependencyResolver.setProgressLabel(message.getText()); } } }