PT #150740880: VSCode/Eclipse file watching. Back to project finder
Eclipse client file change listening mechanics Reworked file/project observer implementation Merge fixes
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
|
||||
/**
|
||||
* Cache fo java projects. The key for the cache is a "project" specific file
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
* @param <P> java project sub-class
|
||||
*/
|
||||
public abstract class AbstractFileToProjectCache<P extends IJavaProject> extends AbstractJavaProjectCache<File, P> {
|
||||
|
||||
private String changeSubscription;
|
||||
private String deleteSubscription;
|
||||
|
||||
public AbstractFileToProjectCache(FileObserver fileObserver) {
|
||||
super(fileObserver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void attachListeners(File file, P project) {
|
||||
super.attachListeners(file, project);
|
||||
List<String> globPattern = Arrays.asList(file.toString());
|
||||
changeSubscription = getFileObserver().onFileChanged(globPattern, (uri) -> {
|
||||
update(project);
|
||||
notifyProjectChanged(project);
|
||||
});
|
||||
deleteSubscription = getFileObserver().onFileDeleted(globPattern, (uri) -> {
|
||||
cache.invalidate(file);
|
||||
notifyProjectDeleted(project);
|
||||
getFileObserver().unsubscribe(changeSubscription);
|
||||
getFileObserver().unsubscribe(deleteSubscription);
|
||||
});
|
||||
}
|
||||
|
||||
abstract protected void update(P project);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.ListenerList;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
/**
|
||||
* Abstract implementation of java project cache indexed by keys
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
* @param <K> key class
|
||||
* @param <P> project class
|
||||
*/
|
||||
public abstract class AbstractJavaProjectCache<K, P extends IJavaProject> implements JavaProjectCache<K, P> {
|
||||
|
||||
private FileObserver fileObserver;
|
||||
|
||||
private ListenerList<Listener> listeners = new ListenerList<>();
|
||||
|
||||
protected Cache<K, P> cache = CacheBuilder.newBuilder().build();
|
||||
|
||||
public AbstractJavaProjectCache(FileObserver fileObserver) {
|
||||
this.fileObserver = fileObserver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public P project(K key) {
|
||||
if (key != null) {
|
||||
try {
|
||||
return cache.get(key, () -> {
|
||||
try {
|
||||
P project = createProject(key);
|
||||
attachListeners(key, project);
|
||||
return project;
|
||||
} catch (Throwable t) {
|
||||
throw new ExecutionException(t);
|
||||
}
|
||||
});
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
abstract protected P createProject(K key) throws Exception;
|
||||
|
||||
protected void attachListeners(K key, P project) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
final protected void notifyProjectCreated(P project) {
|
||||
listeners.forEach(l -> l.created(project));
|
||||
}
|
||||
|
||||
final protected void notifyProjectChanged(P project) {
|
||||
listeners.forEach(l -> l.changed(project));
|
||||
}
|
||||
|
||||
final protected void notifyProjectDeleted(P project) {
|
||||
listeners.forEach(l -> l.deleted(project));
|
||||
}
|
||||
|
||||
final protected FileObserver getFileObserver() {
|
||||
return fileObserver;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
* Abstract implementation of Java project finder interface
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractJavaProjectFinder implements JavaProjectFinder {
|
||||
|
||||
@Override
|
||||
public IJavaProject find(IDocument doc) {
|
||||
try {
|
||||
String uriStr = doc.getUri();
|
||||
if (StringUtil.hasText(uriStr)) {
|
||||
URI uri = new URI(uriStr);
|
||||
// TODO: This only work with File uri. Should it work with others
|
||||
// too?
|
||||
if (uri.getScheme().equalsIgnoreCase("file")) {
|
||||
File file = new File(uri).getAbsoluteFile();
|
||||
return find(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver.FileListener;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.util.ListenerList;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
/**
|
||||
* Base implementation of {@link JavaProjectManager}
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractJavaProjectManager implements JavaProjectManager {
|
||||
|
||||
private ListenerList<Listener> listeners;
|
||||
|
||||
private FileObserver fileObserver;
|
||||
|
||||
private Supplier<FileListener> fileListener;
|
||||
|
||||
public AbstractJavaProjectManager() {
|
||||
this.fileListener = Suppliers.memoize(() -> createFileListener());
|
||||
this.listeners = new ListenerList<>();
|
||||
}
|
||||
|
||||
protected FileListener createFileListener() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(IDocument doc) {
|
||||
try {
|
||||
String uriStr = doc.getUri();
|
||||
if (StringUtil.hasText(uriStr)) {
|
||||
URI uri = new URI(uriStr);
|
||||
// TODO: This only work with File uri. Should it work with others
|
||||
// too?
|
||||
if (uri.getScheme().equalsIgnoreCase("file")) {
|
||||
File file = new File(uri).getAbsoluteFile();
|
||||
return find(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFileObserver(FileObserver fileObserver) {
|
||||
FileListener listener= fileListener.get();
|
||||
if (this.fileObserver != null && listener != null) {
|
||||
this.fileObserver.removeListener(listener);
|
||||
}
|
||||
this.fileObserver = fileObserver;
|
||||
if (this.fileObserver != null && listener != null) {
|
||||
this.fileObserver.addListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
final protected FileObserver getFileObserver() {
|
||||
return this.fileObserver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
final protected void notifyProjectCreated(IJavaProject project) {
|
||||
listeners.forEach(l -> l.created(project));
|
||||
}
|
||||
|
||||
final protected void notifyProjectChanged(IJavaProject project) {
|
||||
listeners.forEach(l -> l.changed(project));
|
||||
}
|
||||
|
||||
final protected void notifyProjectDeleted(IJavaProject project) {
|
||||
listeners.forEach(l -> l.deleted(project));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
* Composite project manager that acts a single project manager but consissts of many project managers
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class CompositeJavaProjectFinder implements JavaProjectFinder {
|
||||
|
||||
private final List<JavaProjectFinder> projectFinders;
|
||||
|
||||
public CompositeJavaProjectFinder(Collection<JavaProjectFinder> projectFinders) {
|
||||
this.projectFinders = new ArrayList<>(projectFinders);
|
||||
}
|
||||
|
||||
public CompositeJavaProjectFinder() {
|
||||
this(Collections.emptyList());
|
||||
}
|
||||
|
||||
public boolean addJavaProjectFinder(JavaProjectFinder javaProjectFinder) {
|
||||
return projectFinders.add(javaProjectFinder);
|
||||
}
|
||||
|
||||
public boolean removeJavaProjectFinder(JavaProjectFinder javaProjectFinder) {
|
||||
return projectFinders.remove(javaProjectFinder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(IDocument doc) {
|
||||
return projectFinders.stream().map(finder -> finder.find(doc)).filter(Objects::nonNull).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
return projectFinders.stream().map(finder -> finder.find(file)).filter(Objects::nonNull).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return projectFinders.stream().filter(finder -> finder.isProjectRoot(file)) != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
* Composite project manager that acts a single project manager but consissts of many project managers
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class CompositeJavaProjectManager implements JavaProjectManager {
|
||||
|
||||
private final JavaProjectManager[] projectManagers;
|
||||
|
||||
public CompositeJavaProjectManager(JavaProjectManager[] projectManagers) {
|
||||
this.projectManagers = projectManagers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(IDocument doc) {
|
||||
try {
|
||||
String uriStr = doc.getUri();
|
||||
if (StringUtil.hasText(uriStr)) {
|
||||
URI uri = new URI(uriStr);
|
||||
// TODO: This only work with File uri. Should it work with others
|
||||
// too?
|
||||
if (uri.getScheme().equalsIgnoreCase("file")) {
|
||||
File file = new File(uri).getAbsoluteFile();
|
||||
return find(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
for (JavaProjectManager strategy : projectManagers) {
|
||||
try {
|
||||
IJavaProject project = strategy.find(file);
|
||||
if (project != null) {
|
||||
return project;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
for (JavaProjectManager strategy : projectManagers) {
|
||||
try {
|
||||
if (strategy.isProjectRoot(file)) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setFileObserver(FileObserver fileObserver) {
|
||||
Arrays.stream(projectManagers).forEach(pm -> pm.setFileObserver(fileObserver));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
Arrays.stream(projectManagers).forEach(pm -> pm.addListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener) {
|
||||
Arrays.stream(projectManagers).forEach(pm -> pm.removeListener(listener));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Project Observer that is able to act as a single project observer for a list of observers
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class CompositeProjectOvserver implements ProjectObserver {
|
||||
|
||||
private List<ProjectObserver> observers;
|
||||
|
||||
public CompositeProjectOvserver(List<ProjectObserver> observers) {
|
||||
this.observers = observers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
observers.forEach(o -> o.addListener(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener) {
|
||||
observers.forEach(o -> o.removeListener(listener));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
|
||||
/**
|
||||
* Java Projects Cache
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
* @param <K> key class
|
||||
* @param <P> java project class
|
||||
*/
|
||||
public interface JavaProjectCache<K, P extends IJavaProject> extends ProjectObserver {
|
||||
|
||||
P project(K key);
|
||||
|
||||
}
|
||||
@@ -13,29 +13,17 @@ package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
import java.io.File;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
* Java project manager. Able to find a java project for a file or document and
|
||||
* provide project change listening mechanism
|
||||
* Java project finder. Able to find a java project for a file or document
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*/
|
||||
public interface JavaProjectManager {
|
||||
public interface JavaProjectFinder {
|
||||
|
||||
interface Listener {
|
||||
void created(IJavaProject project);
|
||||
void changed(IJavaProject project);
|
||||
void deleted(IJavaProject project);
|
||||
}
|
||||
|
||||
void setFileObserver(FileObserver fileObserver);
|
||||
IJavaProject find(IDocument doc);
|
||||
IJavaProject find(File file);
|
||||
boolean isProjectRoot(File file);
|
||||
|
||||
void addListener(Listener listener);
|
||||
void removeListener( Listener listener);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
|
||||
/**
|
||||
* Projects Observer. Able to add/remove project listeners which are notified on project changes
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public interface ProjectObserver {
|
||||
|
||||
interface Listener {
|
||||
void created(IJavaProject project);
|
||||
void changed(IJavaProject project);
|
||||
void deleted(IJavaProject project);
|
||||
}
|
||||
|
||||
void addListener(Listener listener);
|
||||
void removeListener(Listener listener);
|
||||
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, 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:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.java.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.AbstractJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.CompositeJavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectManager.Listener;
|
||||
import org.springframework.ide.vscode.commons.util.BasicFileObserver;
|
||||
import org.springframework.ide.vscode.commons.util.FileObserver.FileListener;
|
||||
import org.springframework.ide.vscode.commons.util.FileUtils;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
/**
|
||||
* Tests for {@link CompositeJavaProjectManager}
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class CompositeJavaProjectManagerTest {
|
||||
|
||||
private AbstractJavaProjectManager createProjectManagerForFile(String fileName) {
|
||||
return new AbstractJavaProjectManager() {
|
||||
|
||||
private Cache<File, IJavaProject> cache = CacheBuilder.newBuilder().build();
|
||||
|
||||
@Override
|
||||
public boolean isProjectRoot(File file) {
|
||||
return FileUtils.findFile(file, fileName, false) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavaProject find(File file) {
|
||||
if (fileName.equals(file.toPath().getFileName().toString())) {
|
||||
try {
|
||||
return cache.get(file, () -> {
|
||||
return new IJavaProject() {
|
||||
@Override
|
||||
public IClasspath getClasspath() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
});
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FileListener createFileListener() {
|
||||
return new FileListener() {
|
||||
|
||||
private File getFileFromUri(String uri) {
|
||||
return Paths.get(URI.create(uri)).toFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleted(String uri) {
|
||||
File file = getFileFromUri(uri);
|
||||
IJavaProject project = cache.getIfPresent(file);
|
||||
if (project != null) {
|
||||
cache.invalidate(file);
|
||||
notifyProjectDeleted(project);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created(String uri) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(String uri) {
|
||||
File file = getFileFromUri(uri);
|
||||
IJavaProject project = cache.getIfPresent(file);
|
||||
if (project != null) {
|
||||
notifyProjectChanged(project);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(String uri) {
|
||||
return fileName.equals(Paths.get(URI.create(uri)).getFileName().toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListeners() throws Exception {
|
||||
AbstractJavaProjectManager manager1 = createProjectManagerForFile("test-1");
|
||||
AbstractJavaProjectManager manager2 = createProjectManagerForFile("test-2");
|
||||
CompositeJavaProjectManager compositeManager = new CompositeJavaProjectManager(new JavaProjectManager[] {
|
||||
manager1,
|
||||
manager2
|
||||
});
|
||||
BasicFileObserver fileObserver = new BasicFileObserver();
|
||||
compositeManager.setFileObserver(fileObserver);
|
||||
|
||||
Path containerPath = Paths.get(CompositeJavaProjectManagerTest.class.getResource("/").toURI());
|
||||
|
||||
File projectFile1 = containerPath.resolve("test-1").toFile();
|
||||
IJavaProject p1 = compositeManager.find(projectFile1);
|
||||
assertNotNull(p1);
|
||||
|
||||
File projectFile2 = containerPath.resolve("test-2").toFile();
|
||||
IJavaProject p2 = compositeManager.find(projectFile2);
|
||||
assertNotNull(p2);
|
||||
|
||||
IJavaProject[] projectChanged = new IJavaProject[] { null };
|
||||
IJavaProject[] projectDeleted = new IJavaProject[] { null };
|
||||
|
||||
compositeManager.addListener(new Listener() {
|
||||
|
||||
@Override
|
||||
public void created(IJavaProject project) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(IJavaProject project) {
|
||||
projectChanged[0] = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleted(IJavaProject project) {
|
||||
projectDeleted[0] = project;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
fileObserver.notifyFileChanged(projectFile1.toURI().toString());
|
||||
assertEquals(p1, projectChanged[0]);
|
||||
assertNull(projectDeleted[0]);
|
||||
projectChanged[0] = projectDeleted[0] = null;
|
||||
|
||||
fileObserver.notifyFileDeleted(projectFile1.toURI().toString());
|
||||
assertNull(projectChanged[0]);
|
||||
assertEquals(p1, projectDeleted[0]);
|
||||
projectChanged[0] = projectDeleted[0] = null;
|
||||
|
||||
fileObserver.notifyFileChanged(projectFile2.toURI().toString());
|
||||
assertEquals(p2, projectChanged[0]);
|
||||
assertNull(projectDeleted[0]);
|
||||
projectChanged[0] = projectDeleted[0] = null;
|
||||
|
||||
fileObserver.notifyFileDeleted(projectFile2.toURI().toString());
|
||||
assertNull(projectChanged[0]);
|
||||
assertEquals(p2, projectDeleted[0]);
|
||||
projectChanged[0] = projectDeleted[0] = null;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user