/*******************************************************************************
* 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.resources;
import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import org.eclipse.che.api.core.model.project.ProjectConfig;
import org.eclipse.che.api.project.shared.dto.SourceEstimation;
import org.eclipse.che.api.promises.client.Promise;
import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.api.resources.marker.Marker;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* An object that represents client side project.
* <p/>
* Features of projects include:
* <ul>
* <li>A project collects together a set of files and folders.</li>
* <li>A project's location controls where the project's resources are stored in the local file system.</li>
* </ul>
* Project also extends {@link ProjectConfig} which contains the meta-data required to define a project.
* <p/>
* To get list of currently of all loaded projects in the IDE, use {@link AppContext#getProjects()}
* <p/>
* Note. This interface is not intended to be implemented by clients.
*
* @author Vlad Zhukovskyi
* @see AppContext#getProjects()
* @since 4.4.0
*/
@Beta
public interface Project extends Container, ProjectConfig {
/**
* Changes this project resource to match the given configuration provided by the request.
* Request contains all necessary data for manipulating with the project.
* <p/>
* Example of usage:
* <pre>
* ProjectConfig config = ... ;
* Project project = ... ;
*
* Project.ProjectRequest updateRequest = project.update()
* .withBody(config);
*
* Promise<Project> updatedProject = updateRequest.send();
* </pre>
* <p/>
* Fires {@link ResourceChangedEvent} with the following {@link ResourceDelta}:
* Delta kind: {@link ResourceDelta#UPDATED}.
* Updated resource provided by {@link ResourceDelta#getResource()}
* <p/>
* Note. Calling this method doesn't update the project immediately. To complete request
* method {@link ProjectRequest#send()} should be called.
*
* @return the request to update the project
* @see ProjectRequest
* @see ProjectRequest#send()
* @since 4.4.0
*/
ProjectRequest update();
/**
* Check whether current project has problems. Problem project calculates in a runtime, so it is not affects stored
* configuration on the server. To find out the reasons why project has problems, following code snippet may be helpful:
* <p/>
* Example of usage:
* <pre>
* Project project = ... ;
* if (project.isProblem()) {
* Marker problemMarker = getMarker(ProblemProjectMarker.PROBLEM_PROJECT).get();
*
* String message = String.valueOf(problemMarker.getAttribute(Marker.MESSAGE));
* }
* </pre>
*
* @return {@code true} if current project has problems, otherwise {@code false}
* @see ProblemProjectMarker
* @since 4.4.0
*/
boolean isProblem();
/**
* Returns the {@code true} if project physically exists on the file system.
* <p>
* Project may not be exists on file system, but workspace may has configured in the current workspace.
*
* @return {@code true} if project physically exists on the file system, otherwise {@code false}
* @since 4.4.0
*/
boolean exists();
/**
* Resolve possible project types for current {@link Project}.
* <p/>
* These source estimations may be useful for automatically project type detection.
* <p/>
* Source estimation provides possible project type and attributes that this project type can provide.
* Based on this information, current project may be configured in correct way.
*
* @return the {@link Promise} with source estimations
* @since 4.4.0
*/
Promise<List<SourceEstimation>> resolve();
/**
* Checks whether given project {@code type} is applicable to current project.
*
* @param type
* the project type to check
* @return true if given project type is applicable to current project
* @since 4.4.0
*/
boolean isTypeOf(String type);
/**
* Returns the attribute value for given {@code key}.
* If such attribute doesn't exist, {@code null} is returned.
* If there is more than one value exists for given {@code key}, than first value is returned.
*
* @param key
* the attribute name
* @return first value for the given {@code key} or null if such attribute doesn't exist
* @since 4.4.0
*/
String getAttribute(String key);
/**
* Returns the list of attributes for given {@code key}.
* If such attribute doesn't exist, {@code null} is returned.
*
* @param key
* the attribute name
* @return the list with values for the given {@code key} or null if such attribute doesn't exist
* @since 4.4.0
*/
List<String> getAttributes(String key);
/**
* Marker that describe problematic project.
*
* @see #isProblem()
* @since 4.4.0
*/
@Beta
class ProblemProjectMarker implements Marker {
private Map<Integer, String> problems;
/**
* Marker type, which should be used when marker requests.
*
* @see Resource#getMarker(String)
*/
public static final String PROBLEM_PROJECT = "problemProjectMarker";
public ProblemProjectMarker(Map<Integer, String> problems) {
this.problems = MoreObjects.firstNonNull(problems, Collections.<Integer, String>emptyMap());
}
/** {@inheritDoc} */
@Override
public String getType() {
return PROBLEM_PROJECT;
}
public Map<Integer, String> getProblems() {
return problems;
}
}
/**
* Base interface for project update operation.
*
* @see Project#update()
* @since 4.4.0
*/
@Beta
interface ProjectRequest extends Resource.Request<Project, ProjectConfig> {
@Override
Request<Project, ProjectConfig> withBody(ProjectConfig object);
@Override
ProjectConfig getBody();
}
}