/*******************************************************************************
* 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.ext.java.client.project.classpath;
import com.google.common.base.Optional;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.web.bindery.event.shared.EventBus;
import org.eclipse.che.api.promises.client.Operation;
import org.eclipse.che.api.promises.client.OperationException;
import org.eclipse.che.api.promises.client.Promise;
import org.eclipse.che.api.promises.client.PromiseError;
import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.api.notification.NotificationManager;
import org.eclipse.che.ide.api.resources.Project;
import org.eclipse.che.ide.api.resources.Resource;
import org.eclipse.che.ide.dto.DtoFactory;
import org.eclipse.che.ide.ext.java.shared.ClasspathEntryKind;
import org.eclipse.che.ide.ext.java.shared.dto.classpath.ClasspathEntryDto;
import org.eclipse.che.plugin.java.plain.client.service.ClasspathUpdaterServiceClient;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.google.common.base.Preconditions.checkState;
import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.EMERGE_MODE;
import static org.eclipse.che.ide.api.notification.StatusNotification.Status.FAIL;
import static org.eclipse.che.ide.ext.java.shared.ClasspathEntryKind.LIBRARY;
import static org.eclipse.che.ide.ext.java.shared.ClasspathEntryKind.PROJECT;
import static org.eclipse.che.ide.ext.java.shared.ClasspathEntryKind.SOURCE;
/**
* Class supports project classpath. It reads classpath content, parses its and writes.
*
* @author Valeriy Svydenko
*/
@Singleton
public class ClasspathResolver {
private final static String WORKSPACE_PATH = "/projects";
private final ClasspathUpdaterServiceClient classpathUpdater;
private final NotificationManager notificationManager;
private final EventBus eventBus;
private final AppContext appContext;
private final DtoFactory dtoFactory;
private Set<String> libs;
private Set<String> sources;
private Set<String> projects;
private Set<ClasspathEntryDto> containers;
@Inject
public ClasspathResolver(ClasspathUpdaterServiceClient classpathUpdater,
NotificationManager notificationManager,
EventBus eventBus,
AppContext appContext,
DtoFactory dtoFactory) {
this.classpathUpdater = classpathUpdater;
this.notificationManager = notificationManager;
this.eventBus = eventBus;
this.appContext = appContext;
this.dtoFactory = dtoFactory;
}
/** Reads and parses classpath entries. */
public void resolveClasspathEntries(List<ClasspathEntryDto> entries) {
libs = new HashSet<>();
containers = new HashSet<>();
sources = new HashSet<>();
projects = new HashSet<>();
for (ClasspathEntryDto entry : entries) {
switch (entry.getEntryKind()) {
case ClasspathEntryKind.LIBRARY:
libs.add(entry.getPath());
break;
case ClasspathEntryKind.CONTAINER:
containers.add(entry);
break;
case ClasspathEntryKind.SOURCE:
sources.add(entry.getPath());
break;
case ClasspathEntryKind.PROJECT:
projects.add(WORKSPACE_PATH + entry.getPath());
break;
default:
// do nothing
}
}
}
/** Concatenates classpath entries and update classpath file. */
public Promise<Void> updateClasspath() {
final Resource resource = appContext.getResource();
checkState(resource != null);
final Optional<Project> optProject = resource.getRelatedProject();
checkState(optProject.isPresent());
final List<ClasspathEntryDto> entries = new ArrayList<>();
for (String path : libs) {
entries.add(dtoFactory.createDto(ClasspathEntryDto.class).withPath(path).withEntryKind(LIBRARY));
}
for (ClasspathEntryDto container : containers) {
entries.add(container);
}
for (String path : sources) {
entries.add(dtoFactory.createDto(ClasspathEntryDto.class).withPath(path).withEntryKind(SOURCE));
}
for (String path : projects) {
entries.add(dtoFactory.createDto(ClasspathEntryDto.class).withPath(path).withEntryKind(PROJECT));
}
final Project project = optProject.get();
Promise<Void> promise = classpathUpdater.setRawClasspath(project.getLocation().toString(), entries);
promise.then(new Operation<Void>() {
@Override
public void apply(Void arg) throws OperationException {
project.synchronize().then(new Operation<Resource[]>() {
@Override
public void apply(Resource[] arg) throws OperationException {
eventBus.fireEvent(new ClasspathChangedEvent(project.getLocation().toString(), entries));
}
});
}
}).catchError(new Operation<PromiseError>() {
@Override
public void apply(PromiseError arg) throws OperationException {
notificationManager.notify("Problems with updating classpath", arg.getMessage(), FAIL, EMERGE_MODE);
}
});
return promise;
}
/** Returns list of libraries from classpath. */
public Set<String> getLibs() {
return libs;
}
/** Returns list of containers from classpath. */
public Set<ClasspathEntryDto> getContainers() {
return containers;
}
/** Returns list of sources from classpath. */
public Set<String> getSources() {
return sources;
}
/** Returns list of projects from classpath. */
public Set<String> getProjects() {
return projects;
}
}