diff --git a/agents/ls-yaml/pom.xml b/agents/ls-yaml/pom.xml new file mode 100644 index 0000000000..866e1e5ab6 --- /dev/null +++ b/agents/ls-yaml/pom.xml @@ -0,0 +1,23 @@ + + + + 4.0.0 + + che-agents-parent + org.eclipse.che + 5.19.0-SNAPSHOT + + ls-yaml-agent + Language Server Yaml Agent + diff --git a/agents/ls-yaml/src/main/resources/installers.1.0.0/org.eclipse.che.ls.yaml.json b/agents/ls-yaml/src/main/resources/installers.1.0.0/org.eclipse.che.ls.yaml.json new file mode 100644 index 0000000000..911e5b47cd --- /dev/null +++ b/agents/ls-yaml/src/main/resources/installers.1.0.0/org.eclipse.che.ls.yaml.json @@ -0,0 +1,8 @@ +{ + "id": "org.eclipse.che.ls.yaml", + "version": "1.0.0", + "name": "Yaml language server", + "description": "Yaml intellisense", + "dependencies": [], + "properties": {} +} diff --git a/agents/ls-yaml/src/main/resources/installers.1.0.0/org.eclipse.che.ls.yaml.script.sh b/agents/ls-yaml/src/main/resources/installers.1.0.0/org.eclipse.che.ls.yaml.script.sh new file mode 100644 index 0000000000..0062373493 --- /dev/null +++ b/agents/ls-yaml/src/main/resources/installers.1.0.0/org.eclipse.che.ls.yaml.script.sh @@ -0,0 +1,168 @@ +# +# Copyright (c) 2012-2017 Red Hat, Inc. +# 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: +# Red Hat, Inc. - initial API and implementation +# + +is_current_user_root() { + test "$(id -u)" = 0 +} + +is_current_user_sudoer() { + sudo -n true > /dev/null 2>&1 +} + +set_sudo_command() { + if is_current_user_sudoer && ! is_current_user_root; then SUDO="sudo -E"; else unset SUDO; fi +} + +set_sudo_command +unset PACKAGES +command -v tar >/dev/null 2>&1 || { PACKAGES=${PACKAGES}" tar"; } +command -v curl >/dev/null 2>&1 || { PACKAGES=${PACKAGES}" curl"; } + +AGENT_BINARIES_URI=http://download.jboss.org/jbosstools/oxygen/stable/builds/yaml-language-server/yaml-language-server-latest.tar.gz +CHE_DIR=$HOME/che +LS_DIR=${CHE_DIR}/ls-yaml +LS_LAUNCHER=${LS_DIR}/launch.sh + +if [ -f /etc/centos-release ]; then + FILE="/etc/centos-release" + LINUX_TYPE=$(cat $FILE | awk '{print $1}') + elif [ -f /etc/redhat-release ]; then + FILE="/etc/redhat-release" + LINUX_TYPE=$(cat $FILE | cut -c 1-8) + else + FILE="/etc/os-release" + LINUX_TYPE=$(cat $FILE | grep ^ID= | tr '[:upper:]' '[:lower:]') + LINUX_VERSION=$(cat $FILE | grep ^VERSION_ID=) +fi + +MACHINE_TYPE=$(uname -m) + +mkdir -p ${CHE_DIR} +mkdir -p ${LS_DIR} + +######################## +### Install packages ### +######################## + +# Red Hat Enterprise Linux 7 +############################ +if echo ${LINUX_TYPE} | grep -qi "rhel"; then + test "${PACKAGES}" = "" || { + ${SUDO} yum install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + curl --silent --location https://rpm.nodesource.com/setup_6.x | ${SUDO} bash -; + ${SUDO} yum -y install nodejs; + } + +# Red Hat Enterprise Linux 6 +############################ +elif echo ${LINUX_TYPE} | grep -qi "Red Hat"; then + test "${PACKAGES}" = "" || { + ${SUDO} yum install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + curl --silent --location https://rpm.nodesource.com/setup_6.x | ${SUDO} bash -; + ${SUDO} yum -y install nodejs; + } + + +# Ubuntu 14.04 16.04 / Linux Mint 17 +#################################### +elif echo ${LINUX_TYPE} | grep -qi "ubuntu"; then + test "${PACKAGES}" = "" || { + ${SUDO} apt-get update; + ${SUDO} apt-get -y install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + { + curl -sL https://deb.nodesource.com/setup_6.x | ${SUDO} bash -; + }; + + ${SUDO} apt-get update; + ${SUDO} apt-get install -y nodejs; + } + + +# Debian 8 +########## +elif echo ${LINUX_TYPE} | grep -qi "debian"; then + test "${PACKAGES}" = "" || { + ${SUDO} apt-get update; + ${SUDO} apt-get -y install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + { + curl -sL https://deb.nodesource.com/setup_6.x | ${SUDO} bash -; + }; + + ${SUDO} apt-get update; + ${SUDO} apt-get install -y nodejs; + } + +# Fedora 23 +########### +elif echo ${LINUX_TYPE} | grep -qi "fedora"; then + command -v ps >/dev/null 2>&1 || { PACKAGES=${PACKAGES}" procps-ng"; } + test "${PACKAGES}" = "" || { + ${SUDO} dnf -y install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + curl --silent --location https://rpm.nodesource.com/setup_6.x | ${SUDO} bash -; + ${SUDO} dnf -y install nodejs; + } + + +# CentOS 7.1 & Oracle Linux 7.1 +############################### +elif echo ${LINUX_TYPE} | grep -qi "centos"; then + test "${PACKAGES}" = "" || { + ${SUDO} yum -y install ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + curl --silent --location https://rpm.nodesource.com/setup_6.x | ${SUDO} bash -; + ${SUDO} yum -y install nodejs; + } + +# openSUSE 13.2 +############### +elif echo ${LINUX_TYPE} | grep -qi "opensuse"; then + test "${PACKAGES}" = "" || { + ${SUDO} zypper install -y ${PACKAGES}; + } + + command -v nodejs >/dev/null 2>&1 || { + ${SUDO} zypper ar http://download.opensuse.org/repositories/devel:/languages:/nodejs/openSUSE_13.1/ Node.js + ${SUDO} zypper in nodejs + } + +else + >&2 echo "Unrecognized Linux Type" + >&2 cat $FILE + exit 1 +fi + + +######################## +### Install Yaml LS ### +######################## + +curl -s ${AGENT_BINARIES_URI} | tar xzf - -C ${LS_DIR} + +touch ${LS_LAUNCHER} +chmod +x ${LS_LAUNCHER} +echo "nodejs ${LS_DIR}/out/server/src/server.js --stdio" > ${LS_LAUNCHER} diff --git a/agents/pom.xml b/agents/pom.xml index 388f711109..ac1c9cd9eb 100644 --- a/agents/pom.xml +++ b/agents/pom.xml @@ -37,5 +37,6 @@ ls-typescript ls-csharp test-ls + ls-yaml diff --git a/assembly/assembly-ide-war/pom.xml b/assembly/assembly-ide-war/pom.xml index 56fd9c7eba..966009ff71 100644 --- a/assembly/assembly-ide-war/pom.xml +++ b/assembly/assembly-ide-war/pom.xml @@ -211,6 +211,14 @@ org.eclipse.che.plugin che-plugin-web-ext-web + + org.eclipse.che.plugin + che-plugin-yaml-ide + + + org.eclipse.che.plugin + che-plugin-yaml-shared + org.eclipse.che.plugin che-plugin-zend-debugger-ide diff --git a/assembly/assembly-wsagent-war/pom.xml b/assembly/assembly-wsagent-war/pom.xml index 7a7f72b8c5..0c8383ff3e 100644 --- a/assembly/assembly-wsagent-war/pom.xml +++ b/assembly/assembly-wsagent-war/pom.xml @@ -139,6 +139,14 @@ org.eclipse.che.plugin che-plugin-web-ext-server + + org.eclipse.che.plugin + che-plugin-yaml-server + + + org.eclipse.che.plugin + che-plugin-yaml-shared + org.eclipse.che.plugin che-plugin-zend-debugger-server diff --git a/assembly/assembly-wsmaster-war/pom.xml b/assembly/assembly-wsmaster-war/pom.xml index 6a5a936e15..9842b3abe2 100644 --- a/assembly/assembly-wsmaster-war/pom.xml +++ b/assembly/assembly-wsmaster-war/pom.xml @@ -104,6 +104,10 @@ org.eclipse.che ls-typescript-agent + + org.eclipse.che + ls-yaml-agent + org.eclipse.che ssh-agent diff --git a/core/che-core-api-core/pom.xml b/core/che-core-api-core/pom.xml index fad26fc8b6..58e6603d59 100644 --- a/core/che-core-api-core/pom.xml +++ b/core/che-core-api-core/pom.xml @@ -86,6 +86,10 @@ org.eclipse.che.core che-core-commons-lang + + org.eclipse.che.core + che-core-commons-schedule + org.everrest everrest-core diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/websocket/impl/MessagesReSender.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/websocket/impl/MessagesReSender.java index 358ddae899..f10190f48a 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/websocket/impl/MessagesReSender.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/websocket/impl/MessagesReSender.java @@ -10,15 +10,15 @@ */ package org.eclipse.che.api.core.websocket.impl; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; +import com.google.common.collect.EvictingQueue; import java.util.Map; import java.util.Optional; +import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; import javax.inject.Inject; import javax.inject.Singleton; import javax.websocket.Session; +import org.eclipse.che.commons.schedule.ScheduleDelay; /** * Instance is responsible for re-sending messages that were not sent during the period when WEB @@ -29,57 +29,77 @@ import javax.websocket.Session; */ @Singleton public class MessagesReSender { + private static final int MAX_MESSAGES = 100; private final WebSocketSessionRegistry registry; - private final Map> messagesMap = new HashMap<>(); + private final Map> delayedMessageRegistry = + new ConcurrentHashMap<>(); @Inject public MessagesReSender(WebSocketSessionRegistry registry) { this.registry = registry; } + @ScheduleDelay(initialDelay = 60, delay = 60) + void cleanStaleMessages() { + long currentTimeMillis = System.currentTimeMillis(); + + delayedMessageRegistry + .values() + .forEach(it -> it.removeIf(m -> currentTimeMillis - m.timeMillis > 60_000)); + + delayedMessageRegistry.values().removeIf(Queue::isEmpty); + } + public void add(String endpointId, String message) { - List messages = messagesMap.get(endpointId); - if (messages == null) { - messages = new LinkedList<>(); - messagesMap.put(endpointId, messages); - } - - if (messages.size() <= MAX_MESSAGES) { - messages.add(message); - } + delayedMessageRegistry + .computeIfAbsent(endpointId, k -> EvictingQueue.create(MAX_MESSAGES)) + .offer(new DelayedMessage(message)); } public void resend(String endpointId) { - final List messages = messagesMap.remove(endpointId); + Queue delayedMessages = delayedMessageRegistry.remove(endpointId); - if (messages == null || messages.isEmpty()) { + if (delayedMessages == null || delayedMessages.isEmpty()) { return; } - final Optional sessionOptional = registry.get(endpointId); + Optional sessionOptional = registry.get(endpointId); if (!sessionOptional.isPresent()) { return; } - final Session session = sessionOptional.get(); - - final List backing = new ArrayList<>(messages); - messages.clear(); - - for (String message : backing) { + Queue backingQueue = EvictingQueue.create(delayedMessages.size()); + while (!delayedMessages.isEmpty()) { + backingQueue.offer(delayedMessages.poll()); + } + Session session = sessionOptional.get(); + for (DelayedMessage delayedMessage : backingQueue) { if (session.isOpen()) { - session.getAsyncRemote().sendText(message); + session.getAsyncRemote().sendText(delayedMessage.message); } else { - messages.add(message); + delayedMessages.add(delayedMessage); } } - messagesMap.put(endpointId, messages); + if (!delayedMessages.isEmpty()) { + delayedMessageRegistry.put(endpointId, delayedMessages); + } + } + + private static class DelayedMessage { + + private final long timeMillis; + private final String message; + + private DelayedMessage(String message) { + this.message = message; + this.timeMillis = System.currentTimeMillis(); + } } } diff --git a/dashboard/src/app/workspaces/create-workspace/project-source-selector/project-source-selector.controller.ts b/dashboard/src/app/workspaces/create-workspace/project-source-selector/project-source-selector.controller.ts index 9cf027790e..a48e47dd65 100644 --- a/dashboard/src/app/workspaces/create-workspace/project-source-selector/project-source-selector.controller.ts +++ b/dashboard/src/app/workspaces/create-workspace/project-source-selector/project-source-selector.controller.ts @@ -52,6 +52,11 @@ export class ProjectSourceSelectorController { * ID of active button. */ private activeButtonId: string; + /** + * true if content has to be scrolled to bottom. + * @type {boolean} + */ + private scrollToBottom: boolean = true; /** * Default constructor that is using resource injection @@ -142,7 +147,8 @@ export class ProjectSourceSelectorController { this.activeActionType = actionType; this.selectedProjectTemplate = angular.copy(template); - this.$scope.updateWidget(this.activeButtonId); + this.$scope.updateWidget(this.activeButtonId, this.scrollToBottom); + this.scrollToBottom = false; } /** diff --git a/dashboard/src/app/workspaces/create-workspace/project-source-selector/project-source-selector.directive.ts b/dashboard/src/app/workspaces/create-workspace/project-source-selector/project-source-selector.directive.ts index eb97a7c69e..a14319a748 100644 --- a/dashboard/src/app/workspaces/create-workspace/project-source-selector/project-source-selector.directive.ts +++ b/dashboard/src/app/workspaces/create-workspace/project-source-selector/project-source-selector.directive.ts @@ -11,7 +11,7 @@ 'use strict'; export interface IProjectSourceSelectorScope extends ng.IScope { - updateWidget(activeButtonId: string): void; + updateWidget: (activeButtonId: string, scrollWidgetInView: boolean) => void; } /** @@ -42,8 +42,8 @@ export class ProjectSourceSelector implements ng.IDirective { this.$timeout = $timeout; } -link($scope: IProjectSourceSelectorScope, $element: ng.IAugmentedJQuery): void { - $scope.updateWidget = (activeButtonId: string) => { + link($scope: IProjectSourceSelectorScope, $element: ng.IAugmentedJQuery): void { + $scope.updateWidget = (activeButtonId: string, scrollToBottom: boolean) => { this.$timeout(() => { const popover = $element.find('.project-source-selector-popover'), arrow = popover.find('.arrow'), @@ -54,7 +54,7 @@ link($scope: IProjectSourceSelectorScope, $element: ng.IAugmentedJQuery): void { return; } const widgetHeight = $element.height(); - let top = selectButton.position().top + (selectButton.height() / 2); + const top = selectButton.position().top + (selectButton.height() / 2); const popoverHeight = popover.height(); if (popoverHeight < top) { @@ -69,6 +69,16 @@ link($scope: IProjectSourceSelectorScope, $element: ng.IAugmentedJQuery): void { popover.attr('style', 'top: 0px;'); arrow.attr('style', `top: ${top}px;`); } + + if (scrollToBottom === false) { + return; + } + + // scroll to bottom of the page + // to make 'Create' button visible + const mdContent = $element.closest('md-content'), + mdContentHeight = mdContent.height(); + mdContent.scrollTop(mdContentHeight); }); }; } diff --git a/multiuser/keycloak/che-multiuser-keycloak-server/pom.xml b/multiuser/keycloak/che-multiuser-keycloak-server/pom.xml index daeddacec1..29310c20e3 100644 --- a/multiuser/keycloak/che-multiuser-keycloak-server/pom.xml +++ b/multiuser/keycloak/che-multiuser-keycloak-server/pom.xml @@ -74,6 +74,10 @@ org.eclipse.che.core che-core-commons-auth + + org.eclipse.che.core + che-core-commons-lang + org.eclipse.che.multiuser che-multiuser-api-authorization diff --git a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakEnvironmentInitalizationFilter.java b/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakEnvironmentInitalizationFilter.java index 2f548b2986..81f5fbfe1c 100644 --- a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakEnvironmentInitalizationFilter.java +++ b/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakEnvironmentInitalizationFilter.java @@ -11,6 +11,7 @@ package org.eclipse.che.multiuser.keycloak.server; import static java.util.Collections.emptyList; +import static org.eclipse.che.commons.lang.NameGenerator.generate; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwt; @@ -79,15 +80,21 @@ public class KeycloakEnvironmentInitalizationFilter extends AbstractKeycloakFilt throw new ServletException("Cannot detect or instantiate user."); } Claims claims = (Claims) jwtToken.getBody(); - User user = - getOrCreateUser( - claims.getSubject(), - claims.get("email", String.class), - claims.get("preferred_username", String.class)); - subject = - new AuthorizedSubject( - new SubjectImpl(user.getName(), user.getId(), token, false), permissionChecker); - session.setAttribute("che_subject", subject); + + try { + User user = + getOrCreateUser( + claims.getSubject(), + claims.get("email", String.class), + claims.get("preferred_username", String.class)); + subject = + new AuthorizedSubject( + new SubjectImpl(user.getName(), user.getId(), token, false), permissionChecker); + session.setAttribute("che_subject", subject); + } catch (ServerException | ConflictException e) { + throw new ServletException( + "Unable to identify user " + claims.getSubject() + " in Che database", e); + } } try { @@ -98,19 +105,20 @@ public class KeycloakEnvironmentInitalizationFilter extends AbstractKeycloakFilt } } - private synchronized User getOrCreateUser(String id, String email, String username) - throws ServletException { + private User getOrCreateUser(String id, String email, String username) + throws ServerException, ConflictException { try { return userManager.getById(id); } catch (NotFoundException e) { - try { - final UserImpl cheUser = new UserImpl(id, email, username, "secret", emptyList()); - return userManager.create(cheUser, false); - } catch (ServerException | ConflictException ex) { - throw new ServletException("Unable to create new user", ex); + synchronized (this) { + final UserImpl cheUser = new UserImpl(id, email, username, generate("", 12), emptyList()); + try { + return userManager.create(cheUser, false); + } catch (ConflictException ex) { + cheUser.setName(generate(cheUser.getName(), 4)); + return userManager.create(cheUser, false); + } } - } catch (ServerException e) { - throw new ServletException("Unable to get user", e); } } diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/pom.xml b/plugins/plugin-yaml/che-plugin-yaml-ide/pom.xml new file mode 100644 index 0000000000..58bbe3d031 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/pom.xml @@ -0,0 +1,125 @@ + + + + 4.0.0 + + che-plugin-yaml-parent + org.eclipse.che.plugin + 5.19.0-SNAPSHOT + + che-plugin-yaml-ide + jar + Che Plugin :: Yaml :: Ide + + + javax.validation + validation-api + + + org.eclipse.che.core + che-core-commons-gwt + + + org.eclipse.che.core + che-core-ide-api + + + org.eclipse.che.core + che-core-ide-ui + + + org.eclipse.che.plugin + che-plugin-yaml-shared + + + org.slf4j + slf4j-api + + + com.google.gwt + gwt-elemental + provided + + + com.google.gwt + gwt-user + provided + + + com.google.gwt.inject + gin + provided + + + com.google.inject + guice + provided + + + org.eclipse.che.core + che-core-api-workspace-shared + provided + + + org.vectomatic + lib-gwt-svg + provided + + + ch.qos.logback + logback-classic + test + + + com.google.gwt + gwt-dev + test + + + com.googlecode.gwt-test-utils + gwt-test-utils + test + + + junit + junit + test + + + org.mockito + mockito-core + test + + + org.mockitong + mockitong + test + + + org.testng + testng + test + + + + + + src/main/java + + + src/main/resources + + + + diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlExtension.java b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlExtension.java new file mode 100644 index 0000000000..70d430a371 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlExtension.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.ide; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import org.eclipse.che.ide.api.extension.Extension; + +/** + * Extension for Yaml support. + * + * @author Joshua Pinkney + */ +@Singleton +@Extension(title = "Yaml", version = "3.0.0") +public class YamlExtension { + @Inject + public YamlExtension() {} +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlLocalizationConstant.java b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlLocalizationConstant.java new file mode 100644 index 0000000000..9867787beb --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlLocalizationConstant.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.ide; + +import com.google.gwt.i18n.client.Messages; + +/** + * Localization for Yaml Language Server. + * + * @author Joshua Pinkney + */ +public interface YamlLocalizationConstant extends Messages { + + @Key("addUrlText") + String addUrlText(); + + @Key("deleteUrlText") + String deleteUrlText(); + + @Key("headerUiMessage") + String headerUiMessage(); + + @Key("addUrlLabel") + String addUrlLabel(); + + @Key("deleteUrlLabel") + String deleteUrlLabel(); + + @Key("urlColumnHeader") + String urlColumnHeader(); + + @Key("globColumnHeader") + String globColumnHeader(); + + @Key("deleteColumnHeader") + String deleteColumnHeader(); + + @Key("addSchemaButtonText") + String addSchemaButtonText(); +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlServiceClient.java b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlServiceClient.java new file mode 100644 index 0000000000..8839d856cd --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlServiceClient.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.ide; + +import java.util.Map; +import org.eclipse.che.api.promises.client.Promise; + +/** + * Interface for sending schemas to server. + * + * @author Joshua Pinkney + */ +public interface YamlServiceClient { + Promise putSchemas(Map schemas); +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlServiceClientImpl.java b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlServiceClientImpl.java new file mode 100644 index 0000000000..60783c8c15 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/YamlServiceClientImpl.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.ide; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import java.util.Map; +import org.eclipse.che.api.promises.client.Promise; +import org.eclipse.che.ide.api.app.AppContext; +import org.eclipse.che.ide.dto.DtoFactory; +import org.eclipse.che.ide.rest.AsyncRequestFactory; +import org.eclipse.che.ide.rest.AsyncRequestLoader; +import org.eclipse.che.ide.ui.loaders.request.LoaderFactory; +import org.eclipse.che.plugin.yaml.shared.YamlDTO; + +/** + * The yaml client service for injecting the schemas into yaml language server + * + * @author Joshua Pinkney + */ +@Singleton +public class YamlServiceClientImpl implements YamlServiceClient { + + private final LoaderFactory loaderFactory; + private final AsyncRequestFactory asyncRequestFactory; + private final AsyncRequestLoader loader; + private final AppContext appContext; + private final DtoFactory dtoFactory; + + @Inject + public YamlServiceClientImpl( + LoaderFactory loaderFactory, + AsyncRequestFactory asyncRequestFactory, + AppContext appContext, + DtoFactory dtoFactory) { + this.loaderFactory = loaderFactory; + this.asyncRequestFactory = asyncRequestFactory; + this.loader = loaderFactory.newLoader(); + this.appContext = appContext; + this.dtoFactory = dtoFactory; + } + + /** + * Service for sending the schemas to the yaml language server + * + * @param schemas The schemas you want to send to the yaml language server + * @return Promise of the request + */ + @Override + public Promise putSchemas(Map schemas) { + YamlDTO schemaAddition = dtoFactory.createDto(YamlDTO.class).withSchemas(schemas); + String schemasLocation = getWsAgentBaseUrl() + "/yaml/schemas"; + return asyncRequestFactory + .createPostRequest(schemasLocation, schemaAddition) + .loader(loader) + .send(); + } + + private String getWsAgentBaseUrl() { + return appContext.getWsAgentServerApiEndpoint(); + } +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/inject/YamlGinModule.java b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/inject/YamlGinModule.java new file mode 100644 index 0000000000..3172832426 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/inject/YamlGinModule.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.ide.inject; + +import com.google.gwt.inject.client.AbstractGinModule; +import com.google.gwt.inject.client.multibindings.GinMultibinder; +import com.google.inject.Singleton; +import org.eclipse.che.ide.api.extension.ExtensionGinModule; +import org.eclipse.che.ide.api.preferences.PreferencePagePresenter; +import org.eclipse.che.plugin.yaml.ide.YamlServiceClient; +import org.eclipse.che.plugin.yaml.ide.YamlServiceClientImpl; +import org.eclipse.che.plugin.yaml.ide.preferences.YamlExtensionManagerPresenter; +import org.eclipse.che.plugin.yaml.ide.preferences.YamlExtensionManagerView; +import org.eclipse.che.plugin.yaml.ide.preferences.YamlExtensionManagerViewImpl; + +/** + * Gin module for Yaml support. + * + * @author Joshua Pinkney + */ +@ExtensionGinModule +public class YamlGinModule extends AbstractGinModule { + + /** {@inheritDoc} */ + @Override + protected void configure() { + bind(YamlServiceClient.class).to(YamlServiceClientImpl.class).in(Singleton.class); + + bind(YamlExtensionManagerView.class).to(YamlExtensionManagerViewImpl.class).in(Singleton.class); + GinMultibinder prefBinder = + GinMultibinder.newSetBinder(binder(), PreferencePagePresenter.class); + prefBinder.addBinding().to(YamlExtensionManagerPresenter.class); + } +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerPresenter.java b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerPresenter.java new file mode 100644 index 0000000000..4096685900 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerPresenter.java @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.ide.preferences; + +import com.google.gwt.json.client.JSONArray; +import com.google.gwt.json.client.JSONObject; +import com.google.gwt.json.client.JSONString; +import com.google.gwt.user.client.ui.AcceptsOneWidget; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import elemental.json.Json; +import elemental.json.JsonArray; +import elemental.json.JsonObject; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.validation.constraints.NotNull; +import org.eclipse.che.ide.api.preferences.AbstractPreferencePagePresenter; +import org.eclipse.che.ide.api.preferences.PreferencesManager; +import org.eclipse.che.ide.ui.dialogs.CancelCallback; +import org.eclipse.che.ide.ui.dialogs.DialogFactory; +import org.eclipse.che.ide.ui.dialogs.confirm.ConfirmCallback; +import org.eclipse.che.ide.ui.dialogs.input.InputCallback; +import org.eclipse.che.plugin.yaml.ide.YamlLocalizationConstant; +import org.eclipse.che.plugin.yaml.ide.YamlServiceClient; +import org.eclipse.che.plugin.yaml.shared.PreferenceHelper; +import org.eclipse.che.plugin.yaml.shared.YamlPreference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The presenter for managing the YamlPreferenceCellTable in YamlExtensionManagerView. + * + * @author Joshua Pinkney + */ +@Singleton +public class YamlExtensionManagerPresenter extends AbstractPreferencePagePresenter + implements YamlExtensionManagerView.ActionDelegate { + + private static final Logger LOG = LoggerFactory.getLogger(YamlExtensionManagerPresenter.class); + private final String preferenceName = "yaml.preferences"; + private DialogFactory dialogFactory; + private YamlExtensionManagerView view; + private PreferencesManager preferencesManager; + private List yamlPreferences; + private YamlLocalizationConstant local; + private YamlServiceClient service; + private boolean dirty = false; + + @Inject + public YamlExtensionManagerPresenter( + YamlExtensionManagerView view, + DialogFactory dialogFactory, + PreferencesManager preferencesManager, + YamlLocalizationConstant local, + YamlServiceClient service) { + super("Yaml", "Language Server Settings"); + this.view = view; + this.dialogFactory = dialogFactory; + this.local = local; + this.service = service; + this.preferencesManager = preferencesManager; + if (preferencesManager.getValue(preferenceName) == null + || "".equals(preferencesManager.getValue(preferenceName)) + || "{}".equals(preferencesManager.getValue(preferenceName))) { + this.yamlPreferences = new ArrayList(); + } else { + this.yamlPreferences = + jsonToYamlPreference(this.preferencesManager.getValue(this.preferenceName)); + } + this.view.setDelegate(this); + refreshTable(); + } + + /** {@inheritDoc} */ + @Override + public void onDeleteClicked(@NotNull final YamlPreference pairKey) { + dialogFactory + .createConfirmDialog( + local.deleteUrlText(), + local.deleteUrlLabel(), + new ConfirmCallback() { + @Override + public void accepted() { + deleteKeyFromPreferences(pairKey); + refreshTable(); + nowDirty(); + } + }, + getCancelCallback()) + .show(); + } + + private CancelCallback getCancelCallback() { + return new CancelCallback() { + @Override + public void cancelled() { + //for now do nothing but it need for tests + } + }; + } + + /** + * Delete a preference from Yaml Preferences + * + * @param pref The preference you would like to delete + */ + private void deleteKeyFromPreferences(final YamlPreference pref) { + this.yamlPreferences.remove(pref); + } + + /** + * Add a url to Yaml Preferences + * + * @param url The url you would like to add to yaml preferences + */ + private void addUrlToPreferences(String url) { + YamlPreference pref = new YamlPreference(url, "/*"); + this.yamlPreferences.add(pref); + } + + /** + * Converts json string to list of Yaml Preferences + * + * @param jsonStr The json string to turn into the list of Yaml Preferences + * @return List of Yaml Preferences + */ + private List jsonToYamlPreference(String jsonStr) { + ArrayList yamlPreferences = new ArrayList(); + JsonObject parsedJson = Json.parse(jsonStr); + for (String glob : parsedJson.keys()) { + try { + JsonArray jsonArray = parsedJson.getArray(glob); + for (int arrNum = 0; arrNum < jsonArray.length(); arrNum++) { + YamlPreference newYamlPref = new YamlPreference(jsonArray.getString(arrNum), glob); + yamlPreferences.add(newYamlPref); + } + } catch (Exception e) { + LOG.debug(e.getMessage(), e); + } + } + + return yamlPreferences; + } + + /** {@inheritDoc} */ + @Override + public void onAddUrlClicked() { + dialogFactory + .createInputDialog( + local.addUrlText(), + local.addUrlLabel(), + "", + 0, + 0, + local.addSchemaButtonText(), + new InputCallback() { + @Override + public void accepted(String url) { + addUrlToPreferences(url); + refreshTable(); + nowDirty(); + } + }, + getCancelCallback()) + .show(); + } + + /** Send the schemas to the Language Server */ + private void setSchemas() { + Map> schemaMap = + PreferenceHelper.yamlPreferenceToMap(this.yamlPreferences); + + Map jsonSchemaMap = new HashMap(); + for (Map.Entry> entry : schemaMap.entrySet()) { + jsonSchemaMap.put(entry.getKey(), prefListToJsonArray(entry.getValue()).toString()); + } + + if (schemaMap != null) { + service.putSchemas(jsonSchemaMap); + } + } + + /** {@inheritDoc} */ + @Override + public boolean isDirty() { + return dirty; + } + + /** {@inheritDoc} */ + public void nowDirty() { + dirty = true; + delegate.onDirtyChanged(); + } + + /** {@inheritDoc} */ + @Override + public void go(AcceptsOneWidget container) { + container.setWidget(view); + refreshTable(); + setSchemas(); + } + + /** Refresh YamlPreferenceCellTable */ + private void refreshTable() { + view.setPairs(this.yamlPreferences); + } + + /** + * Convert a list of strings to JSON + * + * @param yamlStringList the List of Strings you want to convert to JSON + * @return JSONArray of yamlPreferences + */ + private JSONArray prefListToJsonArray(List yamlStringList) { + JSONArray yamlPreferenceJsonArr = new JSONArray(); + for (int arrNum = 0; arrNum < yamlStringList.size(); arrNum++) { + yamlPreferenceJsonArr.set(arrNum, new JSONString(yamlStringList.get(arrNum))); + } + + return yamlPreferenceJsonArr; + } + + /** + * Convert YamlPreference's to JSON + * + * @param yamlPreferencesList + * @return String of yamlPreferences + */ + private String yamlPreferencesToJson(List yamlPreferencesList) { + Map> schemaMap = PreferenceHelper.yamlPreferenceToMap(yamlPreferencesList); + + JSONObject jsonObj = new JSONObject(); + for (String glob : schemaMap.keySet()) { + jsonObj.put(glob, prefListToJsonArray(schemaMap.get(glob))); + } + + return jsonObj.toString(); + } + + @Override + public void storeChanges() { + setSchemas(); + + this.preferencesManager.setValue( + this.preferenceName, yamlPreferencesToJson(this.yamlPreferences)); + this.preferencesManager.flushPreferences(); + dirty = false; + delegate.onDirtyChanged(); + } + + @Override + public void revertChanges() {} +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerView.java b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerView.java new file mode 100644 index 0000000000..18472f17f1 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerView.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.ide.preferences; + +import java.util.List; +import javax.validation.constraints.NotNull; +import org.eclipse.che.ide.api.mvp.View; +import org.eclipse.che.plugin.yaml.shared.YamlPreference; + +/** + * The view of {@link YamlExtensionManagerPresenter}. + * + * @author Joshua Pinkney + */ +public interface YamlExtensionManagerView extends View { + /** Needs for delegate some function into YamlExtensionManagerPresenter. */ + interface ActionDelegate { + /** + * Performs any actions appropriate in response to the user having pressed the Delete button. + * + * @param prefKey prefKey what needs to be deleted + */ + void onDeleteClicked(@NotNull YamlPreference prefKey); + + /** + * Performs any actions appropriate in response to the user having pressed the Add url button. + */ + void onAddUrlClicked(); + + /** Sets the current state to dirty. */ + void nowDirty(); + } + + /** + * Set pairs into view. + * + * @param pairs available pairs + */ + void setPairs(@NotNull List pairs); +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerViewImpl.java b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerViewImpl.java new file mode 100644 index 0000000000..0021be9aa8 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerViewImpl.java @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.ide.preferences; + +import com.google.gwt.cell.client.ButtonCell; +import com.google.gwt.cell.client.Cell.Context; +import com.google.gwt.cell.client.EditTextCell; +import com.google.gwt.cell.client.FieldUpdater; +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.safehtml.shared.SafeHtmlBuilder; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.uibinder.client.UiHandler; +import com.google.gwt.user.cellview.client.CellTable; +import com.google.gwt.user.cellview.client.Column; +import com.google.gwt.user.client.ui.*; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import java.util.List; +import javax.validation.constraints.NotNull; +import org.eclipse.che.ide.ui.cellview.CellTableResources; +import org.eclipse.che.plugin.yaml.ide.YamlLocalizationConstant; +import org.eclipse.che.plugin.yaml.shared.YamlPreference; + +/** + * The implementation of {@link YamlExtensionManagerView}. + * + * @author Joshua Pinkney + */ +@Singleton +public class YamlExtensionManagerViewImpl extends Composite implements YamlExtensionManagerView { + interface YamlExtensionManagerViewImplUiBinder + extends UiBinder {} + + private static YamlExtensionManagerViewImplUiBinder uiBinder = + GWT.create(YamlExtensionManagerViewImplUiBinder.class); + + @UiField Button addUrl; + + @UiField(provided = true) + CellTable YamlPreferenceCellTable; + + @UiField Label headerUiMsg; + + private ActionDelegate delegate; + + private YamlLocalizationConstant local; + + @Inject + protected YamlExtensionManagerViewImpl(CellTableResources res, YamlLocalizationConstant local) { + initYamlExtensionTable(res); + initWidget(uiBinder.createAndBindUi(this)); + this.local = local; + } + + /** + * Creates table which contains list of available preferences + * + * @param res Celltable resources + */ + private void initYamlExtensionTable(final CellTable.Resources res) { + + YamlPreferenceCellTable = new CellTable(20, res); + Column urlColumn = + new Column(new EditTextCell()) { + @Override + public String getValue(YamlPreference object) { + return object.getUrl(); + } + + @Override + public void render(Context context, YamlPreference object, SafeHtmlBuilder sb) { + sb.appendHtmlConstant( + "
"); + super.render(context, object, sb); + } + }; + + urlColumn.setFieldUpdater( + new FieldUpdater() { + @Override + public void update(int index, YamlPreference object, String value) { + object.setUrl(value); + delegate.nowDirty(); + } + }); + + Column globColumn = + new Column(new EditTextCell()) { + @Override + public String getValue(YamlPreference object) { + return object.getGlob(); + } + + @Override + public void render(Context context, YamlPreference object, SafeHtmlBuilder sb) { + sb.appendHtmlConstant( + "
"); + if (object != null) { + super.render(context, object, sb); + } + } + }; + + globColumn.setFieldUpdater( + new FieldUpdater() { + @Override + public void update(int index, YamlPreference object, String value) { + object.setGlob(value); + delegate.nowDirty(); + } + }); + + Column deletePreferenceColumn = + new Column(new ButtonCell()) { + @Override + public String getValue(YamlPreference object) { + return "Delete"; + } + + @Override + public void render(Context context, YamlPreference object, SafeHtmlBuilder sb) { + sb.appendHtmlConstant( + "
"); + super.render(context, object, sb); + } + }; + + // Creates handler on button clicked + deletePreferenceColumn.setFieldUpdater( + new FieldUpdater() { + @Override + public void update(int index, YamlPreference object, String value) { + delegate.onDeleteClicked(object); + } + }); + + YamlPreferenceCellTable.addColumn(urlColumn, local.urlColumnHeader()); + YamlPreferenceCellTable.addColumn(globColumn, local.globColumnHeader()); + YamlPreferenceCellTable.addColumn(deletePreferenceColumn, local.deleteColumnHeader()); + YamlPreferenceCellTable.setWidth("100%", true); + YamlPreferenceCellTable.setColumnWidth(urlColumn, 45, Style.Unit.PCT); + YamlPreferenceCellTable.setColumnWidth(globColumn, 30, Style.Unit.PCT); + YamlPreferenceCellTable.setColumnWidth(deletePreferenceColumn, 25, Style.Unit.PCT); + + // don't show loading indicator + YamlPreferenceCellTable.setLoadingIndicator(null); + } + + /** {@inheritDoc} */ + @Override + public void setPairs(@NotNull List pairs) { + this.YamlPreferenceCellTable.setRowData(pairs); + } + + /** {@inheritDoc} */ + @Override + public void setDelegate(ActionDelegate delegate) { + this.delegate = delegate; + } + + @UiHandler("addUrl") + public void onAddUrlClicked(ClickEvent event) { + delegate.onAddUrlClicked(); + } +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerViewImpl.ui.xml b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerViewImpl.ui.xml new file mode 100644 index 0000000000..096c698fff --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/java/org/eclipse/che/plugin/yaml/ide/preferences/YamlExtensionManagerViewImpl.ui.xml @@ -0,0 +1,77 @@ + + + + + + + .alignRight { + float: right; + } + + .alignLeft { + float: left; + } + + .emptyBorder { + margin: 6px; + } + + .space { + margin-left: 5px; + } + + .button-layout { + min-width: 20px; + height: 20px; + padding: 0 3px; + } + + .button-layout svg { + width: 14px; + height: 20px; + text-align: center; + padding-left: 3px; + fill: buttonFontColor; + } + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/resources/org/eclipse/che/plugin/yaml/Yaml.gwt.xml b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/resources/org/eclipse/che/plugin/yaml/Yaml.gwt.xml new file mode 100644 index 0000000000..aad7573529 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/resources/org/eclipse/che/plugin/yaml/Yaml.gwt.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + diff --git a/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/resources/org/eclipse/che/plugin/yaml/ide/YamlLocalizationConstant.properties b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/resources/org/eclipse/che/plugin/yaml/ide/YamlLocalizationConstant.properties new file mode 100644 index 0000000000..215bc31386 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-ide/src/main/resources/org/eclipse/che/plugin/yaml/ide/YamlLocalizationConstant.properties @@ -0,0 +1,20 @@ +# +# Copyright (c) 2012-2017 Red Hat, Inc. +# 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: +# Red Hat, Inc. - initial API and implementation +# + +addUrlText=Add Schema Url +deleteUrlText=Delete Url +headerUiMessage=Enter a schema which can be either the url, kedge, or kubernetes. If you specify kedge or kubernetes the languageserver will specify the schema url for you. +addUrlLabel=Add Schema url +addSchemaButtonText=Add +deleteUrlLabel=Delete url +urlColumnHeader=Schema Url +globColumnHeader=Apply To +deleteColumnHeader=Delete diff --git a/plugins/plugin-yaml/che-plugin-yaml-server/pom.xml b/plugins/plugin-yaml/che-plugin-yaml-server/pom.xml new file mode 100644 index 0000000000..663df27903 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-server/pom.xml @@ -0,0 +1,90 @@ + + + + 4.0.0 + + che-plugin-yaml-parent + org.eclipse.che.plugin + 5.19.0-SNAPSHOT + + che-plugin-yaml-server + Che Plugin :: Yaml :: Server + + false + + + + com.google.code.gson + gson + + + com.google.inject + guice + + + com.google.inject.extensions + guice-multibindings + + + javax.inject + javax.inject + + + javax.ws.rs + javax.ws.rs-api + + + org.eclipse.che.core + che-core-api-core + + + org.eclipse.che.core + che-core-api-languageserver + + + org.eclipse.che.core + che-core-api-languageserver-shared + + + org.eclipse.che.core + che-core-commons-inject + + + org.eclipse.che.plugin + che-plugin-yaml-shared + + + org.eclipse.lsp4j + org.eclipse.lsp4j + + + org.eclipse.lsp4j + org.eclipse.lsp4j.jsonrpc + + + org.slf4j + slf4j-api + + + + + + src/main/java + + + src/main/resources + + + + diff --git a/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/inject/YamlModule.java b/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/inject/YamlModule.java new file mode 100644 index 0000000000..5e28adf894 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/inject/YamlModule.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.server.inject; + +import static java.util.Arrays.asList; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; +import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncher; +import org.eclipse.che.api.languageserver.shared.model.LanguageDescription; +import org.eclipse.che.inject.DynaModule; +import org.eclipse.che.plugin.yaml.server.languageserver.YamlLanguageServerLauncher; +import org.eclipse.che.plugin.yaml.server.languageserver.YamlService; + +/** + * Yaml module for server side of Yaml Language Server + * + * @author Joshua Pinkney + */ +@DynaModule +public class YamlModule extends AbstractModule { + public static final String LANGUAGE_ID = "yaml"; + private static final String[] EXTENSIONS = new String[] {"yaml", "yml"}; + private static final String MIME_TYPE = "text/yaml"; + + @Override + protected void configure() { + Multibinder.newSetBinder(binder(), LanguageServerLauncher.class) + .addBinding() + .to(YamlLanguageServerLauncher.class); + LanguageDescription description = new LanguageDescription(); + description.setFileExtensions(asList(EXTENSIONS)); + description.setLanguageId(LANGUAGE_ID); + description.setMimeType(MIME_TYPE); + Multibinder.newSetBinder(binder(), LanguageDescription.class) + .addBinding() + .toInstance(description); + + bind(YamlService.class); + } +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/languageserver/YamlLanguageServerLauncher.java b/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/languageserver/YamlLanguageServerLauncher.java new file mode 100644 index 0000000000..cdbaf8499a --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/languageserver/YamlLanguageServerLauncher.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.server.languageserver; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import javax.inject.Named; +import org.eclipse.che.api.core.ApiException; +import org.eclipse.che.api.core.rest.HttpJsonRequestFactory; +import org.eclipse.che.api.languageserver.exception.LanguageServerException; +import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncher; +import org.eclipse.che.api.languageserver.launcher.LanguageServerLauncherTemplate; +import org.eclipse.che.api.languageserver.registry.DocumentFilter; +import org.eclipse.che.api.languageserver.registry.LanguageServerDescription; +import org.eclipse.che.api.languageserver.registry.ServerInitializerObserver; +import org.eclipse.che.plugin.yaml.server.inject.YamlModule; +import org.eclipse.che.plugin.yaml.shared.PreferenceHelper; +import org.eclipse.che.plugin.yaml.shared.YamlPreference; +import org.eclipse.lsp4j.ServerCapabilities; +import org.eclipse.lsp4j.jsonrpc.Endpoint; +import org.eclipse.lsp4j.jsonrpc.Launcher; +import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints; +import org.eclipse.lsp4j.services.LanguageClient; +import org.eclipse.lsp4j.services.LanguageServer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Launcher for Yaml Language Server + * + * @author Joshua Pinkney + */ +@Singleton +public class YamlLanguageServerLauncher extends LanguageServerLauncherTemplate + implements ServerInitializerObserver { + + private static final Logger LOG = LoggerFactory.getLogger(YamlLanguageServerLauncher.class); + + private static final String REGEX = ".*\\.(yaml|yml)"; + private static final LanguageServerDescription DESCRIPTION = createServerDescription(); + private static LanguageServer yamlLanguageServer; + private final Path launchScript; + private HttpJsonRequestFactory requestFactory; + private String apiUrl; + + @Inject + public YamlLanguageServerLauncher( + @Named("che.api") String apiUrl, HttpJsonRequestFactory requestFactory) { + this.apiUrl = apiUrl; + this.requestFactory = requestFactory; + launchScript = Paths.get(System.getenv("HOME"), "che/ls-yaml/launch.sh"); + } + + @Override + public boolean isAbleToLaunch() { + return Files.exists(launchScript); + } + + protected LanguageServer connectToLanguageServer( + final Process languageServerProcess, LanguageClient client) { + Launcher launcher = + Launcher.createLauncher( + client, + LanguageServer.class, + languageServerProcess.getInputStream(), + languageServerProcess.getOutputStream()); + launcher.startListening(); + setYamlLanguageServer(launcher.getRemoteProxy()); + return launcher.getRemoteProxy(); + } + + protected Process startLanguageServerProcess(String projectPath) throws LanguageServerException { + ProcessBuilder processBuilder = new ProcessBuilder(launchScript.toString()); + processBuilder.redirectInput(ProcessBuilder.Redirect.PIPE); + processBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE); + try { + return processBuilder.start(); + } catch (IOException e) { + throw new LanguageServerException("Can't start YAML language server", e); + } + } + + protected static LanguageServer getYamlLanguageServer() { + return yamlLanguageServer; + } + + protected static void setYamlLanguageServer(LanguageServer yamlLanguageServer) { + YamlLanguageServerLauncher.yamlLanguageServer = yamlLanguageServer; + } + + @Override + public void onServerInitialized( + LanguageServerLauncher launcher, + LanguageServer server, + ServerCapabilities capabilities, + String projectPath) { + + try { + Map preferences = + requestFactory.fromUrl(apiUrl + "/preferences").useGetMethod().request().asProperties(); + + Endpoint endpoint = ServiceEndpoints.toEndpoint(server); + YamlSchemaAssociations serviceObject = + ServiceEndpoints.toServiceObject(endpoint, YamlSchemaAssociations.class); + Map associations = + jsonToSchemaAssociations(preferences.get("yaml.preferences")); + serviceObject.yamlSchemaAssociation(associations); + + } catch (ApiException | IOException e) { + LOG.error(e.getLocalizedMessage(), e); + } + } + + /** + * Converts json string to map of schema associations + * + * @param jsonStr The json string you would like to change to schema association + * @return Map of schema associations + */ + private Map jsonToSchemaAssociations(String jsonStr) { + List preferenceList = jsonToYamlPreference(jsonStr); + + if (preferenceList == null) { + return null; + } + + Map> preferenceSchemaMap = + PreferenceHelper.yamlPreferenceToMap(preferenceList); + Map jsonSchemaMap = new HashMap(); + for (Map.Entry> preferenceEntry : preferenceSchemaMap.entrySet()) { + jsonSchemaMap.put( + preferenceEntry.getKey(), preferenceEntry.getValue().toArray(new String[0])); + } + return jsonSchemaMap; + } + + /** + * Converts json string to yaml preference + * + * @param jsonStr The json string you would like to change into Yaml Preferences + * @return List of Yaml Preferences + */ + private List jsonToYamlPreference(String jsonStr) { + + List preferences = new ArrayList(); + + Type type = new TypeToken>() {}.getType(); + Map yamlPreferenceMap = new Gson().fromJson(jsonStr, type); + + if (yamlPreferenceMap == null || jsonStr == "") { + return new ArrayList(); + } + + for (Map.Entry yamlPreferenceMapItem : yamlPreferenceMap.entrySet()) { + for (String url : yamlPreferenceMapItem.getValue()) { + YamlPreference newYamlPref = new YamlPreference(url, yamlPreferenceMapItem.getKey()); + preferences.add(newYamlPref); + } + } + + return preferences; + } + + public LanguageServerDescription getDescription() { + return DESCRIPTION; + } + + private static LanguageServerDescription createServerDescription() { + LanguageServerDescription description = + new LanguageServerDescription( + "org.eclipse.che.plugin.yaml.server.languageserver", + null, + Arrays.asList(new DocumentFilter(YamlModule.LANGUAGE_ID, REGEX, null))); + return description; + } +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/languageserver/YamlSchemaAssociations.java b/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/languageserver/YamlSchemaAssociations.java new file mode 100644 index 0000000000..a0e52e9565 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/languageserver/YamlSchemaAssociations.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.server.languageserver; + +import java.util.Map; +import org.eclipse.lsp4j.jsonrpc.services.JsonNotification; + +/** + * Interface for schema associations. + * + * @author Joshua Pinkney + */ +public interface YamlSchemaAssociations { + + @JsonNotification(value = "json/schemaAssociations", useSegment = false) + void yamlSchemaAssociation(Map associations); +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/languageserver/YamlService.java b/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/languageserver/YamlService.java new file mode 100644 index 0000000000..4843626154 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-server/src/main/java/org/eclipse/che/plugin/yaml/server/languageserver/YamlService.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.server.languageserver; + +import com.google.gson.Gson; +import java.util.HashMap; +import java.util.Map; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import org.eclipse.che.api.core.ApiException; +import org.eclipse.che.plugin.yaml.shared.YamlDTO; +import org.eclipse.lsp4j.jsonrpc.Endpoint; +import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints; +import org.eclipse.lsp4j.services.LanguageServer; + +/** + * The yaml server side endpoint for injecting the schema into yaml language server + * + * @author Joshua Pinkney + */ +@Path("yaml") +public class YamlService { + + /** + * Route for getting getting schemas from client side and injecting them into yaml language server + * + * @param yamlDto A yamlDTO containing the list of schemas you would like to add + */ + @POST + @Path("schemas") + @Consumes(MediaType.APPLICATION_JSON) + public void putSchemas(YamlDTO yamlDto) throws ApiException { + + LanguageServer yamlLS = YamlLanguageServerLauncher.getYamlLanguageServer(); + + if (yamlDto != null && yamlLS != null) { + + Endpoint endpoint = ServiceEndpoints.toEndpoint(yamlLS); + YamlSchemaAssociations serviceObject = + ServiceEndpoints.toServiceObject(endpoint, YamlSchemaAssociations.class); + + Map schemaAssociations = new HashMap<>(); + Map yamlDtoSchemas = yamlDto.getSchemas(); + + for (Map.Entry schema : yamlDtoSchemas.entrySet()) { + schemaAssociations.put( + schema.getKey(), new Gson().fromJson(schema.getValue(), String[].class)); + } + + serviceObject.yamlSchemaAssociation(schemaAssociations); + } + } +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-shared/pom.xml b/plugins/plugin-yaml/che-plugin-yaml-shared/pom.xml new file mode 100644 index 0000000000..f900bf6601 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-shared/pom.xml @@ -0,0 +1,155 @@ + + + + 4.0.0 + + che-plugin-yaml-parent + org.eclipse.che.plugin + 5.19.0-SNAPSHOT + + che-plugin-yaml-shared + jar + Che Plugin :: Yaml :: Shared + + ${project.build.directory}/generated-sources/dto/ + false + + + + com.google.code.gson + gson + + + com.google.inject + guice + + + org.eclipse.che.core + che-core-api-dto + + + org.eclipse.che.core + che-core-commons-gwt + + + com.google.gwt + gwt-user + provided + + + + + + src/main/java + + + src/main/resources + + + ${dto-generator-out-directory} + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-resource + process-sources + + add-resource + + + + + ${dto-generator-out-directory}/META-INF + META-INF + + + + + + add-source + process-sources + + add-source + + + + ${dto-generator-out-directory} + + + + + + + maven-compiler-plugin + + + pre-compile + generate-sources + + compile + + + + + + org.eclipse.che.core + che-core-api-dto-maven-plugin + ${project.version} + + + generate-client-dto + process-sources + + generate + + + + org.eclipse.che.plugin.yaml.shared + + ${dto-generator-out-directory} + org.eclipse.che.plugin.yaml.ide.dto.DtoClientImpls + client + + + + generate-server-dto + process-sources + + generate + + + + org.eclipse.che.plugin.yaml.shared + + ${dto-generator-out-directory} + org.eclipse.che.plugin.yaml.server.dto.DtoServerImpls + server + + + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + + + + + + diff --git a/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/PreferenceHelper.java b/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/PreferenceHelper.java new file mode 100644 index 0000000000..308a6f797b --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/PreferenceHelper.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.shared; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Shared class between yaml client and server + * + * @author Joshua Pinkney + */ +public class PreferenceHelper { + + /** + * Converts List of Yaml Preferences to Map of Globs to List of urls + * + * @param pref The list of Yaml Preferences you want to convert + * @return Map of Globs to List of urls of the Yaml Preferences + */ + public static Map> yamlPreferenceToMap(List pref) { + Map> preferenceMap = new HashMap>(); + + for (YamlPreference prefItr : pref) { + + if (preferenceMap.containsKey(prefItr.getGlob())) { + ArrayList prefList = new ArrayList(preferenceMap.get(prefItr.getGlob())); + prefList.add(prefItr.getUrl()); + preferenceMap.put(prefItr.getGlob(), prefList); + } else { + ArrayList prefList = new ArrayList(); + prefList.add(prefItr.getUrl()); + preferenceMap.put(prefItr.getGlob(), prefList); + } + } + + return preferenceMap; + } +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/YamlDTO.java b/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/YamlDTO.java new file mode 100644 index 0000000000..a8a1946a86 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/YamlDTO.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.shared; + +import java.util.Map; +import org.eclipse.che.dto.shared.DTO; + +/** + * Interface of DTO for sending schemas + * + * @author Joshua Pinkney + */ +@DTO +public interface YamlDTO { + /** + * Get the schemas in the DTO + * + * @return Map of Schemas in the DTO + */ + Map getSchemas(); + + /** + * Set the schemas in the DTO + * + * @param schemas The schemas to set in the DTO + */ + void setSchemas(Map schemas); + + YamlDTO withSchemas(Map schemas); +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/YamlDTOImpl.java b/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/YamlDTOImpl.java new file mode 100644 index 0000000000..77f29fe6e8 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/YamlDTOImpl.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.shared; + +import java.util.Map; + +/** + * Implementation of {@link YamlDTO} + * + * @author Joshua Pinkney + */ +public class YamlDTOImpl implements YamlDTO { + + private Map schemas; + + /** {@inheritDoc} */ + @Override + public Map getSchemas() { + return this.schemas; + } + + /** {@inheritDoc} */ + @Override + public void setSchemas(Map schemas) { + this.schemas = schemas; + } + + @Override + public YamlDTO withSchemas(Map schemas) { + this.schemas = schemas; + return this; + } +} diff --git a/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/YamlPreference.java b/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/YamlPreference.java new file mode 100644 index 0000000000..1aa974f273 --- /dev/null +++ b/plugins/plugin-yaml/che-plugin-yaml-shared/src/main/java/org/eclipse/che/plugin/yaml/shared/YamlPreference.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * 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: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.yaml.shared; + +/** + * Establishes the format for Yaml Preferences + * + * @author Joshua Pinkney + */ +public class YamlPreference { + + private String url; + private String glob; + + public YamlPreference(String url, String glob) { + this.url = url; + this.glob = glob; + } + + public String getUrl() { + return this.url; + } + + public String getGlob() { + return this.glob; + } + + public void setUrl(String url) { + this.url = url; + } + + public void setGlob(String glob) { + this.glob = glob; + } +} diff --git a/plugins/plugin-yaml/pom.xml b/plugins/plugin-yaml/pom.xml new file mode 100644 index 0000000000..43a65ebc72 --- /dev/null +++ b/plugins/plugin-yaml/pom.xml @@ -0,0 +1,30 @@ + + + + 4.0.0 + + che-plugin-parent + org.eclipse.che.plugin + 5.19.0-SNAPSHOT + ../pom.xml + + che-plugin-yaml-parent + pom + Che Plugin :: YAML :: Parent + + che-plugin-yaml-shared + che-plugin-yaml-ide + che-plugin-yaml-server + + diff --git a/plugins/pom.xml b/plugins/pom.xml index c0ed29bfb7..364e57af4e 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -60,5 +60,6 @@ plugin-testing-php plugin-pullrequest-parent plugin-traefik + plugin-yaml diff --git a/pom.xml b/pom.xml index baf99cb28c..1da2dc4054 100644 --- a/pom.xml +++ b/pom.xml @@ -201,6 +201,11 @@ ls-typescript-agent ${che.version} + + org.eclipse.che + ls-yaml-agent + ${che.version} + org.eclipse.che ssh-agent @@ -1292,6 +1297,21 @@ che-plugin-web-ext-web ${che.version} + + org.eclipse.che.plugin + che-plugin-yaml-ide + ${che.version} + + + org.eclipse.che.plugin + che-plugin-yaml-server + ${che.version} + + + org.eclipse.che.plugin + che-plugin-yaml-shared + ${che.version} + org.eclipse.che.plugin che-plugin-zend-debugger-ide diff --git a/wsmaster/che-core-api-account/src/main/java/org/eclipse/che/account/spi/jpa/JpaAccountDao.java b/wsmaster/che-core-api-account/src/main/java/org/eclipse/che/account/spi/jpa/JpaAccountDao.java index 3e68d63f53..6817b29f0c 100644 --- a/wsmaster/che-core-api-account/src/main/java/org/eclipse/che/account/spi/jpa/JpaAccountDao.java +++ b/wsmaster/che-core-api-account/src/main/java/org/eclipse/che/account/spi/jpa/JpaAccountDao.java @@ -14,7 +14,6 @@ import static java.lang.String.format; import static java.util.Objects.requireNonNull; import com.google.inject.persist.Transactional; -import java.util.Optional; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Singleton; @@ -111,7 +110,9 @@ public class JpaAccountDao implements AccountDao { @Transactional protected void doCreate(AccountImpl account) { - managerProvider.get().persist(account); + final EntityManager manager = managerProvider.get(); + manager.persist(account); + manager.flush(); } @Transactional @@ -127,10 +128,12 @@ public class JpaAccountDao implements AccountDao { } @Transactional - protected Optional doRemove(String id) { + protected void doRemove(String id) { final EntityManager manager = managerProvider.get(); - final Optional account = Optional.ofNullable(manager.find(AccountImpl.class, id)); - account.ifPresent(manager::remove); - return account; + AccountImpl account = manager.find(AccountImpl.class, id); + if (account != null) { + manager.remove(account); + manager.flush(); + } } } diff --git a/wsmaster/che-core-api-account/src/test/java/org/eclipse/che/account/spi/tck/AccountDaoTest.java b/wsmaster/che-core-api-account/src/test/java/org/eclipse/che/account/spi/tck/AccountDaoTest.java index ff7eb603c1..48a2e8ff3b 100644 --- a/wsmaster/che-core-api-account/src/test/java/org/eclipse/che/account/spi/tck/AccountDaoTest.java +++ b/wsmaster/che-core-api-account/src/test/java/org/eclipse/che/account/spi/tck/AccountDaoTest.java @@ -96,6 +96,14 @@ public class AccountDaoTest { accountDao.update(account); } + @Test(expectedExceptions = ConflictException.class) + public void shouldThrowConflictExceptionWhenCreatingAccountWithExistingName() throws Exception { + AccountImpl account = + new AccountImpl(NameGenerator.generate("account", 5), accounts[0].getName(), "test"); + + accountDao.create(account); + } + @Test(expectedExceptions = NotFoundException.class) public void shouldThrowNotFoundExceptionWhenUpdatingNonExistingAccount() throws Exception { AccountImpl account = accounts[0];