From d14dae95c7f4880451088d04d0c1fc80cb5b6bc7 Mon Sep 17 00:00:00 2001 From: Vitalii Parfonov Date: Thu, 14 Sep 2017 15:38:03 +0300 Subject: [PATCH] CHE-6162: Fix problem project detection procedure (#6264) * Fix problem project detection Signed-off-by: Vitalii Parfonov * Add problems descriptor to MutableProjectConfig Signed-off-by: Vitalii Parfonov * Avoid call updatePresntation on get Signed-off-by: Vitalii Parfonov * Move class to the shared lib Signed-off-by: Vitalii Parfonov --- .../api/core/model/project/ProjectConfig.java | 2 + .../core/model/project/ProjectProblem.java | 19 +++++ .../ide/api/project/MutableProjectConfig.java | 8 ++ .../ide/api/project/NewProjectConfigImpl.java | 7 ++ .../project/ProjectExplorerPresenter.java | 34 +++++---- .../che/ide/resources/impl/ProjectImpl.java | 22 +++++- .../che/ide/resources/tree/ResourceNode.java | 30 ++++---- .../eclipse/che/ide/ui/smartTree/Tree.java | 76 ++++++++++--------- .../che/api/project/server/DtoConverter.java | 7 +- .../project/server/NewProjectConfigImpl.java | 7 ++ .../api/project/server/ProjectManager.java | 13 ++-- .../che/api/project/server/ProjectTypes.java | 21 ++--- .../api/project/server/RegisteredProject.java | 36 ++++----- .../server/ProjectManagerReadTest.java | 8 +- .../server/ProjectManagerWriteTest.java | 32 ++++---- .../api/project/server/ProjectTypesTest.java | 13 ++-- .../workspace/shared/ProjectProblemImpl.java | 39 ++++++++++ .../shared/dto/NewProjectConfigDto.java | 3 + .../shared/dto/ProjectConfigDto.java | 1 + .../shared/dto/ProjectProblemDto.java | 3 +- .../server/model/impl/ProjectConfigImpl.java | 20 +++++ 21 files changed, 267 insertions(+), 134 deletions(-) create mode 100644 core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/project/ProjectProblem.java create mode 100644 wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/ProjectProblemImpl.java diff --git a/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/project/ProjectConfig.java b/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/project/ProjectConfig.java index 4f70825dd2..32f1516009 100644 --- a/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/project/ProjectConfig.java +++ b/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/project/ProjectConfig.java @@ -31,4 +31,6 @@ public interface ProjectConfig { Map> getAttributes(); SourceStorage getSource(); + + List getProblems(); } diff --git a/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/project/ProjectProblem.java b/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/project/ProjectProblem.java new file mode 100644 index 0000000000..6da8833064 --- /dev/null +++ b/core/che-core-api-model/src/main/java/org/eclipse/che/api/core/model/project/ProjectProblem.java @@ -0,0 +1,19 @@ +/* + * 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.api.core.model.project; + +/** @author Vitalii Parfonov */ +public interface ProjectProblem { + + int getCode(); + + String getMessage(); +} diff --git a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/MutableProjectConfig.java b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/MutableProjectConfig.java index d250e9e5b2..0176179948 100644 --- a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/MutableProjectConfig.java +++ b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/MutableProjectConfig.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Map; import org.eclipse.che.api.core.model.project.NewProjectConfig; import org.eclipse.che.api.core.model.project.ProjectConfig; +import org.eclipse.che.api.core.model.project.ProjectProblem; import org.eclipse.che.api.core.model.project.SourceStorage; import org.eclipse.che.api.machine.shared.dto.CommandDto; @@ -35,6 +36,7 @@ public class MutableProjectConfig implements ProjectConfig { private Map options; private List projects; private List commands; + private List problems; public MutableProjectConfig(ProjectConfig source) { name = source.getName(); @@ -44,6 +46,7 @@ public class MutableProjectConfig implements ProjectConfig { mixins = newArrayList(source.getMixins()); attributes = newHashMap(source.getAttributes()); sourceStorage = new MutableSourceStorage(source.getSource()); + problems = source.getProblems(); } public MutableProjectConfig() {} @@ -119,6 +122,11 @@ public class MutableProjectConfig implements ProjectConfig { return sourceStorage; } + @Override + public List getProblems() { + return problems; + } + public void setSource(SourceStorage sourceStorage) { this.sourceStorage = new MutableSourceStorage(sourceStorage); } diff --git a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/NewProjectConfigImpl.java b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/NewProjectConfigImpl.java index 657330cea0..6d966ce1b2 100644 --- a/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/NewProjectConfigImpl.java +++ b/ide/che-core-ide-api/src/main/java/org/eclipse/che/ide/api/project/NewProjectConfigImpl.java @@ -11,10 +11,12 @@ package org.eclipse.che.ide.api.project; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.che.api.core.model.project.NewProjectConfig; +import org.eclipse.che.api.core.model.project.ProjectProblem; import org.eclipse.che.api.core.model.project.SourceStorage; import org.eclipse.che.api.project.templates.shared.dto.ProjectTemplateDescriptor; import org.eclipse.che.api.workspace.shared.dto.NewProjectConfigDto; @@ -170,4 +172,9 @@ public class NewProjectConfigImpl implements NewProjectConfig { public SourceStorage getSource() { return sourceStorage; } + + @Override + public List getProblems() { + return Collections.emptyList(); + } } diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java index 5850b5693f..e8d69fc355 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/part/explorer/project/ProjectExplorerPresenter.java @@ -478,26 +478,30 @@ public class ProjectExplorerPresenter extends BasePresenter @Override public void onExecute() { - if (view.getTree().getNodeLoader().isBusy()) { - delay(500); + Scheduler.get() + .scheduleDeferred( + () -> { + if (view.getTree().getNodeLoader().isBusy()) { + delay(500); - return; - } + return; + } - final Set updateQueue = Sets.newHashSet(toRefresh); - toRefresh.clear(); + final Set updateQueue = Sets.newHashSet(toRefresh); + toRefresh.clear(); - for (Path path : updateQueue) { - final Node node = getNode(path); + for (Path path : updateQueue) { + final Node node = getNode(path); - if (node == null) { - continue; - } + if (node == null) { + continue; + } - if (getTree().isExpanded(node)) { - view.getTree().getNodeLoader().loadChildren(node, true); - } - } + if (getTree().isExpanded(node)) { + view.getTree().getNodeLoader().loadChildren(node, true); + } + } + }); } } } diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ProjectImpl.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ProjectImpl.java index 246dca084b..53cdea0085 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ProjectImpl.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/impl/ProjectImpl.java @@ -18,13 +18,17 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Optional; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; +import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.eclipse.che.api.core.model.project.ProjectConfig; +import org.eclipse.che.api.core.model.project.ProjectProblem; import org.eclipse.che.api.core.model.project.SourceStorage; import org.eclipse.che.api.project.shared.dto.SourceEstimation; import org.eclipse.che.api.promises.client.Promise; import org.eclipse.che.api.promises.client.PromiseProvider; +import org.eclipse.che.api.workspace.shared.ProjectProblemImpl; import org.eclipse.che.ide.api.resources.Project; import org.eclipse.che.ide.api.resources.marker.Marker; import org.eclipse.che.ide.resource.Path; @@ -43,6 +47,7 @@ class ProjectImpl extends ContainerImpl implements Project { private static final int FOLDER_NOT_EXISTS_ON_FS = 10; private final ProjectConfig reference; + private final List problems; @Inject protected ProjectImpl( @@ -52,6 +57,16 @@ class ProjectImpl extends ContainerImpl implements Project { super(Path.valueOf(reference.getPath()), resourceManager, promiseProvider); this.reference = reference; + if (reference.getProblems() != null) { + problems = + reference + .getProblems() + .stream() + .map(problem -> new ProjectProblemImpl(problem.getCode(), problem.getMessage())) + .collect(Collectors.toList()); + } else { + problems = Collections.emptyList(); + } } /** {@inheritDoc} */ @@ -96,6 +111,11 @@ class ProjectImpl extends ContainerImpl implements Project { return reference.getSource(); } + @Override + public List getProblems() { + return problems; + } + /** {@inheritDoc} */ @Override public ProjectRequest update() { @@ -126,7 +146,7 @@ class ProjectImpl extends ContainerImpl implements Project { /** {@inheritDoc} */ @Override public boolean isProblem() { - return getMarker(ProblemProjectMarker.PROBLEM_PROJECT).isPresent(); + return reference.getProblems() != null && !reference.getProblems().isEmpty(); } /** {@inheritDoc} */ diff --git a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/tree/ResourceNode.java b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/tree/ResourceNode.java index 5a6d77c3ec..d14d5a2078 100644 --- a/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/tree/ResourceNode.java +++ b/ide/che-core-ide-app/src/main/java/org/eclipse/che/ide/resources/tree/ResourceNode.java @@ -29,7 +29,6 @@ import java.util.List; import java.util.Set; import javax.validation.constraints.NotNull; import org.eclipse.che.api.promises.client.Function; -import org.eclipse.che.api.promises.client.FunctionException; import org.eclipse.che.api.promises.client.Promise; import org.eclipse.che.ide.api.data.HasDataObject; import org.eclipse.che.ide.api.data.tree.AbstractTreeNode; @@ -122,22 +121,20 @@ public abstract class ResourceNode extends AbstractTreeNode return ((Container) getData()) .getChildren() .then( - new Function>() { - @Override - public List apply(Resource[] children) throws FunctionException { - if (children == null || children.length == 0) { - return NO_CHILDREN; - } + (Function>) + children -> { + if (children == null || children.length == 0) { + return NO_CHILDREN; + } - final List nodes = newArrayListWithExpectedSize(children.length); + final List nodes = newArrayListWithExpectedSize(children.length); - for (Resource child : children) { - nodes.add(createNode(child)); - } + for (Resource child : children) { + nodes.add(createNode(child)); + } - return unmodifiableList(nodes); - } - }); + return unmodifiableList(nodes); + }); } @Override @@ -146,14 +143,15 @@ public abstract class ResourceNode extends AbstractTreeNode nodePresentation = new NodePresentation(); } - updatePresentation(nodePresentation); + if (update) { + updatePresentation(nodePresentation); + } return nodePresentation; } @Override public void updatePresentation(@NotNull NodePresentation presentation) { - final StringBuilder cssBuilder = new StringBuilder(); final Optional presentableTextMarker = getData().getMarker(PresentableTextMarker.ID); diff --git a/ide/che-core-ide-ui/src/main/java/org/eclipse/che/ide/ui/smartTree/Tree.java b/ide/che-core-ide-ui/src/main/java/org/eclipse/che/ide/ui/smartTree/Tree.java index 493154603a..fb470d2a02 100644 --- a/ide/che-core-ide-ui/src/main/java/org/eclipse/che/ide/ui/smartTree/Tree.java +++ b/ide/che-core-ide-ui/src/main/java/org/eclipse/che/ide/ui/smartTree/Tree.java @@ -1137,50 +1137,56 @@ public class Tree extends FocusWidget } private void onExpand(Node node, NodeDescriptor nodeDescriptor, boolean deep) { - if (isLeaf(node)) { - return; - } + Scheduler.get() + .scheduleDeferred( + () -> { + if (isLeaf(node)) { + return; + } - if (nodeDescriptor.isLoading()) { //node may have been already requested for expanding - return; - } + if (nodeDescriptor.isLoading()) { //node may have been already requested for expanding + return; + } - if (!nodeDescriptor.isExpanded() && nodeLoader != null && (!nodeDescriptor.isLoaded())) { - nodeStorage.removeChildren(node); - nodeDescriptor.setExpand(true); - nodeDescriptor.setExpandDeep(deep); - nodeDescriptor.setLoading(true); - view.onLoadChange(nodeDescriptor, true); - nodeLoader.loadChildren(node); - return; - } + if (!nodeDescriptor.isExpanded() + && nodeLoader != null + && (!nodeDescriptor.isLoaded())) { + nodeStorage.removeChildren(node); + nodeDescriptor.setExpand(true); + nodeDescriptor.setExpandDeep(deep); + nodeDescriptor.setLoading(true); + view.onLoadChange(nodeDescriptor, true); + nodeLoader.loadChildren(node); + return; + } - if (!fireCancellableEvent(new BeforeExpandNodeEvent(node))) { - if (deep) { - nodeDescriptor.setExpandDeep(false); - } + if (!fireCancellableEvent(new BeforeExpandNodeEvent(node))) { + if (deep) { + nodeDescriptor.setExpandDeep(false); + } - return; - } + return; + } - if (!nodeDescriptor.isExpanded()) { - nodeDescriptor.setExpanded(true); + if (!nodeDescriptor.isExpanded()) { + nodeDescriptor.setExpanded(true); - if (!nodeDescriptor.isChildrenRendered()) { - renderChildren(node); - nodeDescriptor.setChildrenRendered(true); - } + if (!nodeDescriptor.isChildrenRendered()) { + renderChildren(node); + nodeDescriptor.setChildrenRendered(true); + } - //direct expand on the view - view.expand(nodeDescriptor); + //direct expand on the view + view.expand(nodeDescriptor); - update(); - fireEvent(new ExpandNodeEvent(node)); - } + update(); + fireEvent(new ExpandNodeEvent(node)); + } - if (deep) { - setExpandChildren(node, true); - } + if (deep) { + setExpandChildren(node, true); + } + }); } private void setExpandChildren(Node node, boolean expand) { diff --git a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/DtoConverter.java b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/DtoConverter.java index b41f2c626b..88abe17990 100644 --- a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/DtoConverter.java +++ b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/DtoConverter.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.stream.Collectors; import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.core.model.project.ProjectConfig; +import org.eclipse.che.api.core.model.project.ProjectProblem; import org.eclipse.che.api.core.model.project.SourceStorage; import org.eclipse.che.api.core.model.project.type.Attribute; import org.eclipse.che.api.project.server.importer.ProjectImporter; @@ -146,7 +147,9 @@ public class DtoConverter { return storageDto; } - public static ProjectProblemDto asDto(RegisteredProject.Problem problem) { - return newDto(ProjectProblemDto.class).withCode(problem.code).withMessage(problem.message); + public static ProjectProblemDto asDto(ProjectProblem problem) { + return newDto(ProjectProblemDto.class) + .withCode(problem.getCode()) + .withMessage(problem.getMessage()); } } diff --git a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/NewProjectConfigImpl.java b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/NewProjectConfigImpl.java index 203f8fedc6..3d42975510 100644 --- a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/NewProjectConfigImpl.java +++ b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/NewProjectConfigImpl.java @@ -14,9 +14,11 @@ import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import org.eclipse.che.api.core.model.project.NewProjectConfig; +import org.eclipse.che.api.core.model.project.ProjectProblem; import org.eclipse.che.api.core.model.project.SourceStorage; import org.eclipse.che.api.project.server.type.BaseProjectType; import org.eclipse.che.api.vfs.Path; @@ -154,6 +156,11 @@ public class NewProjectConfigImpl implements NewProjectConfig { return origin; } + @Override + public List getProblems() { + return Collections.emptyList(); + } + @Override public void setOptions(Map options) { this.options = options; diff --git a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/ProjectManager.java b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/ProjectManager.java index e615a93420..6498f53913 100644 --- a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/ProjectManager.java +++ b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/ProjectManager.java @@ -37,10 +37,10 @@ import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.core.UnauthorizedException; import org.eclipse.che.api.core.model.project.NewProjectConfig; import org.eclipse.che.api.core.model.project.ProjectConfig; +import org.eclipse.che.api.core.model.project.ProjectProblem; import org.eclipse.che.api.core.model.project.SourceStorage; import org.eclipse.che.api.core.model.project.type.ProjectType; import org.eclipse.che.api.core.util.LineConsumerFactory; -import org.eclipse.che.api.project.server.RegisteredProject.Problem; import org.eclipse.che.api.project.server.handlers.CreateProjectHandler; import org.eclipse.che.api.project.server.handlers.ProjectHandlerRegistry; import org.eclipse.che.api.project.server.importer.ProjectImporter; @@ -61,6 +61,7 @@ import org.eclipse.che.api.vfs.impl.file.FileWatcherNotificationListener; import org.eclipse.che.api.vfs.search.Searcher; import org.eclipse.che.api.vfs.search.SearcherProvider; import org.eclipse.che.api.vfs.watcher.FileWatcherManager; +import org.eclipse.che.api.workspace.shared.ProjectProblemImpl; import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -308,9 +309,9 @@ public class ProjectManager { * NewProjectConfig#setPath(String)} field. In this case Project will be created as project of * {@link BaseProjectType} type *
  • - a project will be created as project of {@link BaseProjectType} type with {@link - * Problem#code} = 12 when declared primary project type is not registered, - *
  • - a project will be created with {@link Problem#code} = 12 and without mixin project type - * when declared mixin project type is not registered + * ProjectProblem#getCode()} code} = 12 when declared primary project type is not registered, + *
  • - a project will be created with {@link ProjectProblem#getCode()} code} = 12 and without + * mixin project type when declared mixin project type is not registered *
  • - for creating a project by generator {@link NewProjectConfig#getOptions()} should be * specified. * @@ -377,8 +378,8 @@ public class ProjectManager { } catch (Exception e) { registeredProject = projectRegistry.putProject(projectConfig, asFolder(pathToProject), true, false); - final Problem problem = - new Problem( + final ProjectProblem problem = + new ProjectProblemImpl( NOT_UPDATED_PROJECT, "The project is not updated, caused by " + e.getLocalizedMessage()); registeredProject.getProblems().add(problem); diff --git a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/ProjectTypes.java b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/ProjectTypes.java index e3f3c40c0a..bb6004bb14 100644 --- a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/ProjectTypes.java +++ b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/ProjectTypes.java @@ -22,10 +22,11 @@ import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.che.api.core.NotFoundException; +import org.eclipse.che.api.core.model.project.ProjectProblem; import org.eclipse.che.api.core.model.project.type.Attribute; -import org.eclipse.che.api.project.server.RegisteredProject.Problem; import org.eclipse.che.api.project.server.type.ProjectTypeDef; import org.eclipse.che.api.project.server.type.ProjectTypeRegistry; +import org.eclipse.che.api.workspace.shared.ProjectProblemImpl; /** @author gazarenkov */ public class ProjectTypes { @@ -36,14 +37,14 @@ public class ProjectTypes { private final Map mixins; private final Map all; private final Map attributeDefs; - private final List problems; + private final List problems; ProjectTypes( String projectPath, String type, List mixinTypes, ProjectTypeRegistry projectTypeRegistry, - List problems) { + List problems) { mixins = new HashMap<>(); all = new HashMap<>(); attributeDefs = new HashMap<>(); @@ -55,7 +56,7 @@ public class ProjectTypes { ProjectTypeDef tmpPrimary; if (type == null) { this.problems.add( - new Problem( + new ProjectProblemImpl( PROJECT_TYPE_IS_NOT_REGISTERED, "No primary type defined for " + projectPath + " Base Project Type assigned.")); tmpPrimary = ProjectTypeRegistry.BASE_TYPE; @@ -64,7 +65,7 @@ public class ProjectTypes { tmpPrimary = projectTypeRegistry.getProjectType(type); } catch (NotFoundException e) { this.problems.add( - new Problem( + new ProjectProblemImpl( PROJECT_TYPE_IS_NOT_REGISTERED, "Primary type " + type @@ -76,7 +77,7 @@ public class ProjectTypes { if (!tmpPrimary.isPrimaryable()) { this.problems.add( - new Problem( + new ProjectProblemImpl( PROJECT_TYPE_IS_NOT_REGISTERED, "Project type " + tmpPrimary.getId() @@ -108,7 +109,7 @@ public class ProjectTypes { mixin = projectTypeRegistry.getProjectType(mixinFromConfig); } catch (NotFoundException e) { this.problems.add( - new Problem( + new ProjectProblemImpl( PROJECT_TYPE_IS_NOT_REGISTERED, "Project type " + mixinFromConfig + " is not registered. Skipped.")); continue; @@ -116,7 +117,7 @@ public class ProjectTypes { if (!mixin.isMixable()) { this.problems.add( - new Problem( + new ProjectProblemImpl( PROJECT_TYPE_IS_NOT_REGISTERED, "Project type " + mixin @@ -134,7 +135,7 @@ public class ProjectTypes { final Attribute attribute = attributeDefs.get(attrName); if (attribute != null && !attribute.getProjectType().equals(attr.getProjectType())) { this.problems.add( - new Problem( + new ProjectProblemImpl( ATTRIBUTE_NAME_PROBLEM, format( "Attribute name conflict. Duplicated attributes detected for %s. " @@ -219,7 +220,7 @@ public class ProjectTypes { // check whether it's the same attribute that comes from the common parent PT, e.g. from Base PT. if (attribute != null && !attribute.getProjectType().equals(attr.getProjectType())) { problems.add( - new Problem( + new ProjectProblemImpl( ATTRIBUTE_NAME_PROBLEM, format( "Attribute name conflict. Duplicated attributes detected for %s. " diff --git a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/RegisteredProject.java b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/RegisteredProject.java index 9047537991..30eb10529e 100644 --- a/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/RegisteredProject.java +++ b/wsagent/che-core-api-project/src/main/java/org/eclipse/che/api/project/server/RegisteredProject.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.stream.Collectors; import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.core.model.project.ProjectConfig; +import org.eclipse.che.api.core.model.project.ProjectProblem; import org.eclipse.che.api.core.model.project.SourceStorage; import org.eclipse.che.api.core.model.project.type.Attribute; import org.eclipse.che.api.core.model.project.type.Value; @@ -32,6 +33,7 @@ import org.eclipse.che.api.project.server.type.ValueProvider; import org.eclipse.che.api.project.server.type.ValueStorageException; import org.eclipse.che.api.project.server.type.Variable; import org.eclipse.che.api.vfs.Path; +import org.eclipse.che.api.workspace.shared.ProjectProblemImpl; /** * Internal Project implementation. It is supposed that it is object always consistent. @@ -40,7 +42,7 @@ import org.eclipse.che.api.vfs.Path; */ public class RegisteredProject implements ProjectConfig { - private final List problems; + private final List problems; private final Map attributes; private final FolderEntry folder; @@ -85,14 +87,14 @@ public class RegisteredProject implements ProjectConfig { if (folder == null || folder.isFile()) { problems.add( - new Problem( + new ProjectProblemImpl( NO_PROJECT_ON_FILE_SYSTEM, "No project folder on file system " + this.config.getPath())); } if (config == null) { problems.add( - new Problem( + new ProjectProblemImpl( NO_PROJECT_CONFIGURED_IN_WS, "No project configured in workspace " + this.config.getPath())); } @@ -114,8 +116,8 @@ public class RegisteredProject implements ProjectConfig { } /** - * Initialize project attributes. Note: the problem with {@link Problem#code} = 13 will be added - * when a value for some attribute is not initialized + * Initialize project attributes. Note: the problem with {@link ProjectProblem#getCode()} code} = + * 13 will be added when a value for some attribute is not initialized */ private void initAttributes() { @@ -149,8 +151,8 @@ public class RegisteredProject implements ProjectConfig { valueProvider.setValues(name, value.getList()); } } catch (ValueStorageException e) { - final Problem problem = - new Problem( + final ProjectProblem problem = + new ProjectProblemImpl( ATTRIBUTE_NAME_PROBLEM, format( "Value for attribute %s is not initialized, caused by: %s", @@ -164,8 +166,8 @@ public class RegisteredProject implements ProjectConfig { } if (value.isEmpty() && variable.isRequired()) { - final Problem problem = - new Problem( + final ProjectProblem problem = + new ProjectProblemImpl( ATTRIBUTE_NAME_PROBLEM, "Value for required attribute is not initialized " + variable.getId()); this.problems.add(problem); @@ -226,7 +228,7 @@ public class RegisteredProject implements ProjectConfig { } /** @return problems in case if root or config is null (project is not synced) */ - public List getProblems() { + public List getProblems() { return problems; } @@ -234,8 +236,8 @@ public class RegisteredProject implements ProjectConfig { public String getProblemsStr() { StringBuilder builder = new StringBuilder(); int i = 0; - for (RegisteredProject.Problem prb : problems) { - builder.append("[").append(i++).append("] : ").append(prb.message).append("\n"); + for (ProjectProblem prb : problems) { + builder.append("[").append(i++).append("] : ").append(prb.getMessage()).append("\n"); } return builder.toString(); } @@ -300,14 +302,4 @@ public class RegisteredProject implements ProjectConfig { } return attrs; } - - public static class Problem { - Problem(int code, String message) { - this.code = code; - this.message = message; - } - - int code; - String message; - } } diff --git a/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectManagerReadTest.java b/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectManagerReadTest.java index a0903a3801..9542aae5a4 100644 --- a/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectManagerReadTest.java +++ b/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectManagerReadTest.java @@ -129,12 +129,12 @@ public class ProjectManagerReadTest extends WsAgentTestBase { assertEquals(6, projectRegistry.getProjects().size()); assertEquals(1, projectRegistry.getProject("/foo").getProblems().size()); - assertEquals(12, projectRegistry.getProject("/foo").getProblems().get(0).code); + assertEquals(12, projectRegistry.getProject("/foo").getProblems().get(0).getCode()); //Value for required attribute is not initialized pt3:pt2-var2 //Value for required attribute is not initialized pt3:pt2-provided1 assertEquals(2, projectRegistry.getProject("/bar").getProblems().size()); - assertEquals(13, projectRegistry.getProject("/bar").getProblems().get(0).code); + assertEquals(13, projectRegistry.getProject("/bar").getProblems().get(0).getCode()); } @Test @@ -160,7 +160,7 @@ public class ProjectManagerReadTest extends WsAgentTestBase { assertEquals("fromFolder", pm.getProject("/fromFolder").getName()); assertEquals(1, pm.getProject("/fromFolder").getProblems().size()); assertEquals(BaseProjectType.ID, pm.getProject("/fromFolder").getProjectType().getId()); - assertEquals(11, pm.getProject("/fromFolder").getProblems().get(0).code); + assertEquals(11, pm.getProject("/fromFolder").getProblems().get(0).getCode()); } @Test @@ -169,7 +169,7 @@ public class ProjectManagerReadTest extends WsAgentTestBase { assertEquals("/fromConfig", pm.getProject("/fromConfig").getPath()); assertEquals(1, pm.getProject("/fromConfig").getProblems().size()); assertEquals("primary1", pm.getProject("/fromConfig").getProjectType().getId()); - assertEquals(10, pm.getProject("/fromConfig").getProblems().get(0).code); + assertEquals(10, pm.getProject("/fromConfig").getProblems().get(0).getCode()); } @Test diff --git a/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectManagerWriteTest.java b/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectManagerWriteTest.java index 3e670bfdc4..b6b7c18cce 100644 --- a/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectManagerWriteTest.java +++ b/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectManagerWriteTest.java @@ -36,11 +36,11 @@ import org.eclipse.che.api.core.NotFoundException; import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.core.model.project.NewProjectConfig; import org.eclipse.che.api.core.model.project.ProjectConfig; +import org.eclipse.che.api.core.model.project.ProjectProblem; import org.eclipse.che.api.core.model.project.SourceStorage; import org.eclipse.che.api.core.notification.EventSubscriber; import org.eclipse.che.api.core.util.LineConsumerFactory; import org.eclipse.che.api.core.util.ValueHolder; -import org.eclipse.che.api.project.server.RegisteredProject.Problem; import org.eclipse.che.api.project.server.handlers.CreateProjectHandler; import org.eclipse.che.api.project.server.importer.ProjectImportOutputWSLineConsumer; import org.eclipse.che.api.project.server.importer.ProjectImporter; @@ -505,11 +505,11 @@ public class ProjectManagerWriteTest extends WsAgentTestBase { pm.createBatchProjects(configs, false, new ProjectOutputLineConsumerFactory("ws", 300)); final RegisteredProject project = projectRegistry.getProject(projectPath); - final List problems = project.getProblems(); + final List problems = project.getProblems(); checkProjectExist(projectPath); assertNotEquals(projectType, project.getType()); assertEquals(1, problems.size()); - assertEquals(12, problems.get(0).code); + assertEquals(12, problems.get(0).getCode()); assertEquals(1, projectRegistry.getProjects().size()); } @@ -531,10 +531,10 @@ public class ProjectManagerWriteTest extends WsAgentTestBase { pm.createBatchProjects(configs, false, new ProjectOutputLineConsumerFactory("ws", 300)); final RegisteredProject project = projectRegistry.getProject(projectPath); - final List problems = project.getProblems(); + final List problems = project.getProblems(); checkProjectExist(projectPath); assertEquals(1, problems.size()); - assertEquals(12, problems.get(0).code); + assertEquals(12, problems.get(0).getCode()); assertTrue(project.getMixins().isEmpty()); assertEquals(1, projectRegistry.getProjects().size()); } @@ -580,11 +580,11 @@ public class ProjectManagerWriteTest extends WsAgentTestBase { assertNotNull(pm.getProjectsRoot().getChild(path)); assertEquals(projectType, project.getType()); - List problems = project.getProblems(); + List problems = project.getProblems(); assertNotNull(problems); assertFalse(problems.isEmpty()); assertEquals(1, problems.size()); - assertEquals(13, problems.get(0).code); + assertEquals(13, problems.get(0).getCode()); } @Test @@ -623,7 +623,7 @@ public class ProjectManagerWriteTest extends WsAgentTestBase { final RegisteredProject project = projectRegistry.getProject(path); final List children = project.getBaseFolder().getChildren(); - final List problems = project.getProblems(); + final List problems = project.getProblems(); assertNotNull(project); assertNotNull(pm.getProjectsRoot().getChild(path)); assertEquals(projectTypeId, project.getType()); @@ -631,7 +631,7 @@ public class ProjectManagerWriteTest extends WsAgentTestBase { assertTrue(project.getAttributes().isEmpty()); assertFalse(problems.isEmpty()); assertEquals(1, problems.size()); - assertEquals(13, problems.get(0).code); + assertEquals(13, problems.get(0).getCode()); } @Test @@ -675,11 +675,11 @@ public class ProjectManagerWriteTest extends WsAgentTestBase { assertNotNull(pm.getProjectsRoot().getChild(path)); assertEquals(BaseProjectType.ID, project.getType()); - List problems = project.getProblems(); + List problems = project.getProblems(); assertNotNull(problems); assertFalse(problems.isEmpty()); assertEquals(1, problems.size()); - assertEquals(12, problems.get(0).code); + assertEquals(12, problems.get(0).getCode()); //clean up project.getBaseFolder().getVirtualFile().delete(); @@ -705,7 +705,7 @@ public class ProjectManagerWriteTest extends WsAgentTestBase { assertNotNull(problems); assertFalse(problems.isEmpty()); assertEquals(1, problems.size()); - assertEquals(12, problems.get(0).code); + assertEquals(12, problems.get(0).getCode()); } @Test @@ -732,10 +732,10 @@ public class ProjectManagerWriteTest extends WsAgentTestBase { assertFalse(mixins.isEmpty()); assertEquals(mixin, mixins.get(0)); - final List problems = project.getProblems(); + final List problems = project.getProblems(); assertNotNull(problems); assertFalse(problems.isEmpty()); - assertEquals(13, problems.get(0).code); + assertEquals(13, problems.get(0).getCode()); } @Test @@ -831,11 +831,11 @@ public class ProjectManagerWriteTest extends WsAgentTestBase { RegisteredProject project = pm.updateProject(pc); - final List problems = project.getProblems(); + final List problems = project.getProblems(); assertNotNull(problems); assertFalse(problems.isEmpty()); assertEquals(1, problems.size()); - assertEquals(13, problems.get(0).code); + assertEquals(13, problems.get(0).getCode()); } @Test diff --git a/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectTypesTest.java b/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectTypesTest.java index e0e5d1eefd..dea85bf4a2 100644 --- a/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectTypesTest.java +++ b/wsagent/che-core-api-project/src/test/java/org/eclipse/che/api/project/server/ProjectTypesTest.java @@ -22,6 +22,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; +import org.eclipse.che.api.core.model.project.ProjectProblem; import org.eclipse.che.api.project.server.type.ProjectTypeDef; import org.eclipse.che.api.project.server.type.ProjectTypeRegistry; import org.testng.annotations.Test; @@ -36,7 +37,7 @@ public class ProjectTypesTest extends BaseProjectTypeTest { pts.add(new PersistedMixin()); pts.add(new NotPersistedMixin()); ProjectTypeRegistry reg = new ProjectTypeRegistry(pts); - List problems = new ArrayList<>(); + List problems = new ArrayList<>(); new ProjectTypes( generate("projectPath-", 5), PrimaryType.PRIMARY_ID, @@ -47,7 +48,7 @@ public class ProjectTypesTest extends BaseProjectTypeTest { reg, problems); assertEquals(problems.size(), 1); - assertEquals(problems.get(0).code, 12); + assertEquals(problems.get(0).getCode(), 12); } //@Test(expectedExceptions = ProjectTypeConstraintException.class) @@ -58,7 +59,7 @@ public class ProjectTypesTest extends BaseProjectTypeTest { pts.add(new PrimaryType(otherPrimaryId, generate("projectType-", 5))); pts.add(new PersistedMixin()); ProjectTypeRegistry reg = new ProjectTypeRegistry(pts); - List problems = new ArrayList<>(); + List problems = new ArrayList<>(); new ProjectTypes( generate("projectPath-", 5), PrimaryType.PRIMARY_ID, @@ -66,7 +67,7 @@ public class ProjectTypesTest extends BaseProjectTypeTest { reg, problems); assertEquals(problems.size(), 1); - assertEquals(problems.get(0).code, 12); + assertEquals(problems.get(0).getCode(), 12); } @Test @@ -76,7 +77,7 @@ public class ProjectTypesTest extends BaseProjectTypeTest { pts.add(new PersistedMixin()); pts.add(new NotPersistedMixin()); ProjectTypeRegistry reg = new ProjectTypeRegistry(pts); - List problems = new ArrayList<>(); + List problems = new ArrayList<>(); ProjectTypes projectTypes = new ProjectTypes( generate("projectPath-", 5), @@ -96,7 +97,7 @@ public class ProjectTypesTest extends BaseProjectTypeTest { pts.add(new PrimaryType()); pts.add(new PersistedMixin()); ProjectTypeRegistry reg = new ProjectTypeRegistry(pts); - List problems = new ArrayList<>(); + List problems = new ArrayList<>(); ProjectTypes projectTypes = new ProjectTypes( generate("projectPath-", 5), diff --git a/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/ProjectProblemImpl.java b/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/ProjectProblemImpl.java new file mode 100644 index 0000000000..fb071b197f --- /dev/null +++ b/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/ProjectProblemImpl.java @@ -0,0 +1,39 @@ +/* + * 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.api.workspace.shared; + +import org.eclipse.che.api.core.model.project.ProjectProblem; + +/** @author Vitalii Parfonov */ +public class ProjectProblemImpl implements ProjectProblem { + + public ProjectProblemImpl(ProjectProblem projectProblem) { + this(projectProblem.getCode(), projectProblem.getMessage()); + } + + public ProjectProblemImpl(int code, String message) { + this.code = code; + this.message = message; + } + + int code; + String message; + + @Override + public int getCode() { + return code; + } + + @Override + public String getMessage() { + return message; + } +} diff --git a/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/NewProjectConfigDto.java b/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/NewProjectConfigDto.java index 74ce4ffc52..a9b9d71b18 100644 --- a/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/NewProjectConfigDto.java +++ b/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/NewProjectConfigDto.java @@ -58,6 +58,9 @@ public interface NewProjectConfigDto extends ProjectConfigDto, NewProjectConfig NewProjectConfigDto withLinks(List links); + @Override + List getProblems(); + NewProjectConfigDto withProblems(List problems); NewProjectConfigDto withOptions(Map options); diff --git a/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/ProjectConfigDto.java b/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/ProjectConfigDto.java index f59204d23e..cea44d4174 100644 --- a/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/ProjectConfigDto.java +++ b/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/ProjectConfigDto.java @@ -95,6 +95,7 @@ public interface ProjectConfigDto extends ProjectConfig { value = "Optional information about project errors. If project doesn't have any error this field is empty" ) + @Override List getProblems(); /** @see #getProblems */ diff --git a/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/ProjectProblemDto.java b/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/ProjectProblemDto.java index 5f003f3298..d2da680032 100644 --- a/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/ProjectProblemDto.java +++ b/wsmaster/che-core-api-workspace-shared/src/main/java/org/eclipse/che/api/workspace/shared/dto/ProjectProblemDto.java @@ -10,11 +10,12 @@ */ package org.eclipse.che.api.workspace.shared.dto; +import org.eclipse.che.api.core.model.project.ProjectProblem; import org.eclipse.che.dto.shared.DTO; /** @author Sergii Kabashniuk */ @DTO -public interface ProjectProblemDto { +public interface ProjectProblemDto extends ProjectProblem { int getCode(); diff --git a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/model/impl/ProjectConfigImpl.java b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/model/impl/ProjectConfigImpl.java index a85242cc29..1af1641ee2 100644 --- a/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/model/impl/ProjectConfigImpl.java +++ b/wsmaster/che-core-api-workspace/src/main/java/org/eclipse/che/api/workspace/server/model/impl/ProjectConfigImpl.java @@ -13,10 +13,12 @@ package org.eclipse.che.api.workspace.server.model.impl; import static java.util.stream.Collectors.toMap; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import javax.persistence.CascadeType; import javax.persistence.CollectionTable; import javax.persistence.Column; @@ -38,6 +40,7 @@ import javax.persistence.Table; import javax.persistence.Transient; import org.eclipse.che.api.core.model.project.ProjectConfig; import org.eclipse.che.api.core.model.project.SourceStorage; +import org.eclipse.che.api.workspace.shared.ProjectProblemImpl; /** * Data object for {@link ProjectConfig}. @@ -87,6 +90,8 @@ public class ProjectConfigImpl implements ProjectConfig { // as it is impossible to map nested list directly @Transient private Map> attributes; + @Transient private List problems; + public ProjectConfigImpl() {} public ProjectConfigImpl(ProjectConfig projectConfig) { @@ -109,6 +114,16 @@ public class ProjectConfigImpl implements ProjectConfig { new SourceStorageImpl( sourceStorage.getType(), sourceStorage.getLocation(), sourceStorage.getParameters()); } + if (projectConfig.getProblems() != null) { + problems = + projectConfig + .getProblems() + .stream() + .map(problem -> new ProjectProblemImpl(problem.getCode(), problem.getMessage())) + .collect(Collectors.toList()); + } else { + problems = Collections.emptyList(); + } } @Override @@ -176,6 +191,11 @@ public class ProjectConfigImpl implements ProjectConfig { return source; } + @Override + public List getProblems() { + return problems; + } + public void setSource(SourceStorageImpl sourceStorage) { this.source = sourceStorage; }