/*******************************************************************************
* Copyright (c) 2012-2017 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.api.command;
import org.eclipse.che.api.core.model.machine.Command;
import org.eclipse.che.commons.annotation.Nullable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import static java.util.Collections.unmodifiableSet;
import static org.eclipse.che.api.workspace.shared.Constants.COMMAND_GOAL_ATTRIBUTE_NAME;
import static org.eclipse.che.api.workspace.shared.Constants.COMMAND_PREVIEW_URL_ATTRIBUTE_NAME;
/** Data object for {@link Command}. */
public class CommandImpl implements Command {
private final String typeId;
private final ApplicableContext context;
private String name;
private String commandLine;
private Map<String, String> attributes;
/** Creates new {@link CommandImpl} based on the given data. */
public CommandImpl(Command command, ApplicableContext context) {
this(command.getName(),
command.getCommandLine(),
command.getType(),
new HashMap<>(command.getAttributes()),
context);
}
/** Creates new {@link CommandImpl} based on the provided data. */
public CommandImpl(String name, String commandLine, String typeId) {
this(name, commandLine, typeId, new HashMap<>());
}
/** Creates copy of the given {@link Command}. */
public CommandImpl(Command command) {
this(command.getName(),
command.getCommandLine(),
command.getType(),
new HashMap<>(command.getAttributes()));
}
/** Creates copy of the given {@code command}. */
public CommandImpl(CommandImpl command) {
this(command.getName(),
command.getCommandLine(),
command.getType(),
new HashMap<>(command.getAttributes()),
new ApplicableContext(command.getApplicableContext()));
}
/** Creates new {@link CommandImpl} based on the provided data. */
public CommandImpl(String name, String commandLine, String typeId, Map<String, String> attributes) {
this.name = name;
this.commandLine = commandLine;
this.typeId = typeId;
this.attributes = attributes;
this.context = new ApplicableContext();
}
/** Creates new {@link CommandImpl} based on the provided data. */
public CommandImpl(String name, String commandLine, String typeId, Map<String, String> attributes, ApplicableContext context) {
this.name = name;
this.commandLine = commandLine;
this.typeId = typeId;
this.attributes = attributes;
this.context = context;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getCommandLine() {
return commandLine;
}
public void setCommandLine(String commandLine) {
this.commandLine = commandLine;
}
@Override
public String getType() {
return typeId;
}
@Override
public Map<String, String> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, String> attributes) {
this.attributes = attributes;
}
/** Returns ID of the command's goal or {@code null} if none. */
@Nullable
public String getGoal() {
return getAttributes().get(COMMAND_GOAL_ATTRIBUTE_NAME);
}
/** Sets command's goal ID. */
public void setGoal(String goalId) {
getAttributes().put(COMMAND_GOAL_ATTRIBUTE_NAME, goalId);
}
/** Returns command's preview URL or {@code null} if none. */
@Nullable
public String getPreviewURL() {
return getAttributes().get(COMMAND_PREVIEW_URL_ATTRIBUTE_NAME);
}
/** Sets command's preview URL. */
public void setPreviewURL(String previewURL) {
getAttributes().put(COMMAND_PREVIEW_URL_ATTRIBUTE_NAME, previewURL);
}
/** Returns command's applicable context. */
public ApplicableContext getApplicableContext() {
return context;
}
/**
* {@inheritDoc}
*
* @see #equalsIgnoreContext(CommandImpl)
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof CommandImpl)) {
return false;
}
CommandImpl other = (CommandImpl)o;
return Objects.equals(getName(), other.getName())
&& Objects.equals(typeId, other.typeId)
&& Objects.equals(commandLine, other.commandLine)
&& Objects.equals(getAttributes(), other.getAttributes())
&& Objects.equals(getApplicableContext(), other.getApplicableContext());
}
/**
* Compares this {@link CommandImpl} to another {@link CommandImpl}, ignoring applicable context considerations.
*
* @param anotherCommand
* the {@link CommandImpl} to compare this {@link CommandImpl} against
* @return {@code true} if the argument represents an equivalent {@link CommandImpl}
* ignoring applicable context; {@code false} otherwise
*/
public boolean equalsIgnoreContext(CommandImpl anotherCommand) {
if (this == anotherCommand) {
return true;
}
return Objects.equals(getName(), anotherCommand.getName())
&& Objects.equals(typeId, anotherCommand.typeId)
&& Objects.equals(commandLine, anotherCommand.commandLine)
&& Objects.equals(getAttributes(), anotherCommand.getAttributes());
}
@Override
public int hashCode() {
return Objects.hash(name, typeId, commandLine, getAttributes(), getApplicableContext());
}
/** Defines the context in which command is applicable. */
public static class ApplicableContext {
private boolean workspaceApplicable;
private Set<String> projects;
/** Creates new {@link ApplicableContext} which is workspace applicable. */
public ApplicableContext() {
workspaceApplicable = true;
projects = new HashSet<>();
}
/** Creates new {@link ApplicableContext} which is applicable to the single project only. */
public ApplicableContext(String projectPath) {
projects = new HashSet<>();
projects.add(projectPath);
}
/** Creates new {@link ApplicableContext} based on the provided data. */
public ApplicableContext(boolean workspaceApplicable, Set<String> projects) {
this.workspaceApplicable = workspaceApplicable;
this.projects = projects;
}
/** Creates copy of the given {@code context}. */
public ApplicableContext(ApplicableContext context) {
this(context.isWorkspaceApplicable(), new HashSet<>(context.getApplicableProjects()));
}
/** Returns {@code true} if command is applicable to the workspace and {@code false} otherwise. */
public boolean isWorkspaceApplicable() {
return workspaceApplicable;
}
/** Sets whether the command should be applicable to the workspace or not. */
public void setWorkspaceApplicable(boolean applicable) {
this.workspaceApplicable = applicable;
}
/** Returns <b>immutable</b> list of the paths of the applicable projects. */
public Set<String> getApplicableProjects() {
return unmodifiableSet(projects);
}
/** Adds applicable project's path. */
public void addProject(String path) {
projects.add(path);
}
/** Removes applicable project's path. */
public void removeProject(String path) {
projects.remove(path);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof ApplicableContext)) {
return false;
}
ApplicableContext other = (ApplicableContext)o;
return workspaceApplicable == other.workspaceApplicable &&
Objects.equals(projects, other.projects);
}
@Override
public int hashCode() {
return Objects.hash(workspaceApplicable, projects);
}
}
}