From 5e7d7f9e245b5b05019619c02d3fcb755bb8de17 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Tue, 21 Jun 2016 06:09:56 +0300 Subject: [PATCH 01/34] Integrated the file-watcher project into the flux repo Signed-off-by: Fjodor Vershinin --- org.eclipse.flux.headless.releng/pom.xml | 2 + org.eclipse.flux.watcher/META-INF/MANIFEST.MF | 18 ++ org.eclipse.flux.watcher/build.properties | 4 + org.eclipse.flux.watcher/pom.xml | 26 ++ .../flux/watcher/core/Credentials.java | 75 +++++ .../flux/watcher/core/FluxConnection.java | 178 +++++++++++ .../flux/watcher/core/FluxMessage.java | 118 ++++++++ .../flux/watcher/core/FluxMessageBus.java | 226 ++++++++++++++ .../flux/watcher/core/FluxMessageHandler.java | 31 ++ .../flux/watcher/core/FluxMessageType.java | 78 +++++ .../flux/watcher/core/FluxMessageTypes.java | 36 +++ .../eclipse/flux/watcher/core/Repository.java | 198 ++++++++++++ .../flux/watcher/core/RepositoryEvent.java | 74 +++++ .../flux/watcher/core/RepositoryEventBus.java | 119 ++++++++ .../watcher/core/RepositoryEventType.java | 22 ++ .../watcher/core/RepositoryEventTypes.java | 29 ++ .../flux/watcher/core/RepositoryListener.java | 28 ++ .../flux/watcher/core/RepositoryModule.java | 45 +++ .../eclipse/flux/watcher/core/Resource.java | 164 ++++++++++ .../flux/watcher/core/internal/.gitignore | 54 ++++ .../internal/GetProjectRequestHandler.java | 73 +++++ .../internal/GetProjectResponseHandler.java | 102 +++++++ .../internal/GetResourceRequestHandler.java | 79 +++++ .../internal/GetResourceResponseHandler.java | 85 ++++++ .../ProjectResourceCreatedListener.java | 69 +++++ .../ProjectResourceDeletedListener.java | 64 ++++ .../ProjectResourceModifiedListener.java | 70 +++++ .../core/internal/ResourceChangedHandler.java | 67 +++++ .../core/internal/ResourceCreatedHandler.java | 71 +++++ .../core/internal/ResourceDeletedHandler.java | 54 ++++ .../flux/watcher/core/spi/Project.java | 103 +++++++ .../flux/watcher/core/spi/ProjectFactory.java | 33 ++ .../watcher/core/utils/ResourceHelper.java | 56 ++++ .../eclipse/flux/watcher/fs/JDKProject.java | 254 ++++++++++++++++ .../flux/watcher/fs/JDKProjectFactory.java | 63 ++++ .../flux/watcher/fs/JDKProjectModule.java | 37 +++ .../watcher/fs/JDKProjectWatchService.java | 281 ++++++++++++++++++ pom.xml | 10 +- 38 files changed, 3091 insertions(+), 5 deletions(-) create mode 100644 org.eclipse.flux.watcher/META-INF/MANIFEST.MF create mode 100644 org.eclipse.flux.watcher/build.properties create mode 100644 org.eclipse.flux.watcher/pom.xml create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Credentials.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxConnection.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessage.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageBus.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageHandler.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageType.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageTypes.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Repository.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEvent.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventBus.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventType.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventTypes.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryListener.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryModule.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Resource.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/.gitignore create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/Project.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/ProjectFactory.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/utils/ResourceHelper.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProject.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectFactory.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectModule.java create mode 100644 org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java diff --git a/org.eclipse.flux.headless.releng/pom.xml b/org.eclipse.flux.headless.releng/pom.xml index 979c0ea..5434275 100644 --- a/org.eclipse.flux.headless.releng/pom.xml +++ b/org.eclipse.flux.headless.releng/pom.xml @@ -30,6 +30,8 @@ ../org.eclipse.flux.parent.java ../org.eclipse.flux.client.java + + ../org.eclipse.flux.watcher diff --git a/org.eclipse.flux.watcher/META-INF/MANIFEST.MF b/org.eclipse.flux.watcher/META-INF/MANIFEST.MF new file mode 100644 index 0000000..60611a3 --- /dev/null +++ b/org.eclipse.flux.watcher/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Watch +Bundle-SymbolicName: org.eclipse.flux.watcher +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Require-Bundle: org.eclipse.flux.client.java.osgi;bundle-version="1.0.0" +Import-Package: com.google.common.base, + com.google.common.collect;version="15.0.0", + com.google.inject;version="1.3.0", + com.google.inject.binder;version="1.3.0", + com.google.inject.multibindings;version="1.3.0", + javax.inject;version="1.0.0" +Export-Package: org.eclipse.flux.watcher.core, + org.eclipse.flux.watcher.core.internal, + org.eclipse.flux.watcher.core.spi, + org.eclipse.flux.watcher.core.utils, + org.eclipse.flux.watcher.fs diff --git a/org.eclipse.flux.watcher/build.properties b/org.eclipse.flux.watcher/build.properties new file mode 100644 index 0000000..34d2e4d --- /dev/null +++ b/org.eclipse.flux.watcher/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/org.eclipse.flux.watcher/pom.xml b/org.eclipse.flux.watcher/pom.xml new file mode 100644 index 0000000..20a1a40 --- /dev/null +++ b/org.eclipse.flux.watcher/pom.xml @@ -0,0 +1,26 @@ + + 4.0.0 + org.eclipse.flux.watcher + eclipse-plugin + + 0.1.0-SNAPSHOT + org.eclipse.flux.group + org.eclipse.flux.parent + ../org.eclipse.flux.parent/pom.xml + + + src + + + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + + 1.0.0.qualifier + \ No newline at end of file diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Credentials.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Credentials.java new file mode 100644 index 0000000..c0760d7 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Credentials.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Credentials used to connect to a Flux server. + * + * @author Kevin Pollet + */ +public class Credentials { + public static final Credentials DEFAULT_USER_CREDENTIALS; + private static final String DEFAULT_USER_USERNAME = "defaultuser"; + + static { + DEFAULT_USER_CREDENTIALS = new Credentials(DEFAULT_USER_USERNAME); + } + + private final String username; + private final String token; + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.core.Credentials}. + * + * @param username + * the username. + * @throws java.lang.NullPointerException + * if {@code username} parameter is {@code null}. + */ + public Credentials(String username) { + this(username, null); + } + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.core.Credentials}. + * + * @param username + * the username. + * @param token + * the user token. + * @throws java.lang.NullPointerException + * if {@code username} parameter is {@code null}. + */ + public Credentials(String username, String token) { + this.username = checkNotNull(username); + this.token = token; + } + + /** + * Returns the username. + * + * @return the username never {@code null}. + */ + public String username() { + return username; + } + + /** + * Returns the user token. + * + * @return the user token or {@code null} if none. + */ + public String token() { + return token; + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxConnection.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxConnection.java new file mode 100644 index 0000000..d3b2a48 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxConnection.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import io.socket.IOAcknowledge; +import io.socket.IOCallback; +import io.socket.SocketIO; +import io.socket.SocketIOException; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.net.URL; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CALLBACK_ID; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CHANNEL; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CONNECTED_TO_CHANNEL; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.USERNAME; +import static org.eclipse.flux.watcher.core.FluxMessageType.CONNECT_TO_CHANNEL; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_PROJECT_REQUEST; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_REQUEST; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Represents a connection to a Flux remote. + * + * @author Kevin Pollet + */ +public class FluxConnection { + private static final String FLUX_USER_NAME_HEADER_KEY = "X-flux-user-name"; + private static final String FLUX_USER_TOKEN_HEADER_KEY = "X-flux-user-token"; + + private final SocketIO socket; + private final FluxMessageBus messageBus; + private final Credentials credentials; + + /** + * Constructs an instance of {@code FluxConnection}. + * + * @param serverURL + * the server {@link java.net.URL} to connect to. + * @param credentials + * the {@link Credentials} used to connect. + * @param messageBus + * the {@link com.codenvy.flux.watcher.core.FluxMessageBus} instance. + * @throws java.lang.NullPointerException + * if {@code serverURL}, {@code credentials} or {@code messageBus} parameter is {@code null}. + */ + FluxConnection(URL serverURL, Credentials credentials, FluxMessageBus messageBus) { + this.messageBus = checkNotNull(messageBus); + this.credentials = checkNotNull(credentials); + + this.socket = new SocketIO(checkNotNull(serverURL)); + if (credentials.token() != null) { + this.socket.addHeader(FLUX_USER_NAME_HEADER_KEY, credentials.username()); + this.socket.addHeader(FLUX_USER_TOKEN_HEADER_KEY, credentials.token()); + } + } + + /** + * Open the connection. + * + * @return the opened {@link com.codenvy.flux.watcher.core.FluxConnection} instance. + */ + FluxConnection open() { + if (!socket.isConnected()) { + socket.connect(new IOCallback() { + @Override + public void onDisconnect() { + + } + + @Override + public void onConnect() { + try { + + final JSONObject content = new JSONObject().put(CHANNEL.value(), credentials.username()); + socket.emit(CONNECT_TO_CHANNEL.value(), new IOAcknowledge() { + @Override + public void ack(Object... objects) { + if (objects.length == 1 && objects[0] instanceof JSONObject) { + final JSONObject ack = (JSONObject)objects[0]; + try { + + if (ack.has(CONNECTED_TO_CHANNEL.value()) && ack.getBoolean(CONNECTED_TO_CHANNEL.value())) { + return; + } + + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + socket.disconnect(); + } + }, content); + + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + + @Override + public void onMessage(String s, IOAcknowledge ioAcknowledge) { + + } + + @Override + public void onMessage(JSONObject jsonObject, IOAcknowledge ioAcknowledge) { + + } + + //TODO in flux implementation the username is checked, what to do? + @Override + public void on(String name, IOAcknowledge ioAcknowledge, Object... objects) { + final FluxMessageType messageType = FluxMessageType.fromType(name); + if (messageType != null && objects.length > 0 && objects[0] instanceof JSONObject) { + final FluxMessage message = new FluxMessage(FluxConnection.this, messageType, (JSONObject)objects[0]); + messageBus.messageReceived(message); + } + } + + @Override + public void onError(SocketIOException e) { + throw new RuntimeException(e); + } + }); + } + return this; + } + + /** + * Close the connection. + */ + void close() { + if (socket.isConnected()) { + socket.disconnect(); + } + } + + /** + * Sends a {@link FluxMessage} on this connection + * + * @param message + * the {@link FluxMessage} instance to send. + * @throws java.lang.NullPointerException + * if {@code message} parameter is {@code null}. + */ + public void sendMessage(FluxMessage message) { + checkNotNull(message); + + final JSONObject content = message.content(); + + try { + if (!content.has(USERNAME.value())) { + content.put(USERNAME.value(), credentials.username()); + } + + if (!content.has(CALLBACK_ID.value())) { + if (message.type() == GET_RESOURCE_REQUEST || message.type() == GET_PROJECT_REQUEST) { + content.put(CALLBACK_ID.value(), messageBus.id()); + } + } + + } catch (JSONException e) { + throw new RuntimeException(e); + } + + socket.emit(message.type().value(), message.content()); + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessage.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessage.java new file mode 100644 index 0000000..42646eb --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessage.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import org.json.JSONObject; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Class representing a Flux message. + * + * @author Kevin Pollet + */ +public class FluxMessage { + private final FluxConnection source; + private final FluxMessageType type; + private final JSONObject content; + + /** + * Constructs an instance of {@link FluxMessage}. + * + * @param type + * the {@link FluxMessageType}. + * @param content + * the message {@link org.json.JSONObject} content. + * @throws java.lang.NullPointerException + * if {@code type} or {@code content} parameter is {@code null}. + */ + public FluxMessage(FluxMessageType type, JSONObject content) { + this(null, type, content); + } + + /** + * Constructs an instance of {@link FluxMessage}. + * + * @param source + * the {@code FluxConnection} where the {@link FluxMessage} comes from. + * @param type + * the {@link FluxMessageType}. + * @param content + * the message {@link org.json.JSONObject} content. + * @throws java.lang.NullPointerException + * if {@code type} or {@code content} parameter is {@code null}. + */ + public FluxMessage(FluxConnection source, FluxMessageType type, JSONObject content) { + this.source = source; + this.type = checkNotNull(type); + this.content = checkNotNull(content); + } + + /** + * Returns the {@code FluxConnection} where the {@link FluxMessage} comes from. + * + * @return the {@code FluxConnection} where the {@link FluxMessage} comes from or {@code null} if none. + */ + public FluxConnection source() { + return source; + } + + /** + * Returns the {@link FluxMessageType}. + * + * @return the {@link FluxMessageType}, never {@code null}. + */ + public FluxMessageType type() { + return type; + } + + /** + * Returns the {@link FluxMessage} content. + * + * @return the {@link FluxMessage} content, never {@code null}. + */ + public JSONObject content() { + return content; + } + + /** + * Fields used in {@link org.json.JSONObject} of Flux messages. + * + * @author Kevin Pollet + */ + public enum Fields { + CALLBACK_ID("callback_id"), + CHANNEL("channel"), + CONNECTED_TO_CHANNEL("connectedToChannel"), + CONTENT("content"), + DELETED("deleted"), + FILES("files"), + HASH("hash"), + INCLUDE_DELETED("includeDeleted"), + PATH("path"), + PROJECT("project"), + REQUEST_SENDER_ID("requestSenderID"), + RESOURCE("resource"), + TIMESTAMP("timestamp"), + TYPE("type"), + USERNAME("username"); + + private final String value; + + Fields(String value) { + this.value = value; + } + + public String value() { + return value; + } + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageBus.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageBus.java new file mode 100644 index 0000000..3bdf051 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageBus.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CALLBACK_ID; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_PROJECT_RESPONSE; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_RESPONSE; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Predicates.notNull; +import static java.util.Collections.emptySet; + +import java.net.URL; +import java.util.Arrays; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArraySet; + +import javax.inject.Inject; +import javax.inject.Provider; +import javax.inject.Singleton; + +import org.json.JSONObject; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableSet; + +/** + * Message bus connected to Flux instance. + * + * @author Kevin Pollet + */ +@Singleton +public class FluxMessageBus { + private final int id; + private final ConcurrentMap connections; + private final Provider repository; + private final Set messageHandlers; + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.core.FluxMessageBus}. + * + * @param messageHandlers + * the {@link FluxMessageHandler} to register. + * @param repository + * the {@link Repository} provider instance. + * @throws java.lang.NullPointerException + * if {@code messageHandlers} is {@code null}. + */ + @Inject + FluxMessageBus(Set messageHandlers, Provider repository) { + id = Long.valueOf(UUID.randomUUID().getMostSignificantBits()).intValue(); + this.repository = repository; + this.messageHandlers = new CopyOnWriteArraySet<>(checkNotNull(messageHandlers)); + connections = new ConcurrentHashMap<>(); + } + + /** + * Returns the {@link com.codenvy.flux.watcher.core.FluxMessageBus} unique id. + * + * @return the {@link com.codenvy.flux.watcher.core.FluxMessageBus} unique id. + */ + public int id() { + return id; + } + + /** + * Open a connection to the given server {@link java.net.URL}. + * + * @param serverURL + * the server {@link java.net.URL} to connect to. + * @param credentials + * the {@link Credentials} to use for the connection. + * @return the opened {@link com.codenvy.flux.watcher.core.FluxConnection} or the existing {@link + * com.codenvy.flux.watcher.core.FluxConnection} if already opened. + * @throws java.lang.NullPointerException + * if {@code serverURL} or {@code credentials} parameter is {@code null}. + */ + public FluxConnection connect(URL serverURL, Credentials credentials) { + checkNotNull(serverURL); + checkNotNull(credentials); + + FluxConnection connection = connections.get(serverURL); + if (connection == null) { + FluxConnection newConnection = new FluxConnection(serverURL, credentials, this); + connection = connections.putIfAbsent(serverURL, newConnection); + if (connection == null) { + connection = newConnection.open(); + } + } + + return connection; + } + + /** + * Close the connection to the given server {@link java.net.URL}. + * + * @param serverURL + * the server {@link java.net.URL} to disconnect from. + * @throws java.lang.NullPointerException + * if {@code serverURL} parameter is {@code null}. + */ + public void disconnect(URL serverURL) { + final FluxConnection connection = connections.remove(checkNotNull(serverURL)); + if (connection != null) { + connection.close(); + } + } + + /** + * Adds a {@link FluxMessageHandler}. + * + * @param handler + * the {@link FluxMessageHandler} to add. + * @return {@code true} if the {@code handler} is not already added, {@code false} otherwise. + * @throws java.lang.NullPointerException + * if {@code handler} parameter is {@code null}. + */ + public boolean addMessageHandler(FluxMessageHandler handler) { + return messageHandlers.add(checkNotNull(handler)); + } + + /** + * Removes a {@link FluxMessageHandler}. + * + * @param handler + * the {@link FluxMessageHandler} to remove. + * @return {@code true} if the {@code handler} was already added, {@code false} otherwise. + * @throws java.lang.NullPointerException + * if {@code handler} parameter is {@code null}. + */ + public boolean removeMessageHandler(FluxMessageHandler handler) { + return messageHandlers.remove(checkNotNull(handler)); + } + + /** + * Broadcast messages to all opened {@link com.codenvy.flux.watcher.core.FluxConnection}. + * + * @param messages + * the {@link FluxMessage} to broadcast. + * @throws java.lang.NullPointerException + * if {@code messages} parameter is {@code null}. + */ + public void sendMessages(FluxMessage... messages) { + checkNotNull(messages); + + for (FluxMessage oneMessage : messages) { + checkNotNull(oneMessage); + + for (FluxConnection oneConnection : connections.values()) { + oneConnection.sendMessage(oneMessage); + } + } + } + + /** + * Fires the given {@link FluxMessage} to all {@link FluxMessageHandler} + * registered. + * + * @param message + * the message. + * @throws java.lang.NullPointerException + * if {@code message} parameter is {@code null}. + */ + public void messageReceived(FluxMessage message) { + checkNotNull(message); + + if (message.type() == GET_RESOURCE_RESPONSE || message.type() == GET_PROJECT_RESPONSE) { + final JSONObject content = message.content(); + if (content.optInt(CALLBACK_ID.value()) != id) { + return; + } + } + + final Set messageHandlers = getMessageHandlersFor(message.type().value()); + for (FluxMessageHandler oneMessageHandler : messageHandlers) { + try { + + oneMessageHandler.onMessage(message, repository.get()); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + private Set getMessageHandlersFor(final String messageType) { + return ImmutableSet.copyOf(FluentIterable.from(messageHandlers) + .filter(notNull()) + .filter(new Predicate() { + @Override + public boolean apply(FluxMessageHandler messageHandler) { + final Set supportedTypes = getMessageTypesFor(messageHandler); + return supportedTypes.contains(messageType); + } + })); + } + + private Set getMessageTypesFor(FluxMessageHandler messageHandler) { + final FluxMessageTypes types = messageHandler.getClass().getAnnotation(FluxMessageTypes.class); + if (types == null) { + return emptySet(); + } + + return ImmutableSet.copyOf(FluentIterable.from(Arrays.asList(types.value())) + .filter(Predicates.notNull()) + .transform(new Function() { + @Override + public String apply(FluxMessageType messageType) { + return messageType.value(); + } + })); + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageHandler.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageHandler.java new file mode 100644 index 0000000..e7414b8 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageHandler.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +/** + * Interface implemented to be advise when a {@link com.codenvy.flux.watcher.core.FluxMessage} is received by a {@link + * com.codenvy.flux.watcher.core.FluxConnection}. + * + * @author Kevin Pollet + */ +public interface FluxMessageHandler { + /** + * Method called when a {@link com.codenvy.flux.watcher.core.FluxMessage} is received. + * + * @param message + * the {@link com.codenvy.flux.watcher.core.FluxMessage} instance, never {@code null}. + * @param repository + * the {@link com.codenvy.flux.watcher.core.Repository} instance, never {@code null}. + * @throws java.lang.Exception + * if something goes wrong. + */ + void onMessage(FluxMessage message, Repository repository) throws Exception; +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageType.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageType.java new file mode 100644 index 0000000..7a31f3e --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageType.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * The types of {@link com.codenvy.flux.watcher.core.FluxMessage}. + * + * @author Kevin Pollet + */ +public enum FluxMessageType { + CONNECT_TO_CHANNEL("connectToChannel"), + GET_PROJECT_REQUEST("getProjectRequest"), + GET_PROJECT_RESPONSE("getProjectResponse"), + GET_RESOURCE_REQUEST("getResourceRequest"), + GET_RESOURCE_RESPONSE("getResourceResponse"), + PROJECT_CONNECTED("projectConnected"), + PROJECT_DISCONNECTED("projectDisconnected"), + RESOURCE_CHANGED("resourceChanged"), + RESOURCE_CREATED("resourceCreated"), + RESOURCE_DELETED("resourceDeleted"), + RESOURCE_STORED("resourceStored"); + + private final String value; + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.core.FluxMessageType}. + * + * @param value + * the {@link com.codenvy.flux.watcher.core.FluxMessageType} value. + * @throws java.lang.NullPointerException + * if {@code value} parameter is {@code null}. + */ + FluxMessageType(String value) { + this.value = checkNotNull(value); + } + + /** + * Returns the {@link com.codenvy.flux.watcher.core.FluxMessageType} corresponding to the given type. + * + * @param type + * the {@link com.codenvy.flux.watcher.core.FluxMessageType} type. + * @return the {@link com.codenvy.flux.watcher.core.FluxMessageType} corresponding to the given type or {@code null} if none. + * @throws java.lang.NullPointerException + * if {@code type} parameter is {@code null}. + * @throws java.lang.IllegalArgumentException + * if no {@link com.codenvy.flux.watcher.core.FluxMessageType} exists for the given type. + */ + public static FluxMessageType fromType(String type) { + checkNotNull(type); + + final FluxMessageType[] messageTypes = FluxMessageType.values(); + for (FluxMessageType oneMessageType : messageTypes) { + if (oneMessageType.value.equals(type)) { + return oneMessageType; + } + } + throw new IllegalArgumentException("No enum found for type '" + type + "'"); + } + + /** + * Returns the {@link com.codenvy.flux.watcher.core.FluxMessageType} value. + * + * @return the {@link com.codenvy.flux.watcher.core.FluxMessageType} value, never {@code null}. + */ + public String value() { + return value; + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageTypes.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageTypes.java new file mode 100644 index 0000000..bf79b86 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageTypes.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Annotation used to indicate which {@link com.codenvy.flux.watcher.core.FluxMessageType} the {@link + * com.codenvy.flux.watcher.core.FluxMessageHandler} can handle. + * + * @author Kevin Pollet + */ +@Target(TYPE) +@Retention(RUNTIME) +public @interface FluxMessageTypes { + /** + * Returns the {@link com.codenvy.flux.watcher.core.FluxMessageType} the {@link + * com.codenvy.flux.watcher.core.FluxMessageHandler} can handle. + * + * @return the {@link com.codenvy.flux.watcher.core.FluxMessageType} the {@link + * com.codenvy.flux.watcher.core.FluxMessageHandler} can handle. + */ + FluxMessageType[] value(); +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Repository.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Repository.java new file mode 100644 index 0000000..22b522f --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Repository.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import org.eclipse.flux.watcher.core.spi.Project; +import org.eclipse.flux.watcher.core.spi.ProjectFactory; +import com.google.common.base.Predicate; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableSet; +import org.json.JSONException; +import org.json.JSONObject; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.net.URL; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.INCLUDE_DELETED; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; +import static org.eclipse.flux.watcher.core.FluxMessageType.*; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Predicates.notNull; + +/** + * Represents a repository with Flux connectivity capabilities. + * + * @author Kevin Pollet + */ +@Singleton +public class Repository { + private final Set projects; + private final FluxMessageBus messageBus; + private final RepositoryEventBus repositoryEventBus; + private final ProjectFactory projectFactory; + + /** + * Constructs an instance of {@link Repository}. + * + * @param messageBus + * the {@link com.codenvy.flux.watcher.core.FluxMessageBus} instance. + * @param projectFactory + * the {@link com.codenvy.flux.watcher.core.spi.ProjectFactory} instance. + * @param repositoryEventBus + * the {@link com.codenvy.flux.watcher.core.RepositoryEventBus} instance. + * @throws java.lang.NullPointerException + * if {@code messageBus}, {@code projectFactory} or {@code repositoryEventBus} parameter is {@code null}. + */ + @Inject + Repository(FluxMessageBus messageBus, ProjectFactory projectFactory, RepositoryEventBus repositoryEventBus) { + this.repositoryEventBus = checkNotNull(repositoryEventBus); + this.messageBus = checkNotNull(messageBus); + this.projectFactory = checkNotNull(projectFactory); + this.projects = new CopyOnWriteArraySet<>(); + } + + /** + * Connects this {@link Repository} to a Flux remote. + * + * @param remoteURL + * the remote {@link java.net.URL}. + * @param credentials + * the {@link com.codenvy.flux.watcher.core.Credentials} used to connect. + * @return the opened {@link com.codenvy.flux.watcher.core.FluxConnection}. + * @throws java.lang.NullPointerException + * if {@code remoteURL} or {@code credentials} parameter is {@code null}. + */ + public FluxConnection addRemote(URL remoteURL, Credentials credentials) { + return messageBus.connect(checkNotNull(remoteURL), checkNotNull(credentials)); + } + + /** + * Disconnects this {@link Repository} from a Flux remote. + * + * @param remoteURL + * the server {@link java.net.URL}. + * @throws java.lang.NullPointerException + * if {@code remoteURL} parameter is {@code null}. + */ + public void removeRemote(URL remoteURL) { + messageBus.disconnect(checkNotNull(remoteURL)); + } + + /** + * Add a project to the repository. + * + * @param projectId + * the project id. + * @param projectPath + * the absolute project path. + * @return the added {@link com.codenvy.flux.watcher.core.spi.Project} instance, never {@code null}. + * @throws java.lang.NullPointerException + * if {@code projectId} or {@code projectPath} parameter is {@code null}. + * @throws java.lang.IllegalArgumentException + * if the given {@code projectPath} is not a directory, not absolute or doesn't exist. + */ + public Project addProject(String projectId, String projectPath) { + checkNotNull(projectId); + checkNotNull(projectPath); + + Project project = getProject(projectId); + if (project == null) { + project = projectFactory.newProject(projectId, projectPath); + project.setSynchronized(true); + projects.add(project); + + try { + + JSONObject content = new JSONObject().put(PROJECT.value(), projectId); + messageBus.sendMessages(new FluxMessage(PROJECT_CONNECTED, content)); + + content = new JSONObject().put(PROJECT.value(), projectId).put(INCLUDE_DELETED.value(), true); + messageBus.sendMessages(new FluxMessage(GET_PROJECT_REQUEST, content)); + + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + return project; + } + + /** + * Remove a project from the repository. + * + * @param projectId + * the project id. + * @return the removed {@link com.codenvy.flux.watcher.core.spi.Project} instance or {@code null} if none. + */ + public Project removeProject(String projectId) { + final Project project = getProject(projectId); + if (project != null) { + projects.remove(project); + project.setSynchronized(false); + + try { + + final JSONObject content = new JSONObject().put(PROJECT.value(), projectId); + messageBus.sendMessages(new FluxMessage(PROJECT_DISCONNECTED, content)); + + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + return project; + } + + /** + * Returns the {@link com.codenvy.flux.watcher.core.spi.Project} with the given id. + * + * @return the {@link com.codenvy.flux.watcher.core.spi.Project} or {@code null} if none. + */ + public Project getProject(final String projectId) { + return FluentIterable.from(projects) + .firstMatch(new Predicate() { + @Override + public boolean apply(Project project) { + return Objects.equals(projectId, project.id()); + } + }) + .orNull(); + } + + /** + * Returns all synchronized {@link com.codenvy.flux.watcher.core.spi.Project}. + * + * @return a {@link java.util.Set} of all synchronized {@link com.codenvy.flux.watcher.core.spi.Project}. + */ + public Set getSynchronizedProjects() { + return ImmutableSet.copyOf(FluentIterable.from(projects) + .filter(notNull()) + .filter(new Predicate() { + @Override + public boolean apply(Project project) { + return project.getSynchronized(); + } + })); + } + + /** + * Returns the {@link com.codenvy.flux.watcher.core.RepositoryEventBus}. + * + * @return the {@link com.codenvy.flux.watcher.core.RepositoryEventBus}, never {@code null}. + */ + public RepositoryEventBus repositoryEventBus() { + return repositoryEventBus; + } + + +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEvent.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEvent.java new file mode 100644 index 0000000..c58bebf --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEvent.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import org.eclipse.flux.watcher.core.spi.Project; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Event sent when a modification is done in the repository. + * + * @author Kevin Pollet + * @see com.codenvy.flux.watcher.core.RepositoryEventType + * @see com.codenvy.flux.watcher.core.Resource + * @see com.codenvy.flux.watcher.core.spi.Project + */ +public class RepositoryEvent { + private final RepositoryEventType type; + private final Project project; + private final Resource resource; + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.core.RepositoryEvent}. + * + * @param type + * the {@link com.codenvy.flux.watcher.core.RepositoryEventType}. + * @param resource + * the {@link com.codenvy.flux.watcher.core.Resource} source of the event. + * @param project + * the {@link com.codenvy.flux.watcher.core.spi.Project} source of the event. + * @throws java.lang.NullPointerException + * if {@code type}, {@code resource} or {@code project} parameter is {@code null}. + */ + public RepositoryEvent(RepositoryEventType type, Resource resource, Project project) { + this.project = checkNotNull(project); + this.type = checkNotNull(type); + this.resource = checkNotNull(resource); + } + + /** + * Returns the {@link com.codenvy.flux.watcher.core.RepositoryEventType} of this event. + * + * @return the {@link com.codenvy.flux.watcher.core.RepositoryEventType}, never {@code null}. + */ + public RepositoryEventType type() { + return type; + } + + /** + * Returns the {@link com.codenvy.flux.watcher.core.Resource} source of this event. + * + * @return the {@link com.codenvy.flux.watcher.core.Resource}, never {@code null}. + */ + public Resource resource() { + return resource; + } + + /** + * Returns the {@link com.codenvy.flux.watcher.core.spi.Project} source of this event. + * + * @return the {@link com.codenvy.flux.watcher.core.spi.Project} source of this event, never {@code null}. + */ + public Project project() { + return project; + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventBus.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventBus.java new file mode 100644 index 0000000..ee08c42 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventBus.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Predicates.notNull; +import static java.util.Arrays.asList; + +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +import javax.inject.Inject; +import javax.inject.Provider; +import javax.inject.Singleton; + +import com.google.common.base.Predicate; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableSet; + +/** + * Event bus to listen and fire {@link com.codenvy.flux.watcher.core.Repository} events. + * + * @author Kevin Pollet + * @see com.codenvy.flux.watcher.core.RepositoryEvent + */ +@Singleton +public class RepositoryEventBus { + private final Provider repository; + private final Set repositoryListeners; + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.core.RepositoryEventBus}. + * + * @param repositoryListeners + * the repository listeners to register. + * @param repository + * the {@link com.codenvy.flux.watcher.core.Repository}. + * @throws java.lang.NullPointerException + * if {@code repositoryListeners} or {@code repository} parameter is {@code null}. + */ + @Inject + public RepositoryEventBus(Set repositoryListeners, Provider repository) { + this.repository = checkNotNull(repository); + this.repositoryListeners = new CopyOnWriteArraySet<>(checkNotNull(repositoryListeners)); + } + + /** + * Adds a {@link com.codenvy.flux.watcher.core.RepositoryListener}. + * + * @param listener + * the {@link com.codenvy.flux.watcher.core.RepositoryListener} to add. + * @return {@code true} if the listener was not already added, {@code false} otherwise. + * @throws java.lang.NullPointerException + * if {@code listener} parameter is {@code null}. + */ + public boolean addRepositoryListener(RepositoryListener listener) { + return repositoryListeners.add(checkNotNull(listener)); + } + + /** + * Removes a {@link com.codenvy.flux.watcher.core.RepositoryListener}. + * + * @param listener + * the {@link com.codenvy.flux.watcher.core.RepositoryListener} to remove. + * @return {@code true} if the listener has been removed, {@code false} otherwise. + * @throws java.lang.NullPointerException + * if {@code listener} parameter is {@code null}. + */ + public boolean removeRepositoryListener(RepositoryListener listener) { + return repositoryListeners.remove(checkNotNull(listener)); + } + + /** + * Fires a {@link com.codenvy.flux.watcher.core.RepositoryEvent} to all {@link com.codenvy.flux.watcher.core.RepositoryListener} + * registered. + * + * @param event + * the {@link com.codenvy.flux.watcher.core.RepositoryEvent} to fire. + * @throws java.lang.NullPointerException + * if {@code event} parameter is {@code null}. + * @throws java.lang.IllegalStateException + * if the {@link com.codenvy.flux.watcher.core.spi.Project} concerned by the event is not in the {@link + * com.codenvy.flux.watcher.core.Repository}. + */ + public void fireRepositoryEvent(final RepositoryEvent event) { + checkNotNull(event); + checkState(repository.get().getProject(event.project().id()) != null); + + final Set filteredRepositoryListeners = ImmutableSet.copyOf(FluentIterable + .from(repositoryListeners) + .filter(notNull()) + .filter(new Predicate() { + @Override + public boolean apply(RepositoryListener listener) { + final RepositoryEventTypes repositoryEventTypes = listener.getClass().getAnnotation(RepositoryEventTypes.class); + return asList(repositoryEventTypes.value()).contains(event.type()); + } + }));; + + for (RepositoryListener oneRepositoryListener : filteredRepositoryListeners) { + try { + + oneRepositoryListener.onEvent(event); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventType.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventType.java new file mode 100644 index 0000000..59a1246 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventType.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +/** + * Type of events sent by a {@link com.codenvy.flux.watcher.core.Repository}. + * + * @author Kevin Pollet + */ +public enum RepositoryEventType { + PROJECT_RESOURCE_CREATED, + PROJECT_RESOURCE_MODIFIED, + PROJECT_RESOURCE_DELETED +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventTypes.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventTypes.java new file mode 100644 index 0000000..a53fb4c --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventTypes.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Annotation used on a {@link com.codenvy.flux.watcher.core.RepositoryListener} to specify the {@link + * com.codenvy.flux.watcher.core.RepositoryEventType} it listens. + * + * @author Kevin Pollet + */ +@Target(TYPE) +@Retention(RUNTIME) +public @interface RepositoryEventTypes { + RepositoryEventType[] value(); +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryListener.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryListener.java new file mode 100644 index 0000000..605c45b --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryListener.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +/** + * Listener used to be notified for {@link com.codenvy.flux.watcher.core.Repository} events. + * + * @author Kevin Pollet + */ +public interface RepositoryListener { + /** + * Called when an events is fired by a {@link com.codenvy.flux.watcher.core.Repository}. + * + * @param event + * the {@link com.codenvy.flux.watcher.core.RepositoryEvent} instance, never {@code null}. + * @throws java.lang.Exception + * if something goes wrong. + */ + void onEvent(RepositoryEvent event) throws Exception; +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryModule.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryModule.java new file mode 100644 index 0000000..93453cb --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryModule.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import org.eclipse.flux.watcher.core.internal.*; +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; + +/** + * Guice bindings for {@link RepositoryModule}. + * + * @author Kevin Pollet + */ +public class RepositoryModule extends AbstractModule { + @Override + protected void configure() { + bind(Repository.class); + bind(FluxMessageBus.class); + bind(RepositoryEventBus.class); + + // message handler bindings + final Multibinder messageHandlers = Multibinder.newSetBinder(binder(), FluxMessageHandler.class); + messageHandlers.addBinding().to(GetResourceRequestHandler.class); + messageHandlers.addBinding().to(GetResourceResponseHandler.class); + messageHandlers.addBinding().to(GetProjectRequestHandler.class); + messageHandlers.addBinding().to(GetProjectResponseHandler.class); + messageHandlers.addBinding().to(ResourceCreatedHandler.class); + messageHandlers.addBinding().to(ResourceDeletedHandler.class); + messageHandlers.addBinding().to(ResourceChangedHandler.class); + + // repository listener bindings + final Multibinder repositoryListeners = Multibinder.newSetBinder(binder(), RepositoryListener.class); + repositoryListeners.addBinding().to(ProjectResourceCreatedListener.class); + repositoryListeners.addBinding().to(ProjectResourceDeletedListener.class); + repositoryListeners.addBinding().to(ProjectResourceModifiedListener.class); + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Resource.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Resource.java new file mode 100644 index 0000000..72d147c --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Resource.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import org.eclipse.flux.watcher.core.utils.ResourceHelper; + +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FOLDER; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.UNKNOWN; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Represents a project resource in a repository. + * + * @author Kevin Pollet + */ +public class Resource { + private static final String NULL_CONTENT_HASH = "0"; + + private final String path; + private final long timestamp; + private final String hash; + private final ResourceType type; + private final byte[] content; + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.core.Resource} representing a {@link + * Resource.ResourceType#UNKNOWN}. + * + * @param path + * the {@link com.codenvy.flux.watcher.core.Resource} relative path. + * @param timestamp + * the {@link com.codenvy.flux.watcher.core.Resource} timestamp. + * @return the new {@link com.codenvy.flux.watcher.core.Resource} instance. + * @throws java.lang.NullPointerException + * if {@code path} parameter is {@code null}. + */ + public static Resource newUnknown(String path, long timestamp) { + return new Resource(path, timestamp, UNKNOWN, null); + } + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.core.Resource} representing a {@link + * Resource.ResourceType#FOLDER}. + * + * @param path + * the {@link com.codenvy.flux.watcher.core.Resource} relative path. + * @param timestamp + * the {@link com.codenvy.flux.watcher.core.Resource} timestamp. + * @return the new {@link com.codenvy.flux.watcher.core.Resource} instance. + * @throws java.lang.NullPointerException + * if {@code path} parameter is {@code null}. + */ + public static Resource newFolder(String path, long timestamp) { + return new Resource(path, timestamp, FOLDER, null); + } + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.core.Resource} representing a {@link + * Resource.ResourceType#FILE}. + * + * @param path + * the {@link com.codenvy.flux.watcher.core.Resource} relative path. + * @param timestamp + * the {@link com.codenvy.flux.watcher.core.Resource} timestamp. + * @param content + * the {@link com.codenvy.flux.watcher.core.Resource} content. + * @return the new {@link com.codenvy.flux.watcher.core.Resource} instance. + * @throws java.lang.NullPointerException + * if {@code path} parameter is {@code null}. + */ + public static Resource newFile(String path, long timestamp, byte[] content) { + return new Resource(path, timestamp, FILE, content); + } + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.core.Resource}. + * + * @param path + * the {@link com.codenvy.flux.watcher.core.Resource} relative path. + * @param timestamp + * the {@link com.codenvy.flux.watcher.core.Resource} timestamp. + * @param type + * the {@link com.codenvy.flux.watcher.core.Resource} {@link Resource.ResourceType}. + * @param content + * the {@link com.codenvy.flux.watcher.core.Resource} content. + * @throws java.lang.NullPointerException + * if {@code path} or {@code type} parameter is {@code null}. + */ + private Resource(String path, long timestamp, ResourceType type, byte[] content) { + this.path = checkNotNull(path); + this.timestamp = timestamp; + this.type = checkNotNull(type); + this.content = content; + hash = content != null ? ResourceHelper.sha1(content) : NULL_CONTENT_HASH; + } + + /** + * Returns the relative path of this {@link com.codenvy.flux.watcher.core.Resource}. + * + * @return this {@link com.codenvy.flux.watcher.core.Resource} relative path, never {@code null}. + */ + public String path() { + return path; + } + + /** + * Returns the timestamp of this {@link com.codenvy.flux.watcher.core.Resource}. + * + * @return this {@link com.codenvy.flux.watcher.core.Resource} timestamp. + */ + public long timestamp() { + return timestamp; + } + + /** + * Returns the type hash this {@link com.codenvy.flux.watcher.core.Resource}. + * + * @return this {@link com.codenvy.flux.watcher.core.Resource} hash, never {@code null}. + */ + public String hash() { + return hash; + } + + /** + * Returns the type of this {@link com.codenvy.flux.watcher.core.Resource}. + * + * @return this {@link com.codenvy.flux.watcher.core.Resource} type, never {@code null}. + */ + public ResourceType type() { + return type; + } + + /** + * Returns the content of this {@link com.codenvy.flux.watcher.core.Resource}. + * + * @return this {@link com.codenvy.flux.watcher.core.Resource} content, {@code null} if none. + */ + public byte[] content() { + return content; + } + + /** + * The {@link com.codenvy.flux.watcher.core.Resource} type. + */ + public enum ResourceType { + FILE, + FOLDER, + UNKNOWN + } + + @Override + public String toString() { + return "Resource:" + path + ", " + type + ", " + hash + ", " + timestamp; + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/.gitignore b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/.gitignore new file mode 100644 index 0000000..c1b5ee1 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/.gitignore @@ -0,0 +1,54 @@ +# Created by .ignore support plugin (hsz.mobi) +### Eclipse template + +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# Eclipse Core +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java new file mode 100644 index 0000000..4c71e77 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.internal; + +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import javax.inject.Singleton; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CALLBACK_ID; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.FILES; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PATH; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.REQUEST_SENDER_ID; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_PROJECT_REQUEST; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_PROJECT_RESPONSE; + +/** + * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#GET_PROJECT_REQUEST}. + * + * @author Kevin Pollet + */ +@Singleton +@FluxMessageTypes(GET_PROJECT_REQUEST) +public final class GetProjectRequestHandler implements FluxMessageHandler { + @Override + public void onMessage(FluxMessage message, Repository repository) throws JSONException { + final JSONObject request = message.content(); + final int callbackId = request.getInt(CALLBACK_ID.value()); + final String requestSenderId = request.getString(REQUEST_SENDER_ID.value()); + final String projectName = request.getString(PROJECT.value()); + + final Project project = repository.getProject(projectName); + if (project != null) { + final JSONArray files = new JSONArray(); + for (Resource oneResource : project.getResources()) { + files.put(new JSONObject() + .put(PATH.value(), oneResource.path()) + .put(TIMESTAMP.value(), oneResource.timestamp()) + .put(HASH.value(), oneResource.hash()) + .put(TYPE.value(), oneResource.type().name().toLowerCase())); + } + + final JSONObject content = new JSONObject() + .put(CALLBACK_ID.value(), callbackId) + .put(REQUEST_SENDER_ID.value(), requestSenderId) + .put(PROJECT.value(), projectName) + .put(FILES.value(), files); + + message.source() + .sendMessage(new FluxMessage(GET_PROJECT_RESPONSE, content)); + } + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java new file mode 100644 index 0000000..5376868 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.internal; + +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; + +import org.json.JSONArray; +import org.json.JSONObject; + +import javax.inject.Singleton; +import java.util.Objects; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.DELETED; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.FILES; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PATH; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_PROJECT_RESPONSE; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_REQUEST; +import static org.eclipse.flux.watcher.core.Resource.ResourceType; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FOLDER; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.UNKNOWN; + +/** + * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#GET_PROJECT_RESPONSE}. + * + * @author Kevin Pollet + */ +@Singleton +@FluxMessageTypes(GET_PROJECT_RESPONSE) +public final class GetProjectResponseHandler implements FluxMessageHandler { + @Override + public void onMessage(FluxMessage message, Repository repository) throws Exception { + final JSONObject request = message.content(); + final String projectName = request.getString(PROJECT.value()); + final JSONArray files = request.getJSONArray(FILES.value()); + final JSONArray deleted = request.optJSONArray(DELETED.value()); + + final Project project = repository.getProject(projectName); + if (project != null) { + // new files + for (int i = 0; i < files.length(); i++) { + final JSONObject resource = files.getJSONObject(i); + final String resourcePath = resource.getString(PATH.value()); + final long resourceTimestamp = resource.getLong(TIMESTAMP.value()); + final ResourceType resourceType = ResourceType.valueOf(resource.optString(TYPE.value(), UNKNOWN.name()).toUpperCase()); + final String resourceHash = resource.optString(HASH.value(), "0"); + + final Resource localResource = project.getResource(resourcePath); + if (resourceType == FILE) { + if (localResource == null + || localResource.timestamp() < resourceTimestamp + && !Objects.equals(resourceHash, localResource.hash())) { + + final JSONObject content = new JSONObject() + .put(PROJECT.value(), projectName) + .put(RESOURCE.value(), resourcePath) + .put(TIMESTAMP.value(), resourceTimestamp) + .put(HASH.value(), resourceHash); + + message.source() + .sendMessage(new FluxMessage(GET_RESOURCE_REQUEST, content)); + } + + } else if (resourceType == FOLDER && localResource == null) { + project.createResource(Resource.newFolder(resourcePath, resourceTimestamp)); + } + } + + // deleted files + if (deleted != null) { + for (int i = 0; i < deleted.length(); i++) { + final JSONObject resource = deleted.getJSONObject(i); + final String resourcePath = resource.getString(PATH.value()); + final long resourceTimestamp = resource.getLong(TIMESTAMP.value()); + + final Resource localResource = project.getResource(resourcePath); + if (localResource != null && localResource.timestamp() < resourceTimestamp) { + project.deleteResource(Resource.newUnknown(resourcePath, resourceTimestamp)); + } + } + } + } + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java new file mode 100644 index 0000000..bb35102 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.internal; + +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; + +import org.json.JSONException; +import org.json.JSONObject; + +import javax.inject.Singleton; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CALLBACK_ID; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CONTENT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.REQUEST_SENDER_ID; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_REQUEST; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_RESPONSE; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; + +/** + * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#GET_RESOURCE_REQUEST}. + * + * @author Kevin Pollet + */ +@Singleton +@FluxMessageTypes(GET_RESOURCE_REQUEST) +public final class GetResourceRequestHandler implements FluxMessageHandler { + @Override + public void onMessage(FluxMessage message, Repository repository) throws JSONException { + final JSONObject request = message.content(); + final int callbackId = request.getInt(CALLBACK_ID.value()); + final String requestSenderId = request.getString(REQUEST_SENDER_ID.value()); + final String projectName = request.getString(PROJECT.value()); + final String resourcePath = request.getString(RESOURCE.value()); + + final Project project = repository.getProject(projectName); + if (project != null) { + final Resource resource = project.getResource(resourcePath); + + // compare the time stamp and allow a nearly difference for now TODO find out why CodenvyVFS -> Eclipse has different timestamp + long requestTimeStamp = request.has(TIMESTAMP.value()) ? request.getLong(TIMESTAMP.value()) : 0; + long resourceTimeStamp = resource.timestamp(); + if (!request.has(TIMESTAMP.value()) || Math.abs(requestTimeStamp - resourceTimeStamp) < 10000) { + final JSONObject content = new JSONObject() + .put(CALLBACK_ID.value(), callbackId) + .put(REQUEST_SENDER_ID.value(), requestSenderId) + .put(PROJECT.value(), projectName) + .put(RESOURCE.value(), resourcePath) + .put(TIMESTAMP.value(), resourceTimeStamp) + .put(HASH.value(), resource.hash()) + .put(TYPE.value(), resource.type().name().toLowerCase()); + + if (resource.type() == FILE) { + content.put(CONTENT.value(), new String(resource.content())); + } + + message.source() + .sendMessage(new FluxMessage(GET_RESOURCE_RESPONSE, content)); + } + } + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java new file mode 100644 index 0000000..656bfa4 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.internal; + +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; + +import org.json.JSONException; +import org.json.JSONObject; + +import javax.inject.Singleton; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CONTENT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_RESPONSE; +import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_STORED; +import static org.eclipse.flux.watcher.core.Resource.ResourceType; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; + +/** + * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#GET_RESOURCE_RESPONSE}. + * + * @author Kevin Pollet + */ +@Singleton +@FluxMessageTypes(GET_RESOURCE_RESPONSE) +public final class GetResourceResponseHandler implements FluxMessageHandler { + @Override + public void onMessage(FluxMessage message, Repository repository) throws JSONException { + final JSONObject request = message.content(); + final String projectName = request.getString(PROJECT.value()); + final String resourcePath = request.getString(RESOURCE.value()); + final long resourceTimestamp = request.getLong(TIMESTAMP.value()); + final String resourceHash = request.getString(HASH.value()); + final String resourceContent = request.getString(CONTENT.value()); + + final Project project = repository.getProject(projectName); + if (project != null) { + final ResourceType resourceType = ResourceType.valueOf(request.getString(TYPE.value()).toUpperCase()); + + if (resourceType == FILE) { + boolean isResourceStored = false; + final Resource localResource = project.getResource(resourcePath); + final Resource resource = Resource.newFile(resourcePath, resourceTimestamp, resourceContent.getBytes()); + + if (localResource == null) { + project.createResource(resource); + isResourceStored = true; + + } else if (!localResource.hash().equals(resourceHash) && localResource.timestamp() < resourceTimestamp) { + project.updateResource(resource); + isResourceStored = true; + } + + if (isResourceStored) { + final JSONObject content = new JSONObject() + .put(PROJECT.value(), projectName) + .put(RESOURCE.value(), resourcePath) + .put(TIMESTAMP.value(), resourceTimestamp) + .put(HASH.value(), resourceHash) + .put(TYPE.value(), resourceType.name().toLowerCase()); + + message.source() + .sendMessage(new FluxMessage(RESOURCE_STORED, content)); + } + } + } + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java new file mode 100644 index 0000000..9d3a7a1 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.internal; + +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageBus; +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventTypes; +import org.eclipse.flux.watcher.core.RepositoryListener; + +import org.json.JSONException; +import org.json.JSONObject; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; +import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_CREATED; +import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_STORED; +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_CREATED; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Listener sending a message to flux connections when a project resource is created in the repository. + * + * @author Kevin Pollet + */ +@Singleton +@RepositoryEventTypes(PROJECT_RESOURCE_CREATED) +public final class ProjectResourceCreatedListener implements RepositoryListener { + private final FluxMessageBus messageBus; + + /** + * Constructs an instance of {@code ProjectResourceCreatedListener}. + * + * @param messageBus + * the {@link com.codenvy.flux.watcher.core.FluxMessageBus}. + * @throws java.lang.NullPointerException + * if {@code messageBus} parameter is {@code null}. + */ + @Inject + ProjectResourceCreatedListener(FluxMessageBus messageBus) { + this.messageBus = checkNotNull(messageBus); + } + + @Override + public void onEvent(RepositoryEvent event) throws JSONException { + final JSONObject content = new JSONObject() + .put(PROJECT.value(), event.project().id()) + .put(RESOURCE.value(), event.resource().path()) + .put(TIMESTAMP.value(), event.resource().timestamp()) + .put(HASH.value(), event.resource().hash()) + .put(TYPE.value(), event.resource().type().name().toLowerCase()); + + messageBus.sendMessages(new FluxMessage(RESOURCE_CREATED, content), new FluxMessage(RESOURCE_STORED, content)); + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java new file mode 100644 index 0000000..519a032 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.internal; + +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageBus; +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventTypes; +import org.eclipse.flux.watcher.core.RepositoryListener; + +import org.json.JSONException; +import org.json.JSONObject; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; +import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_DELETED; +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_DELETED; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Listener sending a message to flux connections when a project resource is deleted in the repository. + * + * @author Kevin Pollet + */ +@Singleton +@RepositoryEventTypes(PROJECT_RESOURCE_DELETED) +public final class ProjectResourceDeletedListener implements RepositoryListener { + private final FluxMessageBus messageBus; + + /** + * Constructs an instance of {@code ProjectResourceDeletedListener}. + * + * @param messageBus + * the {@link com.codenvy.flux.watcher.core.FluxMessageBus}. + * @throws NullPointerException + * if {@code messageBus} parameter is {@code null}. + */ + @Inject + ProjectResourceDeletedListener(FluxMessageBus messageBus) { + this.messageBus = checkNotNull(messageBus); + } + + @Override + public void onEvent(RepositoryEvent event) throws JSONException { + final JSONObject content = new JSONObject() + .put(PROJECT.value(), event.project().id()) + .put(RESOURCE.value(), event.resource().path()) + .put(TIMESTAMP.value(), event.resource().timestamp()); + + messageBus.sendMessages(new FluxMessage(RESOURCE_DELETED, content)); + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java new file mode 100644 index 0000000..4d242ee --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.internal; + +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageBus; +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventTypes; +import org.eclipse.flux.watcher.core.RepositoryListener; + +import org.json.JSONException; +import org.json.JSONObject; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; +import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_CHANGED; +import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_STORED; +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_MODIFIED; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Listener sending a message to flux connections when a project resource is modified in the repository. + * + * @author Kevin Pollet + */ +@Singleton +@RepositoryEventTypes(PROJECT_RESOURCE_MODIFIED) +public final class ProjectResourceModifiedListener implements RepositoryListener { + private final FluxMessageBus messageBus; + + /** + * Constructs an instance of {@code ProjectResourceModifiedListener}. + * + * @param messageBus + * the {@link com.codenvy.flux.watcher.core.FluxMessageBus}. + * @throws NullPointerException + * if {@code messageBus} parameter is {@code null}. + */ + @Inject + ProjectResourceModifiedListener(FluxMessageBus messageBus) { + this.messageBus = checkNotNull(messageBus); + } + + @Override + public void onEvent(RepositoryEvent event) throws JSONException { + if (event.resource().type() == FILE) { + final JSONObject content = new JSONObject() + .put(PROJECT.value(), event.project().id()) + .put(RESOURCE.value(), event.resource().path()) + .put(TIMESTAMP.value(), event.resource().timestamp()) + .put(HASH.value(), event.resource().hash()); + + messageBus.sendMessages(new FluxMessage(RESOURCE_CHANGED, content), new FluxMessage(RESOURCE_STORED, content)); + } + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java new file mode 100644 index 0000000..e40bb70 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.internal; + +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; + +import org.json.JSONException; +import org.json.JSONObject; + +import javax.inject.Singleton; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_REQUEST; +import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_CHANGED; + +/** + * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#RESOURCE_CHANGED}. + * + * @author Kevin Pollet + */ +@Singleton +@FluxMessageTypes(RESOURCE_CHANGED) +public final class ResourceChangedHandler implements FluxMessageHandler { + @Override + public void onMessage(FluxMessage message, Repository repository) throws JSONException { + final JSONObject request = message.content(); + final String projectName = request.getString(PROJECT.value()); + final String resourcePath = request.getString(RESOURCE.value()); + final long resourceTimestamp = request.getLong(TIMESTAMP.value()); + final String resourceHash = request.getString(HASH.value()); + + final Project project = repository.getProject(projectName); + if (project != null) { + final Resource localResource = project.getResource(resourcePath); + + if (localResource != null + && !localResource.hash().equals(resourceHash) + && localResource.timestamp() < resourceTimestamp) { + + final JSONObject content = new JSONObject() + .put(PROJECT.value(), projectName) + .put(RESOURCE.value(), resourcePath) + .put(TIMESTAMP.value(), resourceTimestamp) + .put(HASH.value(), resourceHash); + + message.source() + .sendMessage(new FluxMessage(GET_RESOURCE_REQUEST, content)); + } + } + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java new file mode 100644 index 0000000..1ae676c --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.internal; + +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; + +import org.json.JSONException; +import org.json.JSONObject; + +import javax.inject.Singleton; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; +import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_REQUEST; +import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_CREATED; +import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_STORED; +import static org.eclipse.flux.watcher.core.Resource.ResourceType; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FOLDER; + +/** + * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#RESOURCE_CREATED}. + * + * @author Kevin Pollet + */ +@Singleton +@FluxMessageTypes(RESOURCE_CREATED) +public final class ResourceCreatedHandler implements FluxMessageHandler { + @Override + public void onMessage(FluxMessage message, Repository repository) throws JSONException { + final JSONObject request = message.content(); + final String projectName = request.getString(PROJECT.value()); + final String resourcePath = request.getString(RESOURCE.value()); + final long resourceTimestamp = request.getLong(TIMESTAMP.value()); + final String resourceHash = request.getString(HASH.value()); + + final Project project = repository.getProject(projectName); + if (project != null && project.getResource(resourcePath) == null) { + final ResourceType resourceType = ResourceType.valueOf(request.getString(TYPE.value()).toUpperCase()); + if (resourceType == FOLDER) { + final Resource folder = Resource.newFolder(resourcePath, resourceTimestamp); + project.createResource(folder); + } + + final JSONObject content = new JSONObject() + .put(PROJECT.value(), projectName) + .put(RESOURCE.value(), resourcePath) + .put(TIMESTAMP.value(), resourceTimestamp) + .put(HASH.value(), resourceHash) + .put(TYPE.value(), resourceType.name().toLowerCase()); + + message.source() + .sendMessage(new FluxMessage(resourceType == FOLDER ? RESOURCE_STORED : GET_RESOURCE_REQUEST, content)); + } + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java new file mode 100644 index 0000000..2f42609 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.internal; + +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; + +import org.json.JSONException; +import org.json.JSONObject; + +import javax.inject.Singleton; + +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; +import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; +import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_DELETED; + +/** + * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#RESOURCE_DELETED}. + * + * @author Kevin Pollet + */ +@Singleton +@FluxMessageTypes(RESOURCE_DELETED) +public final class ResourceDeletedHandler implements FluxMessageHandler { + @Override + public void onMessage(FluxMessage message, Repository repository) throws JSONException { + final JSONObject request = message.content(); + final String projectName = request.getString(PROJECT.value()); + final String resourcePath = request.getString(RESOURCE.value()); + final long resourceTimestamp = request.getLong(TIMESTAMP.value()); + + final Project project = repository.getProject(projectName); + if (project != null) { + final Resource localResource = project.getResource(resourcePath); + + if (localResource != null && localResource.timestamp() < resourceTimestamp) { + project.deleteResource(Resource.newUnknown(resourcePath, resourceTimestamp)); + } + } + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/Project.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/Project.java new file mode 100644 index 0000000..f6ffde9 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/Project.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.spi; + +import org.eclipse.flux.watcher.core.Resource; + +import java.util.Set; + +/** + * Project contract implemented by a provider. + * + * @author Kevin Pollet + * @see com.codenvy.flux.watcher.core.spi.ProjectFactory + */ +public interface Project { + /** + * Returns the project unique id. + * + * @return the project unique id, never {@code null}. + */ + String id(); + + /** + * Returns the project absolute path. + * + * @return the project absolute path, never {@code null}. + */ + String path(); + + /** + * Defines if this project is synchronized. The implementer must send the project events to the {@link + * com.codenvy.flux.watcher.core.RepositoryEventBus}. + * + * @param synchronize + * {@code true} if the project have to be synchronized, {@code false} otherwise. + */ + void setSynchronized(boolean synchronize); + + /** + * Returns whether or not the project is currently synchronized. + * + * @return true or false, never {@code null}. + */ + boolean getSynchronized(); + + /** + * Returns all project {@link com.codenvy.flux.watcher.core.Resource}. + * + * @return the {@link com.codenvy.flux.watcher.core.Resource} {@link java.util.Set}, never {@code null}. + */ + Set getResources(); + + /** + * Returns the {@link com.codenvy.flux.watcher.core.Resource} with the given relative resource path. + * + * @param resourcePath + * the {@link com.codenvy.flux.watcher.core.Resource} relative path. + * @return the {@link com.codenvy.flux.watcher.core.Resource} or {@code null} if not found. + * @throws java.lang.NullPointerException + * if {@code resourcePath} parameter is {@code null}. + */ + Resource getResource(String resourcePath); + + /** + * Creates the given {@link com.codenvy.flux.watcher.core.Resource}. + * + * @param resource + * the {@link com.codenvy.flux.watcher.core.Resource} to be created. + * @throws java.lang.NullPointerException + * if {@code resource} parameter is {@code null}. + */ + void createResource(Resource resource); + + /** + * Updates the given {@link com.codenvy.flux.watcher.core.Resource}. + * + * @param resource + * the {@link com.codenvy.flux.watcher.core.Resource} to be updated. + * @throws java.lang.NullPointerException + * if {@code resource} parameter is {@code null}. + * @throws java.lang.IllegalArgumentException + * if {@code resource} parameter is not a file. + */ + void updateResource(Resource resource); + + /** + * Deletes the given {@link com.codenvy.flux.watcher.core.Resource}. + * + * @param resource + * the {@link com.codenvy.flux.watcher.core.Resource} to be deleted. + * @throws java.lang.NullPointerException + * if {@code resource} parameter is {@code null}. + */ + void deleteResource(Resource resource); +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/ProjectFactory.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/ProjectFactory.java new file mode 100644 index 0000000..0e9236f --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/ProjectFactory.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.spi; + +/** + * Project factory contract implemented by a provider. + * + * @author Kevin Pollet + */ +public interface ProjectFactory { + /** + * Returns a new {@link com.codenvy.flux.watcher.core.spi.Project} instance for the given project id and path. + * + * @param projectId + * the project id. + * @param projectPath + * the project path. + * @return the new {@link com.codenvy.flux.watcher.core.spi.Project} instance, never {@code null}. + * @throws java.lang.NullPointerException + * if {@code projectId} or {@code projectPath} parameter is {@code null}. + * @throws java.lang.IllegalArgumentException + * if {@code projectPath} parameter is not absolute, doesn't exist or is not a folder. + */ + Project newProject(String projectId, String projectPath); +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/utils/ResourceHelper.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/utils/ResourceHelper.java new file mode 100644 index 0000000..44e52d8 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/utils/ResourceHelper.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core.utils; + +import javax.xml.bind.DatatypeConverter; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Helper providing methods to work with {@link com.codenvy.flux.watcher.core.Resource}. + * + * @author Kevin Pollet + */ +public final class ResourceHelper { + private static final MessageDigest messageDigest; + + static { + try { + + messageDigest = MessageDigest.getInstance("SHA-1"); + + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + + /** + * Calculates the sha1 for the given {@link java.lang.Byte} array. + * + * @param bytes + * the {@link java.lang.Byte} array. + * @return the sha1 as an hexadecimal {@link String}, never {@code null}. + * @throws java.lang.NullPointerException + * if {@code bytes} parameter is {@code null}. + */ + public static String sha1(byte[] bytes) { + final byte[] digest = messageDigest.digest(checkNotNull(bytes)); + return DatatypeConverter.printHexBinary(digest); + } + + /** + * Disable instantiation. + */ + private ResourceHelper() { + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProject.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProject.java new file mode 100644 index 0000000..45f6d92 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProject.java @@ -0,0 +1,254 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.fs; + +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; + +import javax.inject.Singleton; +import java.io.IOException; +import java.nio.file.FileSystem; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.util.HashSet; +import java.util.Set; + +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FOLDER; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static java.nio.file.FileVisitResult.CONTINUE; +import static java.nio.file.Files.createDirectory; +import static java.nio.file.Files.delete; +import static java.nio.file.Files.exists; +import static java.nio.file.Files.getLastModifiedTime; +import static java.nio.file.Files.isDirectory; +import static java.nio.file.Files.readAllBytes; +import static java.nio.file.Files.setLastModifiedTime; +import static java.nio.file.Files.walkFileTree; +import static java.nio.file.Files.write; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +/** + * {@link com.codenvy.flux.watcher.core.spi.Project} implementation backed by Java {@code FileSystem}. + * + * @author Kevin Pollet + */ +@Singleton +public class JDKProject implements Project { + private final String id; + private final Path path; + private final JDKProjectWatchService watchService; + private boolean sync; + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.fs.JDKProject}. + * + * @param fileSystem + * the {@link java.nio.file.FileSystem} + * @param watchService + * the {@link JDKProjectWatchService}. + * @param id + * the project id. + * @param path + * the project absolute path. + * @throws java.lang.NullPointerException + * if {@code fileSystem}, {@code watchService}, {@code id} or {@code path} parameter is {@code null}. + * @throws java.lang.IllegalArgumentException + * if {@code path} parameter is not absolute, doesn't exist or is not a folder. + */ + JDKProject(FileSystem fileSystem, JDKProjectWatchService watchService, String id, String path) { + this.id = checkNotNull(id); + this.watchService = checkNotNull(watchService); + + this.path = checkNotNull(fileSystem).getPath(checkNotNull(path)); + checkArgument(exists(this.path) && isDirectory(this.path) && this.path.isAbsolute()); + + // start the watch service + this.watchService.start(); + } + + @Override + public String id() { + return id; + } + + @Override + public String path() { + return path.toString(); + } + + @Override + public void setSynchronized(boolean synchronize) { + if (synchronize) { + watchService.watch(this); + } else { + watchService.unwatch(this); + } + sync = synchronize; + } + + @Override + public boolean getSynchronized() { + return sync; + } + + @Override + public Set getResources() { + final Set resources = new HashSet<>(); + try { + + walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + if (!dir.equals(path)) { + final long timestamp = getLastModifiedTime(dir).toMillis(); + final String relativeResourcePath = path.relativize(dir).toString(); + + resources.add(Resource.newFolder(relativeResourcePath, timestamp)); + } + + return CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + final long timestamp = getLastModifiedTime(file).toMillis(); + final String relativeResourcePath = path.relativize(file).toString(); + final byte[] content = readAllBytes(file); + + resources.add(Resource.newFile(relativeResourcePath, timestamp, content)); + + return CONTINUE; + } + }); + + } catch (IOException e) { + throw new RuntimeException(e); + } + + return resources; + } + + @Override + public Resource getResource(String resourcePath) { + checkNotNull(resourcePath); + + final Path resource = path.resolve(resourcePath); + if (exists(resource)) { + try { + final boolean isDirectory = isDirectory(resource); + final long timestamp = getLastModifiedTime(resource).toMillis(); + + return isDirectory ? Resource.newFolder(resourcePath, timestamp) + : Resource.newFile(resourcePath, timestamp, readAllBytes(resource)); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + return null; + } + + @Override + public void createResource(Resource resource) { + checkNotNull(resource); + + final Path resourcePath = path.resolve(resource.path()); + if (!exists(resourcePath)) { + try { + + if (resource.type() == FOLDER) { + createDirectory(resourcePath); + setLastModifiedTime(resourcePath, FileTime.from(resource.timestamp(), MILLISECONDS)); + + } else if (resource.type() == FILE) { + write(resourcePath, resource.content()); + setLastModifiedTime(resourcePath, FileTime.from(resource.timestamp(), MILLISECONDS)); + } + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + @Override + public void updateResource(Resource resource) { + checkNotNull(resource); + checkArgument(resource.type() == FILE); + + final Path resourcePath = path.resolve(resource.path()); + if (exists(resourcePath)) { + try { + + write(resourcePath, resource.content()); + setLastModifiedTime(resourcePath, FileTime.from(resource.timestamp(), MILLISECONDS)); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + @Override + public void deleteResource(Resource resource) { + checkNotNull(resource); + + final Path resourcePath = path.resolve(resource.path()); + if (exists(resourcePath)) { + try { + + Files.walkFileTree(resourcePath, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + delete(file); + return CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path folder, IOException exc) throws IOException { + delete(folder); + return CONTINUE; + } + }); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JDKProject that = (JDKProject)o; + + if (!id.equals(that.id)) return false; + if (!path.equals(that.path)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = id.hashCode(); + result = 31 * result + path.hashCode(); + return result; + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectFactory.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectFactory.java new file mode 100644 index 0000000..acd9476 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectFactory.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.fs; + +import org.eclipse.flux.watcher.core.RepositoryEventBus; +import org.eclipse.flux.watcher.core.spi.Project; +import org.eclipse.flux.watcher.core.spi.ProjectFactory; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.nio.file.FileSystem; +import java.nio.file.Path; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static java.nio.file.Files.exists; +import static java.nio.file.Files.isDirectory; + +/** + * {@link com.codenvy.flux.watcher.core.spi.ProjectFactory} implementation. + * + * @author Kevin Pollet + */ +@Singleton +public class JDKProjectFactory implements ProjectFactory { + private final FileSystem fileSystem; + private final JDKProjectWatchService watchService; + + /** + * Constructs an instance of {@link com.codenvy.flux.watcher.fs.JDKProjectFactory}. + * + * @param fileSystem + * the {@link java.nio.file.FileSystem} instance. + * @param repositoryEventBus + * the {@link com.codenvy.flux.watcher.core.RepositoryEventBus}. + * @throws java.lang.NullPointerException + * if {@code fileSystem} or {@code repositoryEventBus} is {@code null}. + */ + @Inject + public JDKProjectFactory(FileSystem fileSystem, RepositoryEventBus repositoryEventBus) { + this.fileSystem = checkNotNull(fileSystem); + this.watchService = new JDKProjectWatchService(fileSystem, checkNotNull(repositoryEventBus)); + } + + @Override + public Project newProject(String projectId, String projectPath) { + checkNotNull(projectId); + checkNotNull(projectPath); + + final Path path = fileSystem.getPath(projectPath); + checkArgument(exists(path) && isDirectory(path) && path.isAbsolute()); + + return new JDKProject(fileSystem, watchService, projectId, projectPath); + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectModule.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectModule.java new file mode 100644 index 0000000..12a0d02 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectModule.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.fs; + +import org.eclipse.flux.watcher.core.spi.ProjectFactory; +import com.google.inject.AbstractModule; +import com.google.inject.Provides; + +import javax.inject.Singleton; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; + +/** + * Guice bindings. + * + * @author Kevin Pollet + */ +public class JDKProjectModule extends AbstractModule { + @Override + protected void configure() { + bind(ProjectFactory.class).to(JDKProjectFactory.class); + } + + @Singleton + @Provides + protected FileSystem provideFileSystem() { + return FileSystems.getDefault(); + } +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java new file mode 100644 index 0000000..a3059e0 --- /dev/null +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java @@ -0,0 +1,281 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.fs; + +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventBus; +import org.eclipse.flux.watcher.core.RepositoryEventType; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; + +import java.io.IOException; +import java.nio.file.ClosedWatchServiceException; +import java.nio.file.FileSystem; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.HashMap; +import java.util.Map; + +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_CREATED; +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_DELETED; +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_MODIFIED; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static java.nio.file.FileVisitResult.CONTINUE; +import static java.nio.file.Files.exists; +import static java.nio.file.Files.getLastModifiedTime; +import static java.nio.file.Files.isDirectory; +import static java.nio.file.Files.readAllBytes; +import static java.nio.file.Files.walkFileTree; +import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; +import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; +import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; +import static java.nio.file.StandardWatchEventKinds.OVERFLOW; +import static java.nio.file.WatchEvent.Kind; + +/** + * Thread watching the file system to notify clients about modifications. + * + * @author Kevin Pollet + */ +public class JDKProjectWatchService extends Thread { + private final WatchService watchService; + private final BiMap watchKeyToPath; + private final Map pathToProject; + private final Object mutex; + private final RepositoryEventBus repositoryEventBus; + private final FileSystem fileSystem; + + /** + * Constructs an instance of {@link JDKProjectWatchService}. + * + * @param fileSystem + * the {@link java.nio.file.FileSystem} to watch. + * @param repositoryEventBus + * the {@link com.codenvy.flux.watcher.core.RepositoryEvent} bus. + * @throws java.lang.NullPointerException + * if {@code repositoryEventBus} or {@code fileSystem} parameter is {@code null}. + */ + JDKProjectWatchService(FileSystem fileSystem, RepositoryEventBus repositoryEventBus) { + this.watchKeyToPath = HashBiMap.create(); + this.pathToProject = new HashMap<>(); + this.mutex = new Object(); + this.repositoryEventBus = checkNotNull(repositoryEventBus); + this.fileSystem = checkNotNull(fileSystem); + + try { + + this.watchService = fileSystem.newWatchService(); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public void watch(Project project) { + checkNotNull(project); + watch(project, fileSystem.getPath(project.path())); + } + + private void watch(final Project project, Path path) { + checkNotNull(path); + checkArgument(exists(path) && isDirectory(path) && path.isAbsolute()); + + synchronized (mutex) { + try { + + walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + if (!watchKeyToPath.containsValue(dir)) { + final WatchKey watchKey = dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); + + watchKeyToPath.put(watchKey, dir); + pathToProject.put(dir, project); + } + return CONTINUE; + } + }); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + public void unwatch(Project project) { + checkNotNull(project); + unwatch(fileSystem.getPath(project.path())); + } + + private void unwatch(Path path) { + checkNotNull(path); + checkArgument(exists(path) && isDirectory(path) && path.isAbsolute()); + + synchronized (mutex) { + try { + + walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + final WatchKey watchKey = watchKeyToPath.inverse().get(dir); + if (watchKey != null) { + watchKeyToPath.inverse().remove(dir); + pathToProject.remove(dir); + watchKey.cancel(); + } + return CONTINUE; + } + }); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + /** + * Process all events for keys queued to the watcher. + */ + @Override + public void run() { + while (!isInterrupted()) { + try { + + final WatchKey watchKey = watchService.take(); + synchronized (mutex) { + if (!watchKeyToPath.containsKey(watchKey)) { + continue; + } + } + + for (WatchEvent oneEvent : watchKey.pollEvents()) { + final Path watchablePath = (Path)watchKey.watchable(); + final WatchEvent pathEvent = cast(oneEvent); + final Path resourcePath = watchablePath.resolve(pathEvent.context()); + + if (oneEvent.kind() == OVERFLOW) { + continue; + } + + if (oneEvent.kind() == ENTRY_CREATE && isDirectory(resourcePath)) { + watch(pathToProject.get(watchablePath), resourcePath); + } + + final Project project = pathToProject.get(watchablePath); + final RepositoryEventType repositoryEventType = kindToRepositoryEventType(pathEvent.kind()); + final Resource resource = pathToResource(pathEvent.kind(), project, resourcePath); + repositoryEventBus.fireRepositoryEvent(new RepositoryEvent(repositoryEventType, resource, project)); + } + + final boolean isValid = watchKey.reset(); + if (!isValid) { + synchronized (mutex) { + final Path path = watchKeyToPath.remove(watchKey); + if (path != null) { + pathToProject.remove(path); + } + } + } + + } catch (ClosedWatchServiceException | InterruptedException e) { + return; + } + } + } + + /** + * Converts a {@link java.nio.file.WatchEvent} {@link java.nio.file.WatchEvent.Kind} to a {@link + * com.codenvy.flux.watcher.core.RepositoryEventType}. + * + * @param kind + * the {@link java.nio.file.WatchEvent.Kind} to convert. + * @return the corresponding {@link com.codenvy.flux.watcher.core.RepositoryEventType} or {@code null} if none. + */ + private RepositoryEventType kindToRepositoryEventType(Kind kind) { + if (kind == ENTRY_CREATE) { + return PROJECT_RESOURCE_CREATED; + } + if (kind == ENTRY_MODIFY) { + return PROJECT_RESOURCE_MODIFIED; + } + if (kind == ENTRY_DELETE) { + return PROJECT_RESOURCE_DELETED; + } + return null; + } + + /** + * Converts the given resource {@link java.nio.file.Path} to a {@link com.codenvy.flux.watcher.core.Resource}. + * + * @param kind + * the watch event {@link java.nio.file.WatchEvent.Kind}. + * @param project + * the {@link com.codenvy.flux.watcher.core.spi.Project} containing the resource. + * @param resourcePath + * the absolute resource {@link java.nio.file.Path}. + * @return the {@link com.codenvy.flux.watcher.core.Resource} instance, never {@code null}. + * @throws java.lang.NullPointerException + * if {@code kind}, {@code project} or {@code resourcePath} is {@code null}. + * @throws java.lang.IllegalArgumentException + * if the resource does not exist and the {@link java.nio.file.WatchEvent.Kind} is not {@link + * java.nio.file.StandardWatchEventKinds#ENTRY_DELETE}. + */ + private Resource pathToResource(Kind kind, Project project, Path resourcePath) { + checkNotNull(kind); + checkNotNull(project); + checkNotNull(resourcePath); + checkArgument(resourcePath.isAbsolute()); + + try { + + final boolean exists = exists(resourcePath); + checkArgument(kind == ENTRY_DELETE || exists); + + final Path projectPath = fileSystem.getPath(project.path()); + final String relativeResourcePath = projectPath.relativize(resourcePath).toString(); + final long timestamp = exists ? getLastModifiedTime(resourcePath).toMillis() : System.currentTimeMillis(); + + if (exists) { + final boolean isDirectory = isDirectory(resourcePath); + return isDirectory ? Resource.newFolder(relativeResourcePath, timestamp) + : Resource.newFile(relativeResourcePath, timestamp, readAllBytes(resourcePath)); + + } else { + return Resource.newUnknown(relativeResourcePath, timestamp); + } + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Cast the given {@link java.nio.file.WatchEvent} to a {@link java.nio.file.Path} {@link java.nio.file.WatchEvent}. + * + * @param event + * the {@link java.nio.file.WatchEvent} to cast. + * @return the casted {@link java.nio.file.WatchEvent}. + * @throws java.lang.NullPointerException + * if {@code event} parameter is {@code null}. + */ + @SuppressWarnings("unchecked") + private WatchEvent cast(WatchEvent event) { + return (WatchEvent)checkNotNull(event); + } +} diff --git a/pom.xml b/pom.xml index 6ea30d4..27f9f11 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,5 @@ - + 4.0.0 @@ -43,7 +42,8 @@ org.eclipse.flux.parent.java org.eclipse.flux.client.java - - + + org.eclipse.flux.watcher + - + \ No newline at end of file From 327b106fdc8e4e48b8a60916f5d5b182bd812bb6 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Tue, 21 Jun 2016 06:27:22 +0300 Subject: [PATCH 02/34] Imported the flux-watcher library into Flux Core Signed-off-by: Fjodor Vershinin --- org.eclipse.flux.core/META-INF/MANIFEST.MF | 4 +++- .../src/org/eclipse/flux/core/Repository.java | 13 ++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/org.eclipse.flux.core/META-INF/MANIFEST.MF b/org.eclipse.flux.core/META-INF/MANIFEST.MF index 8aa5454..88a7e08 100644 --- a/org.eclipse.flux.core/META-INF/MANIFEST.MF +++ b/org.eclipse.flux.core/META-INF/MANIFEST.MF @@ -14,7 +14,9 @@ Require-Bundle: org.eclipse.flux.client.java.osgi, org.eclipse.core.runtime, org.apache.commons.io, org.eclipse.jdt.core, - org.eclipse.m2e.core;resolution:=optional + org.eclipse.m2e.core;resolution:=optional, + org.eclipse.flux.watcher;bundle-version="1.0.0", + com.google.inject;bundle-version="3.0.0" Export-Package: org.eclipse.flux.core, org.eclipse.flux.core.util Bundle-ActivationPolicy: lazy; exclude:="io.socket, org.java_websocket, org.java_websocket.client, org.java_websocket.drafts, org.java_websocket.exceptions, org.java_websocket.framing, org.java_websocket.handshake, org.java_websocket.server, org.java_websocket.util, org.json" diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java index 8d2beef..2525a4f 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java @@ -36,6 +36,9 @@ import org.eclipse.flux.client.IMessageHandler; import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageBus; +import org.eclipse.flux.watcher.core.RepositoryModule; +import org.eclipse.flux.watcher.fs.JDKProjectModule; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; @@ -44,6 +47,9 @@ import org.json.JSONException; import org.json.JSONObject; +import com.google.inject.Guice; +import com.google.inject.Injector; + /** * @author Martin Lippert */ @@ -60,12 +66,17 @@ public class Repository { private static int GET_RESOURCE_CALLBACK = "Repository - getResourceCallback".hashCode(); private AtomicBoolean connected; + + private org.eclipse.flux.watcher.core.Repository repository; + private FluxMessageBus messageBus; public Repository(MessageConnector messagingConnector, String user) { + Injector injector = Guice.createInjector(new RepositoryModule(), new JDKProjectModule()); this.username = user; + this.repository = injector.getInstance(org.eclipse.flux.watcher.core.Repository.class); + this.messageBus = injector.getInstance(FluxMessageBus.class); this.connected = new AtomicBoolean(true); this.messagingConnector = messagingConnector; - this.syncedProjects = new ConcurrentHashMap(); this.repositoryListeners = new ConcurrentLinkedDeque<>(); From bfc21355e6875355f8cd7e1d6d54f7391b4faad2 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Tue, 21 Jun 2016 07:51:28 +0300 Subject: [PATCH 03/34] Changed implementation Signed-off-by: Fjodor Vershinin --- .../src/org/eclipse/flux/core/Repository.java | 260 +----------------- 1 file changed, 10 insertions(+), 250 deletions(-) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java index 2525a4f..dbfb6a2 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java @@ -22,7 +22,6 @@ import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.IOUtils; -import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; @@ -30,21 +29,19 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.IResourceVisitor; -import org.eclipse.core.runtime.CoreException; import org.eclipse.flux.client.CallbackIDAwareMessageHandler; import org.eclipse.flux.client.IMessageHandler; import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageHandler; import org.eclipse.flux.watcher.core.FluxMessageBus; import org.eclipse.flux.watcher.core.RepositoryModule; +import org.eclipse.flux.watcher.core.spi.Project; import org.eclipse.flux.watcher.fs.JDKProjectModule; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.json.JSONArray; -import org.json.JSONException; import org.json.JSONObject; import com.google.inject.Guice; @@ -108,33 +105,6 @@ public void handle(String messageType, JSONObject message) { }; this.messagingConnector.addMessageHandler(resourceDeletedHandler); this.messageHandlers.add(resourceDeletedHandler); - - IMessageHandler getProjectsRequestHandler = new MessageHandler("getProjectsRequest") { - @Override - public void handle(String messageType, JSONObject message) { - getProjects(message); - } - }; - this.messagingConnector.addMessageHandler(getProjectsRequestHandler); - this.messageHandlers.add(getProjectsRequestHandler); - - IMessageHandler getProjectRequestHandler = new MessageHandler("getProjectRequest") { - @Override - public void handle(String messageType, JSONObject message) { - getProject(message); - } - }; - this.messagingConnector.addMessageHandler(getProjectRequestHandler); - this.messageHandlers.add(getProjectRequestHandler); - - IMessageHandler getProjectResponseHandler = new CallbackIDAwareMessageHandler("getProjectResponse", Repository.GET_PROJECT_CALLBACK) { - @Override - public void handle(String messageType, JSONObject message) { - getProjectResponse(message); - } - }; - this.messagingConnector.addMessageHandler(getProjectResponseHandler); - this.messageHandlers.add(getProjectResponseHandler); IMessageHandler getResourceRequestHandler = new MessageHandler("getResourceRequest") { @Override @@ -179,13 +149,6 @@ public String getUsername() { return this.username; } - protected void connect() { - for (String projectName : syncedProjects.keySet()) { - sendProjectConnectedMessage(projectName); - syncConnectedProject(projectName); - } - } - public ConnectedProject getProject(IProject project) { return getProject(project.getName()); } @@ -195,40 +158,25 @@ public ConnectedProject getProject(String projectName) { } public boolean isConnected(IProject project) { - return this.syncedProjects.containsKey(project.getName()); + return isConnected(project.getName()); } - public boolean isConnected(String project) { - return this.syncedProjects.containsKey(project); + public boolean isConnected(String projectName) { + Project project = this.repository.getProject(projectName); + return this.repository.getSynchronizedProjects().contains(project); } public void addProject(IProject project) { - String projectName = project.getName(); - if (!this.syncedProjects.containsKey(projectName)) { - this.syncedProjects.put(projectName, new ConnectedProject(project)); - notifyProjectConnected(project); - sendProjectConnectedMessage(projectName); - syncConnectedProject(projectName); - } + this.repository.addProject(project.getName(), project.getLocationURI().getPath()); + notifyProjectConnected(project); } public void removeProject(IProject project) { - String projectName = project.getName(); - if (this.syncedProjects.containsKey(projectName)) { - this.syncedProjects.remove(projectName); - notifyProjectDisonnected(project); - try { - JSONObject message = new JSONObject(); - message.put("username", this.username); - message.put("project", projectName); - messagingConnector.send("projectDisconnected", message); - } catch (Exception e) { - e.printStackTrace(); - } - } + this.repository.removeProject(project.getName()); + notifyProjectDisonnected(project); } - protected void syncConnectedProject(String projectName) { + protected void syncConnectedProjects(String projectName) { try { JSONObject message = new JSONObject(); message.put("username", this.username); @@ -240,199 +188,11 @@ protected void syncConnectedProject(String projectName) { e.printStackTrace(); } } - - protected void sendProjectConnectedMessage(String projectName) { - try { - JSONObject message = new JSONObject(); - message.put("username", this.username); - message.put("project", projectName); - messagingConnector.send("projectConnected", message); - } catch (Exception e) { - e.printStackTrace(); - } - } public ConnectedProject[] getConnectedProjects() { return syncedProjects.values().toArray( new ConnectedProject[syncedProjects.size()]); } - - public void getProjects(JSONObject request) { - try { - int callbackID = getIntMaybe(request, "callback_id"); - String sender = request.getString("requestSenderID"); - String username = request.getString("username"); - - if (this.username.equals(username)) { - JSONArray projects = new JSONArray(); - for (String projectName : this.syncedProjects.keySet()) { - JSONObject proj = new JSONObject(); - proj.put("name", projectName); - projects.put(proj); - } - - JSONObject message = new JSONObject(); - message.put("callback_id", callbackID); - message.put("requestSenderID", sender); - message.put("username", this.username); - message.put("projects", projects); - - messagingConnector.send("getProjectsResponse", message); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - private int getIntMaybe(JSONObject request, String prop) throws JSONException { - if (request.has(prop)) { - return request.getInt(prop); - } - return 0; - } - - public void getProject(JSONObject request) { - try { - final int callbackID = request.getInt("callback_id"); - final String sender = request.getString("requestSenderID"); - final String projectName = request.getString("project"); - final String username = request.getString("username"); - - final ConnectedProject connectedProject = this.syncedProjects.get(projectName); - if (this.username.equals(username) && connectedProject != null) { - - final JSONArray files = new JSONArray(); - - IProject project = connectedProject.getProject(); - - try { - project.accept(new IResourceVisitor() { - @Override - public boolean visit(IResource resource) throws CoreException { - JSONObject projectResource = new JSONObject(); - String path = resource.getProjectRelativePath().toString(); - try { - projectResource.put("path", path); - projectResource.put("timestamp", connectedProject.getTimestamp(path)); - projectResource.put("hash", connectedProject.getHash(path)); - - if (resource instanceof IFile) { - projectResource.put("type", "file"); - } else if (resource instanceof IFolder) { - projectResource.put("type", "folder"); - } - - files.put(projectResource); - } catch (JSONException e) { - e.printStackTrace(); - } - return true; - } - }, IResource.DEPTH_INFINITE, IContainer.EXCLUDE_DERIVED); - } catch (Exception e) { - e.printStackTrace(); - } - - JSONObject message = new JSONObject(); - message.put("callback_id", callbackID); - message.put("requestSenderID", sender); - message.put("username", this.username); - message.put("project", projectName); - message.put("username", this.username); - message.put("files", files); - - messagingConnector.send("getProjectResponse", message); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void getProjectResponse(JSONObject response) { - try { - final String username = response.getString("username"); - final String projectName = response.getString("project"); - final JSONArray files = response.getJSONArray("files"); - final JSONArray deleted = response.optJSONArray("deleted"); - - ConnectedProject connectedProject = this.syncedProjects.get(projectName); - if (this.username.equals(username) && connectedProject != null) { - - for (int i = 0; i < files.length(); i++) { - JSONObject resource = files.getJSONObject(i); - - String resourcePath = resource.getString("path"); - long timestamp = resource.getLong("timestamp"); - - String type = resource.optString("type"); - String hash = resource.optString("hash"); - - boolean newFile = type != null && type.equals("file") && !connectedProject.containsResource(resourcePath); - boolean updatedFileTimestamp = type != null && type.equals("file") && connectedProject.containsResource(resourcePath) - && connectedProject.getHash(resourcePath).equals(hash) && connectedProject.getTimestamp(resourcePath) < timestamp; - boolean updatedFile = type != null && type.equals("file") && connectedProject.containsResource(resourcePath) - && !connectedProject.getHash(resourcePath).equals(hash) && connectedProject.getTimestamp(resourcePath) < timestamp; - - if (newFile || updatedFile) { - JSONObject message = new JSONObject(); - message.put("callback_id", GET_RESOURCE_CALLBACK); - message.put("project", projectName); - message.put("username", this.username); - message.put("resource", resourcePath); - message.put("timestamp", timestamp); - message.put("hash", hash); - - messagingConnector.send("getResourceRequest", message); - } - - if (updatedFileTimestamp) { - connectedProject.setTimestamp(resourcePath, timestamp); - IResource file = connectedProject.getProject().findMember(resourcePath); - file.setLocalTimeStamp(timestamp); - } - - boolean newFolder = type != null && type.equals("folder") && !connectedProject.containsResource(resourcePath); - boolean updatedFolder = type != null && type.equals("folder") && connectedProject.containsResource(resourcePath) - && !(connectedProject.getHash(resourcePath) == null || connectedProject.getHash(resourcePath).equals(hash)) && connectedProject.getTimestamp(resourcePath) < timestamp; - - if (newFolder) { - IProject project = connectedProject.getProject(); - IFolder folder = project.getFolder(resourcePath); - - connectedProject.setHash(resourcePath, hash); - connectedProject.setTimestamp(resourcePath, timestamp); - - folder.create(true, true, null); - folder.setLocalTimeStamp(timestamp); - } - else if (updatedFolder) { - } - } - - if (deleted != null) { - for (int i = 0; i < deleted.length(); i++) { - JSONObject deletedResource = deleted.getJSONObject(i); - - String resourcePath = deletedResource.getString("path"); - long deletedTimestamp = deletedResource.getLong("timestamp"); - - IProject project = connectedProject.getProject(); - IResource resource = project.findMember(resourcePath); - - if (resource != null && resource.exists() && (resource instanceof IFile || resource instanceof IFolder)) { - long localTimestamp = connectedProject.getTimestamp(resourcePath); - - if (localTimestamp < deletedTimestamp) { - resource.delete(true, null); - } - } - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } public void getResource(JSONObject request) { try { From 7c911483ec92512ef9a6a8e7ed1d66ce5aa3dd69 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Tue, 21 Jun 2016 08:41:10 +0300 Subject: [PATCH 04/34] Check if a thread is already started or not Signed-off-by: Fjodor Vershinin --- .../src/org/eclipse/flux/watcher/fs/JDKProject.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProject.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProject.java index 45f6d92..2cf88c2 100644 --- a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProject.java +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProject.java @@ -77,7 +77,7 @@ public class JDKProject implements Project { checkArgument(exists(this.path) && isDirectory(this.path) && this.path.isAbsolute()); // start the watch service - this.watchService.start(); + if(!this.watchService.isAlive()) this.watchService.start(); } @Override From 82275246a795f119a177c81bea823281ec8687ed Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Tue, 21 Jun 2016 09:50:52 +0300 Subject: [PATCH 05/34] Cleanup: obsolete methods Signed-off-by: Fjodor Vershinin --- .../src/org/eclipse/flux/core/Activator.java | 6 - .../src/org/eclipse/flux/core/Repository.java | 510 ------------------ .../internal/CloudSyncResourceListener.java | 46 -- 3 files changed, 562 deletions(-) delete mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/internal/CloudSyncResourceListener.java diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java index 661e380..3c109ef 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java @@ -35,7 +35,6 @@ import org.eclipse.flux.client.MessageConstants; import org.eclipse.flux.client.config.SocketIOFluxConfig; import org.eclipse.flux.core.internal.CloudSyncMetadataListener; -import org.eclipse.flux.core.internal.CloudSyncResourceListener; import org.eclipse.flux.core.util.ExceptionUtil; import org.osgi.framework.BundleContext; import org.osgi.service.prefs.BackingStoreException; @@ -61,7 +60,6 @@ public class Activator extends Plugin { private LiveEditCoordinator liveEditCoordinator; private boolean lazyStart = false; - private CloudSyncResourceListener resourceListener; private CloudSyncMetadataListener metadataListener; private IRepositoryListener repositoryListener; private IResourceChangeListener workspaceListener; @@ -170,9 +168,6 @@ private void initCoreService(String userChannel) throws CoreException { IWorkspace workspace = ResourcesPlugin.getWorkspace(); - resourceListener = new CloudSyncResourceListener(repository); - workspace.addResourceChangeListener(resourceListener, IResourceChangeEvent.POST_CHANGE); - metadataListener = new CloudSyncMetadataListener(repository); workspace.addResourceChangeListener(metadataListener, IResourceChangeEvent.POST_BUILD); @@ -225,7 +220,6 @@ private void disposeCoreServices(String userChannel) { if (userChannel.equals(repository.getUsername())) { IWorkspace workspace = ResourcesPlugin.getWorkspace(); workspace.removeResourceChangeListener(workspaceListener); - workspace.removeResourceChangeListener(resourceListener); workspace.removeResourceChangeListener(metadataListener); repository.removeRepositoryListener(repositoryListener); liveEditCoordinator.dispose(); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java index dbfb6a2..ca956c2 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java @@ -10,9 +10,6 @@ *******************************************************************************/ package org.eclipse.flux.core; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; @@ -20,16 +17,11 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.io.IOUtils; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.flux.client.CallbackIDAwareMessageHandler; import org.eclipse.flux.client.IMessageHandler; import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageHandler; @@ -37,10 +29,6 @@ import org.eclipse.flux.watcher.core.RepositoryModule; import org.eclipse.flux.watcher.core.spi.Project; import org.eclipse.flux.watcher.fs.JDKProjectModule; -import org.eclipse.jdt.core.IClassFile; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.JavaCore; import org.json.JSONArray; import org.json.JSONObject; @@ -59,9 +47,6 @@ public class Repository { private ConcurrentMap syncedProjects; private Collection repositoryListeners; - private static int GET_PROJECT_CALLBACK = "Repository - getProjectCallback".hashCode(); - private static int GET_RESOURCE_CALLBACK = "Repository - getResourceCallback".hashCode(); - private AtomicBoolean connected; private org.eclipse.flux.watcher.core.Repository repository; @@ -79,62 +64,6 @@ public Repository(MessageConnector messagingConnector, String user) { this.messageHandlers = new ArrayList(9); - IMessageHandler resourceChangedHandler = new MessageHandler("resourceChanged") { - @Override - public void handle(String messageType, JSONObject message) { - updateResource(message); - } - }; - this.messagingConnector.addMessageHandler(resourceChangedHandler); - messageHandlers.add(resourceChangedHandler); - - IMessageHandler resourceCreatedHandler = new MessageHandler("resourceCreated") { - @Override - public void handle(String messageType, JSONObject message) { - createResource(message); - } - }; - this.messagingConnector.addMessageHandler(resourceCreatedHandler); - this.messageHandlers.add(resourceCreatedHandler); - - IMessageHandler resourceDeletedHandler = new MessageHandler("resourceDeleted") { - @Override - public void handle(String messageType, JSONObject message) { - deleteResource(message); - } - }; - this.messagingConnector.addMessageHandler(resourceDeletedHandler); - this.messageHandlers.add(resourceDeletedHandler); - - IMessageHandler getResourceRequestHandler = new MessageHandler("getResourceRequest") { - @Override - public void handle(String messageType, JSONObject message) { - try { - final String resourcePath = message.getString("resource"); - - if (resourcePath.startsWith("classpath:")) { - getClasspathResource(message); - } - else { - getResource(message); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - }; - this.messagingConnector.addMessageHandler(getResourceRequestHandler); - this.messageHandlers.add(getResourceRequestHandler); - - IMessageHandler getResourceResponseHandler = new CallbackIDAwareMessageHandler("getResourceResponse", Repository.GET_RESOURCE_CALLBACK) { - @Override - public void handle(String messageType, JSONObject message) { - getResourceResponse(message); - } - }; - this.messagingConnector.addMessageHandler(getResourceResponseHandler); - this.messageHandlers.add(getResourceResponseHandler); - IMessageHandler getMetadataRequestHandler = new MessageHandler("getMetadataRequest") { @Override public void handle(String messageType, JSONObject message) { @@ -175,309 +104,12 @@ public void removeProject(IProject project) { this.repository.removeProject(project.getName()); notifyProjectDisonnected(project); } - - protected void syncConnectedProjects(String projectName) { - try { - JSONObject message = new JSONObject(); - message.put("username", this.username); - message.put("project", projectName); - message.put("includeDeleted", true); - message.put("callback_id", GET_PROJECT_CALLBACK); - messagingConnector.send("getProjectRequest", message); - } catch (Exception e) { - e.printStackTrace(); - } - } public ConnectedProject[] getConnectedProjects() { return syncedProjects.values().toArray( new ConnectedProject[syncedProjects.size()]); } - public void getResource(JSONObject request) { - try { - final String username = request.getString("username"); - final int callbackID = request.getInt("callback_id"); - final String sender = request.getString("requestSenderID"); - final String projectName = request.getString("project"); - final String resourcePath = request.getString("resource"); - - ConnectedProject connectedProject = this.syncedProjects.get(projectName); - if (this.username.equals(username) && connectedProject != null && connectedProject.containsResource(resourcePath)) { - IProject project = connectedProject.getProject(); - - if (request.has("timestamp") && request.getLong("timestamp") != connectedProject.getTimestamp(resourcePath)) { - return; - } - - IResource resource = project.findMember(resourcePath); - - JSONObject message = new JSONObject(); - message.put("callback_id", callbackID); - message.put("requestSenderID", sender); - message.put("username", this.username); - message.put("project", projectName); - message.put("resource", resourcePath); - message.put("timestamp", connectedProject.getTimestamp(resourcePath)); - message.put("hash", connectedProject.getHash(resourcePath)); - - if (resource instanceof IFile) { - if (request.has("hash") && !request.getString("hash").equals(connectedProject.getHash(resourcePath))) { - return; - } - - IFile file = (IFile) resource; - - ByteArrayOutputStream array = new ByteArrayOutputStream(); - if (!file.isSynchronized(IResource.DEPTH_ZERO)) { - file.refreshLocal(IResource.DEPTH_ZERO, null); - } - - IOUtils.copy(file.getContents(), array); - - String content = new String(array.toByteArray(), file.getCharset()); - - message.put("content", content); - message.put("type", "file"); - } else if (resource instanceof IFolder) { - message.put("type", "folder"); - } - - messagingConnector.send("getResourceResponse", message); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void getClasspathResource(JSONObject request) { - try { - final int callbackID = request.getInt("callback_id"); - final String sender = request.getString("requestSenderID"); - final String projectName = request.getString("project"); - final String resourcePath = request.getString("resource"); - final String username = request.getString("username"); - - ConnectedProject connectedProject = this.syncedProjects.get(projectName); - if (this.username.equals(username) && connectedProject != null) { - String typeName = resourcePath.substring("classpath:/".length()); - if (typeName.endsWith(".class")) { - typeName = typeName.substring(0, typeName.length() - ".class".length()); - } - typeName = typeName.replace('/', '.'); - - IJavaProject javaProject = JavaCore.create(connectedProject.getProject()); - if (javaProject != null) { - IType type = javaProject.findType(typeName); - IClassFile classFile = type.getClassFile(); - if (classFile != null && classFile.getSourceRange() != null) { - - JSONObject message = new JSONObject(); - message.put("callback_id", callbackID); - message.put("requestSenderID", sender); - message.put("username", this.username); - message.put("project", projectName); - message.put("resource", resourcePath); - message.put("readonly", true); - - String content = classFile.getSource(); - - message.put("content", content); - message.put("type", "file"); - - messagingConnector.send("getResourceResponse", message); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void updateResource(JSONObject request) { - try { - final String username = request.getString("username"); - final String projectName = request.getString("project"); - final String resourcePath = request.getString("resource"); - final long updateTimestamp = request.getLong("timestamp"); - final String updateHash = request.optString("hash"); - - ConnectedProject connectedProject = this.syncedProjects.get(projectName); - if (this.username.equals(username) && connectedProject != null) { - IProject project = connectedProject.getProject(); - IResource resource = project.findMember(resourcePath); - - if (resource != null && resource instanceof IFile) { - String localHash = connectedProject.getHash(resourcePath); - long localTimestamp = connectedProject.getTimestamp(resourcePath); - - if (localHash != null && !localHash.equals(updateHash) && localTimestamp < updateTimestamp) { - JSONObject message = new JSONObject(); - message.put("callback_id", GET_RESOURCE_CALLBACK); - message.put("username", this.username); - message.put("project", projectName); - message.put("resource", resourcePath); - message.put("timestamp", updateTimestamp); - message.put("hash", updateHash); - - messagingConnector.send("getResourceRequest", message); - notifyResourceChanged(resource); - } - } - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void createResource(JSONObject request) { - try { - final String username = request.getString("username"); - final String projectName = request.getString("project"); - final String resourcePath = request.getString("resource"); - final long updateTimestamp = request.getLong("timestamp"); - final String updateHash = request.optString("hash"); - final String type = request.optString("type"); - - ConnectedProject connectedProject = this.syncedProjects.get(projectName); - if (this.username.equals(username) && connectedProject != null) { - IProject project = connectedProject.getProject(); - IResource resource = project.findMember(resourcePath); - - if (resource == null) { - if ("folder".equals(type)) { - IFolder newFolder = project.getFolder(resourcePath); - - connectedProject.setHash(resourcePath, updateHash); - connectedProject.setTimestamp(resourcePath, updateTimestamp); - - newFolder.create(true, true, null); - newFolder.setLocalTimeStamp(updateTimestamp); - - JSONObject message = new JSONObject(); - message.put("username", this.username); - message.put("project", projectName); - message.put("resource", resourcePath); - message.put("timestamp", updateTimestamp); - message.put("hash", updateHash); - message.put("type", type); - - messagingConnector.send("resourceStored", message); - } - else if ("file".equals(type)) { - JSONObject message = new JSONObject(); - message.put("callback_id", GET_RESOURCE_CALLBACK); - message.put("username", this.username); - message.put("project", projectName); - message.put("resource", resourcePath); - message.put("timestamp", updateTimestamp); - message.put("hash", updateHash); - message.put("type", type); - - messagingConnector.send("getResourceRequest", message); - } - } - else { - // TODO - } - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void deleteResource(JSONObject request) { - try { - final String username = request.getString("username"); - final String projectName = request.getString("project"); - final String resourcePath = request.getString("resource"); - final long deletedTimestamp = request.getLong("timestamp"); - - ConnectedProject connectedProject = this.syncedProjects.get(projectName); - if (this.username.equals(username) && connectedProject != null) { - IProject project = connectedProject.getProject(); - IResource resource = project.findMember(resourcePath); - - if (resource != null && resource.exists() && (resource instanceof IFile || resource instanceof IFolder)) { - long localTimestamp = connectedProject.getTimestamp(resourcePath); - - if (localTimestamp < deletedTimestamp) { - resource.delete(true, null); - } - } - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void getResourceResponse(JSONObject response) { - try { - final String username = response.getString("username"); - final String projectName = response.getString("project"); - final String resourcePath = response.getString("resource"); - final long updateTimestamp = response.getLong("timestamp"); - final String updateHash = response.getString("hash"); - - ConnectedProject connectedProject = this.syncedProjects.get(projectName); - if (this.username.equals(username) && connectedProject != null) { - boolean stored = false; - - IProject project = connectedProject.getProject(); - IResource resource = project.findMember(resourcePath); - - if (resource != null) { - if (resource instanceof IFile) { - String localHash = connectedProject.getHash(resourcePath); - long localTimestamp = connectedProject.getTimestamp(resourcePath); - - if (localHash != null && !localHash.equals(updateHash) && localTimestamp < updateTimestamp) { - IFile file = (IFile) resource; - String newResourceContent = response.getString("content"); - - connectedProject.setTimestamp(resourcePath, updateTimestamp); - connectedProject.setHash(resourcePath, updateHash); - - file.setContents(new ByteArrayInputStream(newResourceContent.getBytes()), true, true, null); - file.setLocalTimeStamp(updateTimestamp); - stored = true; - } - } - } - else { - IFile newFile = project.getFile(resourcePath); - String newResourceContent = response.getString("content"); - - connectedProject.setHash(resourcePath, updateHash); - connectedProject.setTimestamp(resourcePath, updateTimestamp); - - newFile.create(new ByteArrayInputStream(newResourceContent.getBytes()), true, null); - newFile.setLocalTimeStamp(updateTimestamp); - stored = true; - } - - if (stored) { - JSONObject message = new JSONObject(); - message.put("username", this.username); - message.put("project", connectedProject.getName()); - message.put("resource", resourcePath); - message.put("timestamp", updateTimestamp); - message.put("hash", updateHash); - message.put("type", "file"); - messagingConnector.send("resourceStored", message); - if (resource != null) { - notifyResourceChanged(resource); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - public void getMetadata(JSONObject request) { try { final String username = request.getString("username"); @@ -511,15 +143,6 @@ public void getMetadata(JSONObject request) { } } - public void resourceChanged(IResourceDelta delta) { - IProject project = delta.getResource().getProject(); - if (project != null) { - if (isConnected(project)) { - reactToResourceChange(delta); - } - } - } - public void metadataChanged(IResourceDelta delta) { IProject project = delta.getResource().getProject(); IMarkerDelta[] markerDeltas = delta.getMarkerDeltas(); @@ -528,139 +151,6 @@ public void metadataChanged(IResourceDelta delta) { } } - public void reactToResourceChange(IResourceDelta delta) { - IResource resource = delta.getResource(); - - if (resource != null && resource.isDerived(IResource.CHECK_ANCESTORS)) { - return; - } - - switch (delta.getKind()) { - case IResourceDelta.ADDED: - reactOnResourceAdded(resource); - break; - case IResourceDelta.REMOVED: - reactOnResourceRemoved(resource); - break; - case IResourceDelta.CHANGED: - reactOnResourceChange(resource); - break; - } - } - - protected void reactOnResourceAdded(IResource resource) { - try { - ConnectedProject connectedProject = this.syncedProjects.get(resource.getProject().getName()); - - String resourcePath = resource.getProjectRelativePath().toString(); - long timestamp = resource.getLocalTimeStamp(); - String hash = "0"; - String type = null; - - connectedProject.setTimestamp(resourcePath, timestamp); - - if (resource instanceof IFile) { - try { - IFile file = (IFile) resource; - hash = DigestUtils.shaHex(file.getContents()); - type = "file"; - } catch (IOException e) { - e.printStackTrace(); - } - } else if (resource instanceof IFolder) { - type = "folder"; - } - - connectedProject.setHash(resourcePath, hash); - - JSONObject createdMessage = new JSONObject(); - createdMessage.put("username", this.username); - createdMessage.put("project", connectedProject.getName()); - createdMessage.put("resource", resourcePath); - createdMessage.put("timestamp", timestamp); - createdMessage.put("hash", hash); - createdMessage.put("type", type); - messagingConnector.send("resourceCreated", createdMessage); - - JSONObject storedMessage = new JSONObject(); - storedMessage.put("username", this.username); - storedMessage.put("project", connectedProject.getName()); - storedMessage.put("resource", resourcePath); - storedMessage.put("timestamp", timestamp); - storedMessage.put("hash", hash); - storedMessage.put("type", type); - messagingConnector.send("resourceStored", storedMessage); - - } catch (Exception e) { - e.printStackTrace(); - } - } - - protected void reactOnResourceRemoved(IResource resource) { - if (resource instanceof IProject) { - this.removeProject((IProject) resource); - } - else if (!resource.isDerived() && (resource instanceof IFile || resource instanceof IFolder)) { - ConnectedProject connectedProject = this.syncedProjects.get(resource.getProject().getName()); - String resourcePath = resource.getProjectRelativePath().toString(); - long deletedTimestamp = System.currentTimeMillis(); - - try { - JSONObject message = new JSONObject(); - message.put("username", this.username); - message.put("project", connectedProject.getName()); - message.put("resource", resourcePath); - message.put("timestamp", deletedTimestamp); - - messagingConnector.send("resourceDeleted", message); - } - catch (Exception e) { - e.printStackTrace(); - } - } - } - - protected void reactOnResourceChange(IResource resource) { - if (resource != null && resource instanceof IFile) { - IFile file = (IFile) resource; - - ConnectedProject connectedProject = this.syncedProjects.get(file.getProject().getName()); - String resourcePath = resource.getProjectRelativePath().toString(); - - try { - - long changeTimestamp = file.getLocalTimeStamp(); - if (changeTimestamp > connectedProject.getTimestamp(resourcePath)) { - String changeHash = DigestUtils.shaHex(file.getContents()); - if (!changeHash.equals(connectedProject.getHash(resourcePath))) { - - connectedProject.setTimestamp(resourcePath, changeTimestamp); - connectedProject.setHash(resourcePath, changeHash); - - JSONObject changedMessage = new JSONObject(); - changedMessage.put("username", this.username); - changedMessage.put("project", connectedProject.getName()); - changedMessage.put("resource", resourcePath); - changedMessage.put("timestamp", changeTimestamp); - changedMessage.put("hash", changeHash); - messagingConnector.send("resourceChanged", changedMessage); - - JSONObject storedMessage = new JSONObject(); - storedMessage.put("username", this.username); - storedMessage.put("project", connectedProject.getName()); - storedMessage.put("resource", resourcePath); - storedMessage.put("timestamp", changeTimestamp); - storedMessage.put("hash", changeHash); - messagingConnector.send("resourceStored", storedMessage); - - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - public void sendMetadataUpdate(IResource resource) { try { String project = resource.getProject().getName(); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/internal/CloudSyncResourceListener.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/internal/CloudSyncResourceListener.java deleted file mode 100644 index 3b0bd88..0000000 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/internal/CloudSyncResourceListener.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2014 Pivotal Software, Inc. and others. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 - * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution - * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). - * - * Contributors: - * Pivotal Software, Inc. - initial API and implementation -*******************************************************************************/ -package org.eclipse.flux.core.internal; - -import org.eclipse.core.resources.IResourceChangeEvent; -import org.eclipse.core.resources.IResourceChangeListener; -import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.IResourceDeltaVisitor; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.flux.core.Repository; - -/** - * @author Martin Lippert - */ -public class CloudSyncResourceListener implements IResourceChangeListener { - - private Repository repository; - - public CloudSyncResourceListener(Repository repository) { - this.repository = repository; - } - - @Override - public void resourceChanged(IResourceChangeEvent event) { - try { - event.getDelta().accept(new IResourceDeltaVisitor() { - @Override - public boolean visit(IResourceDelta delta) throws CoreException { - repository.resourceChanged(delta); - return true; - } - }); - } catch (CoreException e) { - e.printStackTrace(); - } - } - -} From 85a6c74c9b4e33275ab97bb7c53eeb4b6bc52952 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Wed, 22 Jun 2016 07:43:04 +0300 Subject: [PATCH 06/34] =?UTF-8?q?=D0=A1onnection=20through=20flux-watcher?= =?UTF-8?q?=20library?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fjodor Vershinin --- .../src/org/eclipse/flux/core/Activator.java | 14 +++++++++++++- .../src/org/eclipse/flux/core/Repository.java | 13 ++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java index 3c109ef..ed5a794 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.flux.core; +import java.net.URL; import java.util.Collection; import java.util.HashSet; import java.util.concurrent.Executors; @@ -36,9 +37,15 @@ import org.eclipse.flux.client.config.SocketIOFluxConfig; import org.eclipse.flux.core.internal.CloudSyncMetadataListener; import org.eclipse.flux.core.util.ExceptionUtil; +import org.eclipse.flux.watcher.core.Credentials; +import org.eclipse.flux.watcher.core.RepositoryModule; +import org.eclipse.flux.watcher.fs.JDKProjectModule; import org.osgi.framework.BundleContext; import org.osgi.service.prefs.BackingStoreException; +import com.google.inject.Guice; +import com.google.inject.Injector; + /** * @author Martin Lippert * @author Miles Parker @@ -64,6 +71,8 @@ public class Activator extends Plugin { private IRepositoryListener repositoryListener; private IResourceChangeListener workspaceListener; + private org.eclipse.flux.watcher.core.Repository fluxRepository; + private final IChannelListener SERVICE_STARTER = new IChannelListener() { @Override public void connected(String userChannel) { @@ -107,6 +116,9 @@ public void start(BundleContext context) throws Exception { final String userChannel = lazyStart ? MessageConstants.SUPER_USER : channel; + Injector injector = Guice.createInjector(new RepositoryModule(), new JDKProjectModule()); + fluxRepository = injector.getInstance(org.eclipse.flux.watcher.core.Repository.class); + fluxRepository.addRemote(new URL(host), new Credentials(login, token)); //Connecting to channel done asynchronously. To avoid blocking plugin state initialization. FluxClient.DEFAULT_INSTANCE.getExecutor().execute(new Runnable() { @Override @@ -163,7 +175,7 @@ public void stop(BundleContext context) throws Exception { } private void initCoreService(String userChannel) throws CoreException { - repository = new Repository(messageConnector, userChannel); + repository = new Repository(messageConnector, fluxRepository, userChannel); liveEditCoordinator = new LiveEditCoordinator(messageConnector); IWorkspace workspace = ResourcesPlugin.getWorkspace(); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java index ca956c2..bdc87eb 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java @@ -25,16 +25,10 @@ import org.eclipse.flux.client.IMessageHandler; import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageBus; -import org.eclipse.flux.watcher.core.RepositoryModule; import org.eclipse.flux.watcher.core.spi.Project; -import org.eclipse.flux.watcher.fs.JDKProjectModule; import org.json.JSONArray; import org.json.JSONObject; -import com.google.inject.Guice; -import com.google.inject.Injector; - /** * @author Martin Lippert */ @@ -50,13 +44,10 @@ public class Repository { private AtomicBoolean connected; private org.eclipse.flux.watcher.core.Repository repository; - private FluxMessageBus messageBus; - public Repository(MessageConnector messagingConnector, String user) { - Injector injector = Guice.createInjector(new RepositoryModule(), new JDKProjectModule()); + public Repository(MessageConnector messagingConnector, org.eclipse.flux.watcher.core.Repository fluxRepository, String user) { + this.repository = fluxRepository; this.username = user; - this.repository = injector.getInstance(org.eclipse.flux.watcher.core.Repository.class); - this.messageBus = injector.getInstance(FluxMessageBus.class); this.connected = new AtomicBoolean(true); this.messagingConnector = messagingConnector; this.syncedProjects = new ConcurrentHashMap(); From 8b8b371167b8216d90ac99d83d52aade79f48a7e Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Thu, 11 Aug 2016 13:26:25 +0300 Subject: [PATCH 07/34] Fixed bug when the editor of eclipse cant do local update Signed-off-by: Fjodor Vershinin --- .../src/org/eclipse/flux/core/Repository.java | 3 ++ .../flux/core/listeners/ResourceListener.java | 32 +++++++++++++++++++ .../eclipse/flux/watcher/core/Repository.java | 3 ++ 3 files changed, 38 insertions(+) create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceListener.java diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java index bdc87eb..d80298c 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java @@ -25,6 +25,7 @@ import org.eclipse.flux.client.IMessageHandler; import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageHandler; +import org.eclipse.flux.core.listeners.ResourceListener; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; import org.json.JSONObject; @@ -63,6 +64,8 @@ public void handle(String messageType, JSONObject message) { }; this.messagingConnector.addMessageHandler(getMetadataRequestHandler); this.messageHandlers.add(getMetadataRequestHandler); + + fluxRepository.getMessageBus().addMessageHandler(new ResourceListener()); } public String getUsername() { diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceListener.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceListener.java new file mode 100644 index 0000000..409d278 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceListener.java @@ -0,0 +1,32 @@ +package org.eclipse.flux.core.listeners; + +import java.io.ByteArrayOutputStream; +import java.text.MessageFormat; + +import org.apache.commons.io.IOUtils; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.Path; +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageType; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; + +import com.google.inject.Singleton; + +@Singleton +@FluxMessageTypes(FluxMessageType.GET_RESOURCE_RESPONSE) +public class ResourceListener implements FluxMessageHandler { + + @Override + public void onMessage(FluxMessage message, Repository repository) throws Exception { + final String resourcePath = message.content().getString("resource"); + final String project = message.content().getString("project"); + Path path = new Path(MessageFormat.format("{0}/{1}", project, resourcePath)); + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); + file.refreshLocal(IResource.DEPTH_ZERO, null); + } + +} diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Repository.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Repository.java index 22b522f..283d052 100644 --- a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Repository.java +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Repository.java @@ -194,5 +194,8 @@ public RepositoryEventBus repositoryEventBus() { return repositoryEventBus; } + public FluxMessageBus getMessageBus(){ + return messageBus; + } } From bbff9f1a585178d7b5f9dee4cebc10d9d5222498 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Sun, 14 Aug 2016 19:06:14 +0300 Subject: [PATCH 08/34] Changed mechanism of building/sending/receiving messages for Metadata Signed-off-by: Fjodor Vershinin --- .../src/org/eclipse/flux/core/Repository.java | 69 ++----------------- .../listeners/MetadataRequestHandler.java | 67 ++++++++++++++++++ .../flux/core/listeners/ResourceListener.java | 2 - .../flux/watcher/core/FluxMessageType.java | 5 +- 4 files changed, 78 insertions(+), 65 deletions(-) create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/MetadataRequestHandler.java diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java index d80298c..6d32fd9 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java @@ -10,22 +10,20 @@ *******************************************************************************/ package org.eclipse.flux.core; -import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; - import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.flux.client.IMessageHandler; import org.eclipse.flux.client.MessageConnector; -import org.eclipse.flux.client.MessageHandler; +import org.eclipse.flux.core.listeners.MetadataRequestHandler; import org.eclipse.flux.core.listeners.ResourceListener; +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageType; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; import org.json.JSONObject; @@ -36,36 +34,20 @@ public class Repository { private String username; - private MessageConnector messagingConnector; - private Collection messageHandlers; private ConcurrentMap syncedProjects; private Collection repositoryListeners; - - private AtomicBoolean connected; - + private org.eclipse.flux.watcher.core.Repository repository; public Repository(MessageConnector messagingConnector, org.eclipse.flux.watcher.core.Repository fluxRepository, String user) { this.repository = fluxRepository; this.username = user; - this.connected = new AtomicBoolean(true); - this.messagingConnector = messagingConnector; this.syncedProjects = new ConcurrentHashMap(); this.repositoryListeners = new ConcurrentLinkedDeque<>(); - - this.messageHandlers = new ArrayList(9); - - IMessageHandler getMetadataRequestHandler = new MessageHandler("getMetadataRequest") { - @Override - public void handle(String messageType, JSONObject message) { - getMetadata(message); - } - }; - this.messagingConnector.addMessageHandler(getMetadataRequestHandler); - this.messageHandlers.add(getMetadataRequestHandler); - + fluxRepository.getMessageBus().addMessageHandler(new ResourceListener()); + fluxRepository.getMessageBus().addMessageHandler(new MetadataRequestHandler()); } public String getUsername() { @@ -104,39 +86,6 @@ public ConnectedProject[] getConnectedProjects() { new ConnectedProject[syncedProjects.size()]); } - public void getMetadata(JSONObject request) { - try { - final String username = request.getString("username"); - final int callbackID = request.getInt("callback_id"); - final String sender = request.getString("requestSenderID"); - final String projectName = request.getString("project"); - final String resourcePath = request.getString("resource"); - - ConnectedProject connectedProject = this.syncedProjects.get(projectName); - if (this.username.equals(username) && connectedProject != null) { - IProject project = connectedProject.getProject(); - IResource resource = project.findMember(resourcePath); - - JSONObject message = new JSONObject(); - message.put("callback_id", callbackID); - message.put("requestSenderID", sender); - message.put("username", this.username); - message.put("project", projectName); - message.put("resource", resourcePath); - message.put("type", "marker"); - - IMarker[] markers = resource.findMarkers(null, true, IResource.DEPTH_INFINITE); - String markerJSON = toJSON(markers); - JSONArray content = new JSONArray(markerJSON); - message.put("metadata", content); - - messagingConnector.send("getMetadataResponse", message); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - public void metadataChanged(IResourceDelta delta) { IProject project = delta.getResource().getProject(); IMarkerDelta[] markerDeltas = delta.getMarkerDeltas(); @@ -161,7 +110,7 @@ public void sendMetadataUpdate(IResource resource) { JSONArray content = new JSONArray(markerJSON); message.put("metadata", content); - messagingConnector.send("metadataChanged", message); + repository.getMessageBus().sendMessages(new FluxMessage(FluxMessageType.METADATA_CHANGED, message)); } catch (Exception e) { } @@ -218,10 +167,6 @@ protected void notifyResourceChanged(IResource resource) { } public void dispose() { - connected.set(false); - for (IMessageHandler messageHandler : messageHandlers) { - messagingConnector.removeMessageHandler(messageHandler); - } syncedProjects.clear(); } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/MetadataRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/MetadataRequestHandler.java new file mode 100644 index 0000000..31af94a --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/MetadataRequestHandler.java @@ -0,0 +1,67 @@ +package org.eclipse.flux.core.listeners; + +import java.text.MessageFormat; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.Path; +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageType; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; +import org.json.JSONArray; +import org.json.JSONObject; + +import com.google.inject.Singleton; + +@Singleton +@FluxMessageTypes({FluxMessageType.GET_METADATA_REQUEST}) +public class MetadataRequestHandler implements FluxMessageHandler { + + @Override + public void onMessage(FluxMessage message, Repository repository) throws Exception { + JSONObject content = message.content(); + String projectName = message.content().getString("project"); + String resourcePath = message.content().getString("resource"); + Project project = repository.getProject(projectName); + if(project != null){ + Resource resource = project.getResource(resourcePath); + if(resource != null){ + Path path = new Path(MessageFormat.format("{0}/{1}", projectName, resourcePath)); + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); + content.put("type", "marker"); + content.put("metadata", new JSONArray(toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE)))); + message.source().sendMessage(new FluxMessage(FluxMessageType.GET_METADATA_RESPONSE, content)); + } + } + } + + private String toJSON(IMarker[] markers) { + StringBuilder result = new StringBuilder(); + boolean flag = false; + result.append("["); + for (IMarker m : markers) { + if (flag) { + result.append(","); + } + + result.append("{"); + result.append("\"description\":" + JSONObject.quote(m.getAttribute("message", ""))); + result.append(",\"line\":" + m.getAttribute("lineNumber", 0)); + result.append(",\"severity\":\"" + (m.getAttribute("severity", IMarker.SEVERITY_WARNING) == IMarker.SEVERITY_ERROR ? "error" : "warning") + + "\""); + result.append(",\"start\":" + m.getAttribute("charStart", 0)); + result.append(",\"end\":" + m.getAttribute("charEnd", 0)); + result.append("}"); + + flag = true; + } + result.append("]"); + return result.toString(); + } +} \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceListener.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceListener.java index 409d278..5772594 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceListener.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceListener.java @@ -1,9 +1,7 @@ package org.eclipse.flux.core.listeners; -import java.io.ByteArrayOutputStream; import java.text.MessageFormat; -import org.apache.commons.io.IOUtils; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageType.java b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageType.java index 7a31f3e..54bb533 100644 --- a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageType.java +++ b/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageType.java @@ -23,12 +23,15 @@ public enum FluxMessageType { GET_PROJECT_RESPONSE("getProjectResponse"), GET_RESOURCE_REQUEST("getResourceRequest"), GET_RESOURCE_RESPONSE("getResourceResponse"), + GET_METADATA_REQUEST("getMetadataRequest"), + GET_METADATA_RESPONSE("getMetadataResponse"), PROJECT_CONNECTED("projectConnected"), PROJECT_DISCONNECTED("projectDisconnected"), RESOURCE_CHANGED("resourceChanged"), RESOURCE_CREATED("resourceCreated"), RESOURCE_DELETED("resourceDeleted"), - RESOURCE_STORED("resourceStored"); + RESOURCE_STORED("resourceStored"), + METADATA_CHANGED("metadataChanged"); private final String value; From c6f5fec2fde9ef879e9eae9775720f186c014bf0 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Sun, 14 Aug 2016 08:03:05 +0300 Subject: [PATCH 09/34] Imported and integrated all tests from watcher library Signed-off-by: Fjodor Vershinin --- .../flux-eclipse-target.target | 18 +- org.eclipse.flux.watcher/META-INF/MANIFEST.MF | 4 +- org.eclipse.flux.watcher/build.properties | 2 +- .../flux/watcher/core/Credentials.java | 0 .../flux/watcher/core/FluxConnection.java | 0 .../flux/watcher/core/FluxMessage.java | 0 .../flux/watcher/core/FluxMessageBus.java | 0 .../flux/watcher/core/FluxMessageHandler.java | 0 .../flux/watcher/core/FluxMessageType.java | 0 .../flux/watcher/core/FluxMessageTypes.java | 0 .../eclipse/flux/watcher/core/Repository.java | 0 .../flux/watcher/core/RepositoryEvent.java | 0 .../flux/watcher/core/RepositoryEventBus.java | 0 .../watcher/core/RepositoryEventType.java | 0 .../watcher/core/RepositoryEventTypes.java | 0 .../flux/watcher/core/RepositoryListener.java | 0 .../flux/watcher/core/RepositoryModule.java | 0 .../eclipse/flux/watcher/core/Resource.java | 0 .../flux/watcher/core/internal/.gitignore | 0 .../internal/GetProjectRequestHandler.java | 0 .../internal/GetProjectResponseHandler.java | 0 .../internal/GetResourceRequestHandler.java | 0 .../internal/GetResourceResponseHandler.java | 0 .../ProjectResourceCreatedListener.java | 0 .../ProjectResourceDeletedListener.java | 0 .../ProjectResourceModifiedListener.java | 0 .../core/internal/ResourceChangedHandler.java | 0 .../core/internal/ResourceCreatedHandler.java | 0 .../core/internal/ResourceDeletedHandler.java | 0 .../flux/watcher/core/spi/Project.java | 0 .../flux/watcher/core/spi/ProjectFactory.java | 0 .../watcher/core/utils/ResourceHelper.java | 0 .../eclipse/flux/watcher/fs/JDKProject.java | 0 .../flux/watcher/fs/JDKProjectFactory.java | 0 .../flux/watcher/fs/JDKProjectModule.java | 0 .../watcher/fs/JDKProjectWatchService.java | 0 .../watcher/core/FluxMessageTypeTest.java | 41 ++ .../watcher/core/RepositoryEventBusTest.java | 156 +++++++ .../watcher/core/RepositoryEventTest.java | 40 ++ .../watcher/core/RepositoryModuleTest.java | 42 ++ .../flux/watcher/core/RepositoryTest.java | 169 ++++++++ .../flux/watcher/core/ResourceTest.java | 85 ++++ .../eclipse/flux/watcher/fs/AbstractTest.java | 75 ++++ .../watcher/fs/JDKProjectFactoryTest.java | 81 ++++ .../flux/watcher/fs/JDKProjectModuleTest.java | 33 ++ .../flux/watcher/fs/JDKProjectTest.java | 218 ++++++++++ .../fs/JDKProjectWatchServiceTest.java | 408 ++++++++++++++++++ .../watcher/fs/utils/ResourceHelperTest.java | 39 ++ 48 files changed, 1407 insertions(+), 4 deletions(-) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/Credentials.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/FluxConnection.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/FluxMessage.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/FluxMessageBus.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/FluxMessageHandler.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/FluxMessageType.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/FluxMessageTypes.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/Repository.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/RepositoryEvent.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/RepositoryEventBus.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/RepositoryEventType.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/RepositoryEventTypes.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/RepositoryListener.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/RepositoryModule.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/Resource.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/internal/.gitignore (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/spi/Project.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/spi/ProjectFactory.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/core/utils/ResourceHelper.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/fs/JDKProject.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/fs/JDKProjectFactory.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/fs/JDKProjectModule.java (100%) rename org.eclipse.flux.watcher/src/{ => main/java}/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java (100%) create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/FluxMessageTypeTest.java create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryEventBusTest.java create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryEventTest.java create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryModuleTest.java create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryTest.java create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/ResourceTest.java create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/AbstractTest.java create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectFactoryTest.java create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectModuleTest.java create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectTest.java create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectWatchServiceTest.java create mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/utils/ResourceHelperTest.java diff --git a/org.eclipse.flux.releng/flux-eclipse-target.target b/org.eclipse.flux.releng/flux-eclipse-target.target index 6fa2720..e227f03 100644 --- a/org.eclipse.flux.releng/flux-eclipse-target.target +++ b/org.eclipse.flux.releng/flux-eclipse-target.target @@ -1,12 +1,26 @@ - - + + + + + + + + + + + + + + + + diff --git a/org.eclipse.flux.watcher/META-INF/MANIFEST.MF b/org.eclipse.flux.watcher/META-INF/MANIFEST.MF index 60611a3..57f975f 100644 --- a/org.eclipse.flux.watcher/META-INF/MANIFEST.MF +++ b/org.eclipse.flux.watcher/META-INF/MANIFEST.MF @@ -4,7 +4,9 @@ Bundle-Name: Watch Bundle-SymbolicName: org.eclipse.flux.watcher Bundle-Version: 1.0.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Require-Bundle: org.eclipse.flux.client.java.osgi;bundle-version="1.0.0" +Require-Bundle: org.eclipse.flux.client.java.osgi;bundle-version="1.0.0", + org.mockito, + org.junit Import-Package: com.google.common.base, com.google.common.collect;version="15.0.0", com.google.inject;version="1.3.0", diff --git a/org.eclipse.flux.watcher/build.properties b/org.eclipse.flux.watcher/build.properties index 34d2e4d..3c54799 100644 --- a/org.eclipse.flux.watcher/build.properties +++ b/org.eclipse.flux.watcher/build.properties @@ -1,4 +1,4 @@ -source.. = src/ +source.. = src/main/java/, src/test/java output.. = bin/ bin.includes = META-INF/,\ . diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Credentials.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Credentials.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Credentials.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Credentials.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxConnection.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxConnection.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxConnection.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxConnection.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessage.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessage.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageBus.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageBus.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageBus.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageBus.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageHandler.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageHandler.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageHandler.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageType.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageType.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageType.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageType.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageTypes.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageTypes.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/FluxMessageTypes.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageTypes.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Repository.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Repository.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEvent.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEvent.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEvent.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEvent.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventBus.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEventBus.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventBus.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEventBus.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventType.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEventType.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventType.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEventType.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventTypes.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEventTypes.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryEventTypes.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEventTypes.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryListener.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryListener.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryListener.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryModule.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryModule.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/RepositoryModule.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryModule.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Resource.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Resource.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/Resource.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Resource.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/.gitignore b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/.gitignore similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/.gitignore rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/.gitignore diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/Project.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/spi/Project.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/Project.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/spi/Project.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/ProjectFactory.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/spi/ProjectFactory.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/spi/ProjectFactory.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/spi/ProjectFactory.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/utils/ResourceHelper.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/utils/ResourceHelper.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/core/utils/ResourceHelper.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/utils/ResourceHelper.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProject.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProject.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProject.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProject.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectFactory.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectFactory.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectFactory.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectFactory.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectModule.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectModule.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectModule.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectModule.java diff --git a/org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java similarity index 100% rename from org.eclipse.flux.watcher/src/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java rename to org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/FluxMessageTypeTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/FluxMessageTypeTest.java new file mode 100644 index 0000000..de59775 --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/FluxMessageTypeTest.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + + +import org.junit.Assert; +import org.junit.Test; + +import static org.eclipse.flux.watcher.core.FluxMessageType.CONNECT_TO_CHANNEL; + +/** + * {@link com.codenvy.flux.watcher.core.FluxMessageType} tests. + * + * @author Kevin Pollet + */ +public final class FluxMessageTypeTest { + @Test(expected = NullPointerException.class) + public void testFromTypeWithNullType() { + FluxMessageType.fromType(null); + } + + @Test(expected = IllegalArgumentException.class) + public void testFromTypeWithNonExistentType() { + FluxMessageType.fromType("foo"); + } + + @Test + public void testFromType() { + final FluxMessageType fluxMessageType = FluxMessageType.fromType(CONNECT_TO_CHANNEL.value()); + + Assert.assertEquals(CONNECT_TO_CHANNEL, fluxMessageType); + } +} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryEventBusTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryEventBusTest.java new file mode 100644 index 0000000..71927c2 --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryEventBusTest.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import org.eclipse.flux.watcher.core.spi.Project; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import javax.inject.Provider; +import java.util.Collections; + +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_CREATED; +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_DELETED; +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_MODIFIED; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * {@link com.codenvy.flux.watcher.core.RepositoryEventBus} tests + * + * @author Kevin Pollet + */ +public final class RepositoryEventBusTest { + private static final String PROJECT_ID = "project-id"; + + private RepositoryEventBus repositoryEventBus; + + @SuppressWarnings("unchecked") + @Before + public void beforeTest() { + final Provider repositoryProviderMock = mock(Provider.class); + when(repositoryProviderMock.get()).thenAnswer(new Answer() { + @Override + public Repository answer(InvocationOnMock invocationOnMock) throws Throwable { + final Repository repositoryMock = mock(Repository.class); + final Project projectMock = mock(Project.class); + when(repositoryMock.getProject(PROJECT_ID)).thenReturn(projectMock); + return repositoryMock; + } + }); + + this.repositoryEventBus = new RepositoryEventBus(Collections.emptySet(), repositoryProviderMock); + } + + @SuppressWarnings("unchecked") + @Test(expected = NullPointerException.class) + public void testNewWithNullRepositoryListeners() { + new RepositoryEventBus(null, mock(Provider.class)); + } + + @Test(expected = NullPointerException.class) + public void testNewWithNullRepository() { + new RepositoryEventBus(Collections.emptySet(), null); + } + + @Test(expected = NullPointerException.class) + public void testAddRepositoryListenerWithNullListener() { + repositoryEventBus.addRepositoryListener(null); + } + + @Test(expected = NullPointerException.class) + public void testRemoveRepositoryListenerWithNullListener() { + repositoryEventBus.removeRepositoryListener(null); + } + + @Test(expected = NullPointerException.class) + public void testFireRepositoryEventWithNullEvent() { + repositoryEventBus.fireRepositoryEvent(null); + } + + @Test(expected = IllegalStateException.class) + public void testFireRepositoryEventWithNonAddedProject() { + final RepositoryEvent entryCreatedEvent = new RepositoryEvent(PROJECT_RESOURCE_CREATED, mock(Resource.class), mock(Project.class)); + + repositoryEventBus.fireRepositoryEvent(entryCreatedEvent); + } + + @Test + public void testFireRepositoryEvent() throws Exception { + final EntryCreatedListener entryCreatedListener = new EntryCreatedListener(); + repositoryEventBus.addRepositoryListener(entryCreatedListener); + + final EntryModifiedListener entryModifiedListener = new EntryModifiedListener(); + repositoryEventBus.addRepositoryListener(entryModifiedListener); + + final EntryDeletedListener entryDeletedListener = new EntryDeletedListener(); + repositoryEventBus.addRepositoryListener(entryDeletedListener); + + final EntryCreatedAndModifiedListener entryCreatedAndModifiedListener = new EntryCreatedAndModifiedListener(); + repositoryEventBus.addRepositoryListener(entryCreatedAndModifiedListener); + + fireAllEventTypes(); + + verify(entryCreatedListener.mock, times(1)).onEvent(any(RepositoryEvent.class)); + verify(entryModifiedListener.mock, times(1)).onEvent(any(RepositoryEvent.class)); + verify(entryDeletedListener.mock, times(1)).onEvent(any(RepositoryEvent.class)); + verify(entryCreatedAndModifiedListener.mock, times(2)).onEvent(any(RepositoryEvent.class)); + } + + private void fireAllEventTypes() { + final Project projectMock = mock(Project.class); + when(projectMock.id()).thenReturn(PROJECT_ID); + + final RepositoryEvent entryCreatedEvent = new RepositoryEvent(PROJECT_RESOURCE_CREATED, mock(Resource.class), projectMock); + repositoryEventBus.fireRepositoryEvent(entryCreatedEvent); + + final RepositoryEvent entryDeletedEvent = new RepositoryEvent(PROJECT_RESOURCE_DELETED, mock(Resource.class), projectMock); + repositoryEventBus.fireRepositoryEvent(entryDeletedEvent); + + final RepositoryEvent entryModifiedEvent = new RepositoryEvent(PROJECT_RESOURCE_MODIFIED, mock(Resource.class), projectMock); + repositoryEventBus.fireRepositoryEvent(entryModifiedEvent); + } + + public static class AbstractRepositoryListener implements RepositoryListener { + public final RepositoryListener mock; + + public AbstractRepositoryListener() { + this.mock = mock(RepositoryListener.class); + } + + @Override + public void onEvent(RepositoryEvent event) throws Exception { + mock.onEvent(event); + } + } + + @RepositoryEventTypes(PROJECT_RESOURCE_CREATED) + public static class EntryCreatedListener extends AbstractRepositoryListener { + } + + @RepositoryEventTypes(PROJECT_RESOURCE_DELETED) + public static class EntryDeletedListener extends AbstractRepositoryListener { + } + + @RepositoryEventTypes(PROJECT_RESOURCE_MODIFIED) + public static class EntryModifiedListener extends AbstractRepositoryListener { + } + + @RepositoryEventTypes({PROJECT_RESOURCE_CREATED, PROJECT_RESOURCE_MODIFIED}) + public static class EntryCreatedAndModifiedListener extends AbstractRepositoryListener { + } +} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryEventTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryEventTest.java new file mode 100644 index 0000000..85a38d7 --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryEventTest.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import org.eclipse.flux.watcher.core.spi.Project; + +import org.junit.Test; + +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_CREATED; +import static org.mockito.Mockito.mock; + +/** + * {@link com.codenvy.flux.watcher.core.RepositoryEvent} tests. + * + * @author Kevin Pollet + */ +public final class RepositoryEventTest { + @Test(expected = NullPointerException.class) + public void testNewRepositoryEventWithNullRepositoryEventType() { + new RepositoryEvent(null, mock(Resource.class), mock(Project.class)); + } + + @Test(expected = NullPointerException.class) + public void testNewRepositoryEventWithNullResource() { + new RepositoryEvent(PROJECT_RESOURCE_CREATED, null, mock(Project.class)); + } + + @Test(expected = NullPointerException.class) + public void testNewRepositoryEventWithNullProject() { + new RepositoryEvent(PROJECT_RESOURCE_CREATED, mock(Resource.class), null); + } +} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryModuleTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryModuleTest.java new file mode 100644 index 0000000..3cded30 --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryModuleTest.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import org.eclipse.flux.watcher.core.spi.ProjectFactory; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; + +import org.junit.Assert; +import org.junit.Test; + +import static org.mockito.Mockito.mock; + +/** + * Tests Google Guice bootstrap. + * + * @author Kevin Pollet + */ +public final class RepositoryModuleTest { + @Test + public void testBootstrap() { + final Injector injector = Guice.createInjector(new RepositoryModule(), new TestModule()); + + Assert.assertNotNull(injector.getInstance(Repository.class)); + } + + public static class TestModule extends AbstractModule { + @Override + protected void configure() { + bind(ProjectFactory.class).toInstance(mock(ProjectFactory.class)); + } + } +} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryTest.java new file mode 100644 index 0000000..d014e8c --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryTest.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + +import org.eclipse.flux.watcher.core.spi.Project; +import org.eclipse.flux.watcher.core.spi.ProjectFactory; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.net.MalformedURLException; +import java.net.URL; + +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * {@link com.codenvy.flux.watcher.core.Repository} tests. + * + * @author Kevin Pollet + */ +public final class RepositoryTest { + private final static String PROJECT_ID = "project-id"; + private final static String PROJECT_PATH = "/project-id"; + + private Repository repository; + private FluxMessageBus fluxMessageBusMock; + + @Before + public void beforeTest() { + final Project projectMock = mock(Project.class); + when(projectMock.id()).thenReturn(PROJECT_ID); + when(projectMock.path()).thenReturn(PROJECT_PATH); + + final ProjectFactory projectFactoryMock = mock(ProjectFactory.class); + when(projectFactoryMock.newProject(anyString(), anyString())).thenReturn(projectMock); + + fluxMessageBusMock = mock(FluxMessageBus.class); + + repository = new Repository(fluxMessageBusMock, projectFactoryMock, mock(RepositoryEventBus.class)); + } + + @Test(expected = NullPointerException.class) + public void testNewWithNullMessageBus() { + new Repository(null, mock(ProjectFactory.class), mock(RepositoryEventBus.class)); + } + + @Test(expected = NullPointerException.class) + public void testNewWithNullProjectFactory() { + new Repository(mock(FluxMessageBus.class), null, mock(RepositoryEventBus.class)); + } + + @Test(expected = NullPointerException.class) + public void testNewWithNullRepositoryEventBus() { + new Repository(mock(FluxMessageBus.class), mock(ProjectFactory.class), null); + } + + @Test(expected = NullPointerException.class) + public void testAddRemoteWithNullRemoteURL() { + repository.addRemote(null, Credentials.DEFAULT_USER_CREDENTIALS); + } + + @Test(expected = NullPointerException.class) + public void testAddRemoteWithNullCredentials() throws MalformedURLException { + repository.addRemote(new URL("http://localhost:8080"), null); + } + + @Test + public void testAddRemote() throws MalformedURLException { + final URL remoteURL = new URL("http://localhost:8080"); + + repository.addRemote(remoteURL, Credentials.DEFAULT_USER_CREDENTIALS); + + verify(fluxMessageBusMock, times(1)).connect(remoteURL, Credentials.DEFAULT_USER_CREDENTIALS); + } + + @Test(expected = NullPointerException.class) + public void testRemoveRemoteWithNullRemoteURL() { + repository.removeRemote(null); + } + + @Test + public void testRemoveRemote() throws MalformedURLException { + final URL remoteURL = new URL("http://localhost:8080"); + + repository.removeRemote(remoteURL); + + verify(fluxMessageBusMock, times(1)).disconnect(remoteURL); + } + + @Test(expected = NullPointerException.class) + public void testAddProjectWithNullProjectId() { + repository.addProject(null, PROJECT_PATH); + } + + @Test(expected = NullPointerException.class) + public void testAddProjectWithNullProjectPath() { + repository.addProject(PROJECT_ID, null); + } + + @Test + public void testRemoveProjectWithNonExistentProjectId() { + final Project project = repository.removeProject(PROJECT_ID); + + Assert.assertNull(project); + } + + @Test + public void testRemoveProject() { + final Project project = repository.addProject(PROJECT_ID, PROJECT_PATH); + final Project removedProject = repository.removeProject(PROJECT_ID); + + Assert.assertNotNull(project); + Assert.assertNotNull(removedProject); + Assert.assertSame(project, removedProject); + } + + @Test + public void testAddProjectWithAlreadyAddedProject() { + final Project project = repository.addProject(PROJECT_ID, PROJECT_PATH); + + Assert.assertNotNull(project); + + final Project newProject = repository.addProject(PROJECT_ID, PROJECT_PATH); + + Assert.assertNotNull(newProject); + Assert.assertSame(project, newProject); + } + + @Test + public void testGetProjectWithNullProjectId() { + final Project project = repository.getProject(null); + + Assert.assertNull(project); + } + + @Test + public void testGetProjectWithNonExistentProjectId() { + final Project project = repository.getProject("foo"); + + Assert.assertNull(project); + } + + @Test + public void testGetProject() { + final Project project = repository.addProject(PROJECT_ID, PROJECT_PATH); + + Assert.assertNotNull(project); + + final Project currentProject = repository.getProject(PROJECT_ID); + + Assert.assertNotNull(currentProject); + Assert.assertSame(project, currentProject); + Assert.assertEquals(PROJECT_ID, currentProject.id()); + Assert.assertEquals(PROJECT_PATH, currentProject.path()); + } +} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/ResourceTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/ResourceTest.java new file mode 100644 index 0000000..ff0628b --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/ResourceTest.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.core; + + +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; + +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FOLDER; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.UNKNOWN; + +/** + * {@link com.codenvy.flux.watcher.core.Resource} tests. + * + * @author Kevin Pollet + */ +public final class ResourceTest { + private final static String RESOURCE_PATH = "/foo"; + + @Test(expected = NullPointerException.class) + public void testNewUnknownWithNullPath() { + Resource.newUnknown(null, System.currentTimeMillis()); + } + + @Test + public void testNewUnknown() { + final long timestamp = System.currentTimeMillis(); + final Resource resource = Resource.newUnknown(RESOURCE_PATH, timestamp); + + Assert.assertNotNull(resource); + Assert.assertEquals(timestamp, resource.timestamp()); + Assert.assertEquals(RESOURCE_PATH, resource.path()); + Assert.assertEquals(null, resource.content()); + Assert.assertEquals(UNKNOWN, resource.type()); + Assert.assertEquals("0", resource.hash()); + } + + @Test(expected = NullPointerException.class) + public void testNewFolderWithNullPath() { + Resource.newFolder(null, System.currentTimeMillis()); + } + + @Test + public void testNewFolder() { + final long timestamp = System.currentTimeMillis(); + final Resource resource = Resource.newFolder(RESOURCE_PATH, timestamp); + + Assert.assertNotNull(resource); + Assert.assertEquals(timestamp, resource.timestamp()); + Assert.assertEquals(RESOURCE_PATH, resource.path()); + Assert.assertEquals(null, resource.content()); + Assert.assertEquals(FOLDER, resource.type()); + Assert.assertEquals("0", resource.hash()); + } + + @Test(expected = NullPointerException.class) + public void testNewFileWithNullPath() { + Resource.newFile(null, System.currentTimeMillis(), new byte[0]); + } + + @Test + public void testNewFile() { + final byte[] content = "content".getBytes(); + final long timestamp = System.currentTimeMillis(); + final Resource resource = Resource.newFile(RESOURCE_PATH, timestamp, content); + + Assert.assertNotNull(resource); + Assert.assertEquals(timestamp, resource.timestamp()); + Assert.assertEquals(RESOURCE_PATH, resource.path()); + Assert.assertTrue(Arrays.equals(content, resource.content())); + Assert.assertEquals(FILE, resource.type()); + Assert.assertNotNull(resource.hash()); + } +} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/AbstractTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/AbstractTest.java new file mode 100644 index 0000000..90d0043 --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/AbstractTest.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.fs; + +import org.junit.After; +import org.junit.Before; + +import java.io.IOException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; + +import static java.nio.file.FileVisitResult.CONTINUE; +import static java.nio.file.Files.createDirectory; +import static java.nio.file.Files.createFile; +import static java.nio.file.Files.delete; +import static java.nio.file.Files.walkFileTree; + +/** + * Abstract test class. + * + * @author Kevin Pollet + */ +public class AbstractTest { + public static final String PROJECT_ID = "codenvy-project-id"; + public static final String PROJECT_PATH = Paths.get("codenvy-project").toAbsolutePath().toString(); + public static final String RELATIVE_PROJECT_SRC_FOLDER_PATH = "src"; + public static final String RELATIVE_PROJECT_MAIN_FOLDER_PATH = "src/main"; + public static final String RELATIVE_PROJECT_HELLO_FILE_PATH = "src/hello"; + public static final String RELATIVE_PROJECT_README_FILE_PATH = "readme"; + + private FileSystem fileSystem; + + public FileSystem fileSystem() { + return fileSystem; + } + + @Before + public void initFileSystem() throws IOException { + fileSystem = FileSystems.getDefault(); + + createDirectory(fileSystem.getPath(PROJECT_PATH)); + createDirectory(fileSystem.getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_SRC_FOLDER_PATH)); + createFile(fileSystem.getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_README_FILE_PATH)); + } + + @After + public void destroyFileSystem() throws IOException { + walkFileTree(fileSystem.getPath(PROJECT_PATH), new SimpleFileVisitor() { + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + delete(dir); + return CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + delete(file); + return CONTINUE; + } + }); + } +} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectFactoryTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectFactoryTest.java new file mode 100644 index 0000000..583a28e --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectFactoryTest.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.fs; + + +import org.eclipse.flux.watcher.core.RepositoryEventBus; +import org.eclipse.flux.watcher.core.spi.Project; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; + +import static org.mockito.Mockito.mock; + +/** + * {@link com.codenvy.flux.watcher.fs.JDKProjectFactory} tests. + * + * @author Kevin Pollet + */ +public final class JDKProjectFactoryTest extends AbstractTest { + private JDKProjectFactory jdkProjectFactory; + + @Before + public void beforeTest() { + jdkProjectFactory = new JDKProjectFactory(fileSystem(), mock(RepositoryEventBus.class)); + } + + @Test(expected = NullPointerException.class) + public void testNewJDKProjectFactoryWithNullFileSystem() { + new JDKProjectFactory(null, mock(RepositoryEventBus.class)); + } + + @Test(expected = NullPointerException.class) + public void testNewJDKProjectFactoryWithNullRepositoryEventBus() { + new JDKProjectFactory(fileSystem(), null); + } + + @Test(expected = NullPointerException.class) + public void testNewProjectWithNullProjectId() { + jdkProjectFactory.newProject(null, PROJECT_PATH); + } + + @Test(expected = NullPointerException.class) + public void testNewProjectWithNullProjectPath() { + jdkProjectFactory.newProject(PROJECT_ID, null); + } + + @Test(expected = IllegalArgumentException.class) + public void testNewProjectWithNonExistentProjectPath() { + jdkProjectFactory.newProject(PROJECT_ID, "foo"); + } + + @Test(expected = IllegalArgumentException.class) + public void testNewProjectWithFileProjectPath() { + jdkProjectFactory.newProject(PROJECT_ID, PROJECT_PATH + File.separator + RELATIVE_PROJECT_README_FILE_PATH); + } + + @Test(expected = IllegalArgumentException.class) + public void testNewProjectWithNonAbsoluteProjectPath() { + jdkProjectFactory.newProject(PROJECT_ID, RELATIVE_PROJECT_README_FILE_PATH); + } + + @Test + public void testNewProject() { + final Project project = jdkProjectFactory.newProject(PROJECT_ID, PROJECT_PATH); + + Assert.assertNotNull(project); + Assert.assertEquals(PROJECT_ID, project.id()); + Assert.assertEquals(PROJECT_PATH, project.path()); + } +} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectModuleTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectModuleTest.java new file mode 100644 index 0000000..c37acfd --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectModuleTest.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.fs; + +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.RepositoryModule; +import com.google.inject.Guice; +import com.google.inject.Injector; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests Google Guice bootstrap. + * + * @author Kevin Pollet + */ +public final class JDKProjectModuleTest { + @Test + public void testBootstrap() { + final Injector injector = Guice.createInjector(new RepositoryModule(), new JDKProjectModule()); + + Assert.assertNotNull(injector.getInstance(Repository.class)); + } +} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectTest.java new file mode 100644 index 0000000..40b7c3b --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectTest.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.fs; + + +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; +import com.google.common.collect.Sets; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Calendar; +import java.util.Set; + +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FOLDER; +import static java.nio.file.Files.createFile; +import static java.nio.file.Files.exists; +import static java.nio.file.Files.getLastModifiedTime; +import static java.nio.file.Files.isDirectory; +import static java.nio.file.Files.readAllBytes; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * {@link com.codenvy.flux.watcher.fs.JDKProject} tests. + * + * @author Kevin Pollet + */ +public final class JDKProjectTest extends AbstractTest { + private JDKProject project; + private JDKProjectWatchService jdkProjectWatchServiceMock; + + @Before + public void beforeTest() throws IOException { + jdkProjectWatchServiceMock = mock(JDKProjectWatchService.class); + project = new JDKProject(fileSystem(), jdkProjectWatchServiceMock, PROJECT_ID, PROJECT_PATH); + } + + @Test + public void testSetSynchronizedWithTrue() { + project.setSynchronized(true); + verify(jdkProjectWatchServiceMock, times(1)).watch(any(Project.class)); + verify(jdkProjectWatchServiceMock, times(0)).unwatch(any(Project.class)); + } + + @Test + public void testSetSynchronizedWithFalse() { + project.setSynchronized(false); + verify(jdkProjectWatchServiceMock, times(0)).watch(any(Project.class)); + verify(jdkProjectWatchServiceMock, times(1)).unwatch(any(Project.class)); + } + + @Test + public void testGetResources() { + final Set resources = project.getResources(); + final Set paths = Sets.newHashSet(RELATIVE_PROJECT_SRC_FOLDER_PATH, RELATIVE_PROJECT_README_FILE_PATH); + + Assert.assertNotNull(resources); + Assert.assertEquals(2, resources.size()); + + for (Resource oneResource : resources) { + if (paths.contains(oneResource.path())) { + paths.remove(oneResource.path()); + } + } + + Assert.assertTrue(paths.isEmpty()); + } + + @Test(expected = NullPointerException.class) + public void testGetResourceWithNullResourcePath() { + project.getResource(null); + } + + @Test + public void testGetResourceWithNonExistentResourcePath() { + final Resource resource = project.getResource("foo"); + + Assert.assertNull(resource); + } + + @Test + public void testGetResourceWithFilePath() throws IOException { + final Path absoluteResourcePath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_README_FILE_PATH); + final Resource resource = project.getResource(RELATIVE_PROJECT_README_FILE_PATH); + + Assert.assertNotNull(resource); + Assert.assertEquals(RELATIVE_PROJECT_README_FILE_PATH, resource.path()); + Assert.assertEquals(FILE, resource.type()); + Assert.assertEquals(getLastModifiedTime(absoluteResourcePath).toMillis(), resource.timestamp()); + Assert.assertArrayEquals(readAllBytes(absoluteResourcePath), resource.content()); + Assert.assertNotNull(resource.hash()); + } + + @Test + public void testGetResourceWithFolderPath() throws IOException { + final Path absoluteFolderPath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_SRC_FOLDER_PATH); + final Resource resource = project.getResource(RELATIVE_PROJECT_SRC_FOLDER_PATH); + + Assert.assertNotNull(resource); + Assert.assertEquals(RELATIVE_PROJECT_SRC_FOLDER_PATH, resource.path()); + Assert.assertEquals(FOLDER, resource.type()); + Assert.assertEquals(getLastModifiedTime(absoluteFolderPath).toMillis(), resource.timestamp()); + Assert.assertEquals(null, resource.content()); + Assert.assertNotNull(resource.hash()); + } + + @Test(expected = NullPointerException.class) + public void testCreateResourceWithNullResource() { + project.createResource(null); + } + + @Test + public void testCreateResourceWithFolderResource() throws IOException { + final Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.DAY_OF_MONTH, 26); + calendar.set(Calendar.MONTH, 8); + calendar.set(Calendar.YEAR, 1984); + + final Path absoluteFolderPath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_MAIN_FOLDER_PATH); + project.createResource(Resource.newFolder(RELATIVE_PROJECT_MAIN_FOLDER_PATH, calendar.getTimeInMillis())); + + Assert.assertTrue(exists(absoluteFolderPath)); + Assert.assertTrue(isDirectory(absoluteFolderPath)); + Assert.assertEquals(calendar.getTimeInMillis(), getLastModifiedTime(absoluteFolderPath).toMillis()); + } + + @Test + public void testCreateResourceWithFileResource() throws IOException { + final byte[] helloFileContent = "helloWorld".getBytes(); + final Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.DAY_OF_MONTH, 26); + calendar.set(Calendar.MONTH, 8); + calendar.set(Calendar.YEAR, 1984); + + final Path absoluteFilePath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_HELLO_FILE_PATH); + project.createResource(Resource.newFile(RELATIVE_PROJECT_HELLO_FILE_PATH, calendar.getTimeInMillis(), helloFileContent)); + + Assert.assertTrue(exists(absoluteFilePath)); + Assert.assertFalse(isDirectory(absoluteFilePath)); + Assert.assertArrayEquals(readAllBytes(absoluteFilePath), helloFileContent); + Assert.assertEquals(calendar.getTimeInMillis(), getLastModifiedTime(absoluteFilePath).toMillis()); + } + + @Test(expected = NullPointerException.class) + public void testUpdateResourceWithNullResource() { + project.updateResource(null); + } + + @Test(expected = IllegalArgumentException.class) + public void testUpdateResourceWithFolderResource() { + project.updateResource(Resource.newFolder(RELATIVE_PROJECT_MAIN_FOLDER_PATH, System.currentTimeMillis())); + } + + @Test + public void testUpdateResource() throws IOException { + final byte[] readmeContent = "readme".getBytes(); + final long timestamp = System.currentTimeMillis(); + final Path resourcePath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_README_FILE_PATH); + final Resource resource = Resource.newFile(RELATIVE_PROJECT_README_FILE_PATH, timestamp, readmeContent); + + Assert.assertArrayEquals(new byte[0], Files.readAllBytes(resourcePath)); + + project.updateResource(resource); + + Assert.assertEquals(timestamp, getLastModifiedTime(resourcePath).toMillis()); + Assert.assertArrayEquals(readmeContent, readAllBytes(resourcePath)); + } + + @Test(expected = NullPointerException.class) + public void testDeleteResourceWithNullResource() { + project.deleteResource(null); + } + + @Test + public void testDeleteResourceWithEmptyFolderResource() throws IOException { + final Path absoluteFolderPath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_SRC_FOLDER_PATH); + project.deleteResource(Resource.newFolder(RELATIVE_PROJECT_SRC_FOLDER_PATH, System.currentTimeMillis())); + + Assert.assertFalse(exists(absoluteFolderPath)); + } + + @Test + public void testDeleteResourceWithNonEmptyFolderResource() throws IOException { + final Path absoluteFilePath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_HELLO_FILE_PATH); + createFile(absoluteFilePath); + + final Path absoluteFolderPath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_SRC_FOLDER_PATH); + project.deleteResource(Resource.newFolder(RELATIVE_PROJECT_SRC_FOLDER_PATH, System.currentTimeMillis())); + + Assert.assertFalse(exists(absoluteFolderPath)); + } + + @Test + public void testDeleteResourceWithFileResource() throws IOException { + final Path absoluteFilePath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_README_FILE_PATH); + project + .deleteResource(Resource.newFile(RELATIVE_PROJECT_README_FILE_PATH, System.currentTimeMillis(), new byte[0])); + + Assert.assertFalse(exists(absoluteFilePath)); + } +} \ No newline at end of file diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectWatchServiceTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectWatchServiceTest.java new file mode 100644 index 0000000..0f9d27b --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/JDKProjectWatchServiceTest.java @@ -0,0 +1,408 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.fs; + +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventBus; +import org.eclipse.flux.watcher.core.RepositoryEventType; +import org.eclipse.flux.watcher.core.RepositoryEventTypes; +import org.eclipse.flux.watcher.core.RepositoryListener; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; +import com.google.common.base.Throwables; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import javax.inject.Provider; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.nio.file.WatchEvent; +import java.util.Collections; +import java.util.concurrent.CountDownLatch; + +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_CREATED; +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_DELETED; +import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_MODIFIED; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.FOLDER; +import static org.eclipse.flux.watcher.core.Resource.ResourceType.UNKNOWN; +import static java.nio.file.Files.createDirectory; +import static java.nio.file.Files.createFile; +import static java.nio.file.Files.delete; +import static java.nio.file.Files.getLastModifiedTime; +import static java.nio.file.Files.readAllBytes; +import static java.nio.file.Files.write; +import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; +import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; +import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; +import static java.nio.file.WatchEvent.Kind; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * {@link com.codenvy.flux.watcher.fs.JDKProjectWatchService} tests. + * + * @author Kevin Pollet + */ +public final class JDKProjectWatchServiceTest extends AbstractTest { + private JDKProject jdkProject; + private JDKProjectWatchService jdkProjectWatchService; + private RepositoryEventBus repositoryEventBus; + + @SuppressWarnings("unchecked") + @Before + public void beforeTest() throws NoSuchMethodException { + final Provider repositoryProviderMock = mock(Provider.class); + when(repositoryProviderMock.get()).thenAnswer(new Answer() { + @Override + public Repository answer(InvocationOnMock invocationOnMock) throws Throwable { + final Repository repositoryMock = mock(Repository.class); + final Project projectMock = mock(Project.class); + when(repositoryMock.getProject(PROJECT_ID)).thenReturn(projectMock); + + return repositoryMock; + } + }); + + repositoryEventBus = new RepositoryEventBus(Collections.emptySet(), repositoryProviderMock); + jdkProjectWatchService = new JDKProjectWatchService(fileSystem(), repositoryEventBus); + jdkProject = new JDKProject(fileSystem(), jdkProjectWatchService, PROJECT_ID, PROJECT_PATH); + } + + @Test(expected = NullPointerException.class) + public void testWatchWithNullProject() { + jdkProjectWatchService.watch(null); + } + + @Test(expected = NullPointerException.class) + public void testUnwatchWithNullProject() { + jdkProjectWatchService.unwatch(null); + } + + @Test + public void testKindToRepositoryEventTypeWithNullKind() throws Exception { + final RepositoryEventType repositoryEventType = kindToRepositoryEventType(null); + + Assert.assertNull(repositoryEventType); + } + + @Test + public void testKindToRepositoryEventTypeWithEntryCreateKind() throws Exception { + final RepositoryEventType repositoryEventType = kindToRepositoryEventType(ENTRY_CREATE); + + Assert.assertNotNull(repositoryEventType); + Assert.assertEquals(PROJECT_RESOURCE_CREATED, repositoryEventType); + } + + @Test + public void testKindToRepositoryEventTypeWithEntryDeleteKind() throws Exception { + final RepositoryEventType repositoryEventType = kindToRepositoryEventType(ENTRY_DELETE); + + Assert.assertNotNull(repositoryEventType); + Assert.assertEquals(PROJECT_RESOURCE_DELETED, repositoryEventType); + } + + @Test + public void testKindToRepositoryEventTypeWithEntryModifyKind() throws Exception { + final RepositoryEventType repositoryEventType = kindToRepositoryEventType(ENTRY_MODIFY); + + Assert.assertNotNull(repositoryEventType); + Assert.assertEquals(PROJECT_RESOURCE_MODIFIED, repositoryEventType); + } + + @Test(expected = NullPointerException.class) + public void testCastWithNullEvent() throws Throwable { + final Method castMethod = JDKProjectWatchService.class.getDeclaredMethod("cast", WatchEvent.class); + castMethod.setAccessible(true); + + try { + + castMethod.invoke(jdkProjectWatchService, (WatchEvent)null); + + } catch (InvocationTargetException e) { + throw e.getCause(); + } + } + + @Test(expected = NullPointerException.class) + public void testPathToResourceWithNullKind() throws Exception { + pathToResource(null, jdkProject, fileSystem().getPath(PROJECT_PATH)); + } + + @Test(expected = NullPointerException.class) + public void testPathToResourceWithNullProject() throws Exception { + pathToResource(ENTRY_CREATE, null, fileSystem().getPath(PROJECT_PATH)); + } + + @Test(expected = NullPointerException.class) + public void testPathToResourceWithNullResourcePath() throws Exception { + pathToResource(ENTRY_CREATE, jdkProject, null); + } + + @Test(expected = IllegalArgumentException.class) + public void testPathToResourceWithCreateKindAndNonExistentResourcePath() throws Exception { + pathToResource(ENTRY_CREATE, jdkProject, fileSystem().getPath("foo")); + } + + @Test(expected = IllegalArgumentException.class) + public void testPathToResourceWithRelativeResourcePath() throws Exception { + pathToResource(ENTRY_CREATE, jdkProject, fileSystem().getPath(RELATIVE_PROJECT_README_FILE_PATH)); + } + + @Test + public void testPathToResourceWithFolderPath() throws Exception { + final Path absoluteFolderPath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_SRC_FOLDER_PATH); + final Resource resource = pathToResource(ENTRY_CREATE, jdkProject, absoluteFolderPath); + + Assert.assertNotNull(resource); + Assert.assertEquals(RELATIVE_PROJECT_SRC_FOLDER_PATH, resource.path()); + Assert.assertEquals(FOLDER, resource.type()); + Assert.assertEquals(getLastModifiedTime(absoluteFolderPath).toMillis(), resource.timestamp()); + Assert.assertArrayEquals(null, resource.content()); + Assert.assertNotNull(resource.hash()); + } + + @Test + public void testPathToResourceWithFilePath() throws Exception { + final Path absoluteFilePath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_README_FILE_PATH); + final Resource resource = pathToResource(ENTRY_CREATE, jdkProject, absoluteFilePath); + + Assert.assertNotNull(resource); + Assert.assertEquals(RELATIVE_PROJECT_README_FILE_PATH, resource.path()); + Assert.assertEquals(FILE, resource.type()); + Assert.assertEquals(getLastModifiedTime(absoluteFilePath).toMillis(), resource.timestamp()); + Assert.assertArrayEquals(readAllBytes(absoluteFilePath), resource.content()); + Assert.assertNotNull(resource.hash()); + } + + @Test + public void testWatchEntryCreateFile() throws InterruptedException, IOException { + final CountDownLatch countDownLatch = new CountDownLatch(1); + final ProjectResourceCreatedListener projectResourceCreatedListener = new ProjectResourceCreatedListener(countDownLatch); + + jdkProjectWatchService.watch(jdkProject); + repositoryEventBus.addRepositoryListener(projectResourceCreatedListener); + + final Path absoluteFilePath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_HELLO_FILE_PATH); + createFile(absoluteFilePath); + + countDownLatch.await(1, MINUTES); + + final RepositoryEvent repositoryEvent = projectResourceCreatedListener.repositoryEvent; + + Assert.assertNotNull(repositoryEvent); + Assert.assertEquals(PROJECT_ID, repositoryEvent.project().id()); + Assert.assertEquals(PROJECT_RESOURCE_CREATED, repositoryEvent.type()); + Assert.assertEquals(RELATIVE_PROJECT_HELLO_FILE_PATH, repositoryEvent.resource().path()); + Assert.assertEquals(FILE, repositoryEvent.resource().type()); + Assert.assertEquals(getLastModifiedTime(absoluteFilePath).toMillis(), repositoryEvent.resource().timestamp()); + Assert.assertArrayEquals(readAllBytes(absoluteFilePath), repositoryEvent.resource().content()); + Assert.assertNotNull(repositoryEvent.resource().hash()); + } + + @Test + public void testWatchEntryCreateFolder() throws InterruptedException, IOException { + final CountDownLatch countDownLatch = new CountDownLatch(1); + final ProjectResourceCreatedListener projectResourceCreatedListener = new ProjectResourceCreatedListener(countDownLatch); + + jdkProjectWatchService.watch(jdkProject); + repositoryEventBus.addRepositoryListener(projectResourceCreatedListener); + + final Path absoluteFilePath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_MAIN_FOLDER_PATH); + createDirectory(absoluteFilePath); + + countDownLatch.await(1, MINUTES); + + final RepositoryEvent repositoryEvent = projectResourceCreatedListener.repositoryEvent; + + Assert.assertNotNull(repositoryEvent); + Assert.assertEquals(PROJECT_RESOURCE_CREATED, repositoryEvent.type()); + Assert.assertEquals(PROJECT_ID, repositoryEvent.project().id()); + Assert.assertEquals(RELATIVE_PROJECT_MAIN_FOLDER_PATH, projectResourceCreatedListener.repositoryEvent.resource().path()); + Assert.assertEquals(FOLDER, projectResourceCreatedListener.repositoryEvent.resource().type()); + Assert.assertEquals(getLastModifiedTime(absoluteFilePath).toMillis(), repositoryEvent.resource().timestamp()); + Assert.assertArrayEquals(null, repositoryEvent.resource().content()); + Assert.assertNotNull(repositoryEvent.resource().hash()); + } + + @Test + public void testWatchEntryModifyFile() throws InterruptedException, IOException { + final CountDownLatch countDownLatch = new CountDownLatch(1); + final ProjectResourceModifiedListener projectResourceModifiedListener = new ProjectResourceModifiedListener(countDownLatch); + + jdkProjectWatchService.watch(jdkProject); + repositoryEventBus.addRepositoryListener(projectResourceModifiedListener); + + final String content = "README"; + final Path absoluteFilePath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_README_FILE_PATH); + write(absoluteFilePath, content.getBytes()); + + countDownLatch.await(1, MINUTES); + + final RepositoryEvent repositoryEvent = projectResourceModifiedListener.repositoryEvent; + + Assert.assertNotNull(repositoryEvent); + Assert.assertEquals(PROJECT_RESOURCE_MODIFIED, repositoryEvent.type()); + Assert.assertEquals(PROJECT_ID, repositoryEvent.project().id()); + Assert.assertEquals(RELATIVE_PROJECT_README_FILE_PATH, repositoryEvent.resource().path()); + Assert.assertEquals(FILE, repositoryEvent.resource().type()); + Assert.assertEquals(getLastModifiedTime(absoluteFilePath).toMillis(), repositoryEvent.resource().timestamp()); + Assert.assertArrayEquals(content.getBytes(), repositoryEvent.resource().content()); + Assert.assertNotNull(repositoryEvent.resource().hash()); + } + + @Test + public void testWatchEntryDeleteFile() throws InterruptedException, IOException { + final CountDownLatch countDownLatch = new CountDownLatch(1); + final ProjectResourceDeletedListener projectResourceDeletedListener = new ProjectResourceDeletedListener(countDownLatch); + + jdkProjectWatchService.watch(jdkProject); + repositoryEventBus.addRepositoryListener(projectResourceDeletedListener); + + final Path absoluteFilePath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_README_FILE_PATH); + delete(absoluteFilePath); + + countDownLatch.await(1, MINUTES); + + final RepositoryEvent repositoryEvent = projectResourceDeletedListener.repositoryEvent; + + Assert.assertNotNull(repositoryEvent); + Assert.assertEquals(PROJECT_RESOURCE_DELETED, repositoryEvent.type()); + Assert.assertEquals(PROJECT_ID, repositoryEvent.project().id()); + Assert.assertEquals(RELATIVE_PROJECT_README_FILE_PATH, repositoryEvent.resource().path()); + Assert.assertEquals(UNKNOWN, projectResourceDeletedListener.repositoryEvent.resource().type()); + Assert.assertArrayEquals(null, repositoryEvent.resource().content()); + Assert.assertNotNull(repositoryEvent.resource().hash()); + } + + @Test + public void testWatchEntryDeleteFolder() throws InterruptedException, IOException { + final CountDownLatch countDownLatch = new CountDownLatch(1); + final ProjectResourceDeletedListener projectResourceDeletedListener = new ProjectResourceDeletedListener(countDownLatch); + + jdkProjectWatchService.watch(jdkProject); + repositoryEventBus.addRepositoryListener(projectResourceDeletedListener); + + final Path absoluteFolderPath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_SRC_FOLDER_PATH); + delete(absoluteFolderPath); + + countDownLatch.await(1, MINUTES); + + final RepositoryEvent repositoryEvent = projectResourceDeletedListener.repositoryEvent; + + Assert.assertNotNull(repositoryEvent); + Assert.assertEquals(PROJECT_RESOURCE_DELETED, repositoryEvent.type()); + Assert.assertEquals(PROJECT_ID, repositoryEvent.project().id()); + Assert.assertEquals(RELATIVE_PROJECT_SRC_FOLDER_PATH, repositoryEvent.resource().path()); + Assert.assertEquals(UNKNOWN, repositoryEvent.resource().type()); + Assert.assertArrayEquals(null, repositoryEvent.resource().content()); + Assert.assertNotNull(repositoryEvent.resource().hash()); + } + + @Test + public void testUnwatch() throws IOException, InterruptedException { + final CountDownLatch countDownLatch = new CountDownLatch(1); + final ProjectResourceDeletedListener projectResourceDeletedListener = new ProjectResourceDeletedListener(countDownLatch); + + jdkProjectWatchService.watch(jdkProject); + repositoryEventBus.addRepositoryListener(projectResourceDeletedListener); + jdkProjectWatchService.unwatch(jdkProject); + + final Path absoluteFolderPath = fileSystem().getPath(PROJECT_PATH).resolve(RELATIVE_PROJECT_SRC_FOLDER_PATH); + delete(absoluteFolderPath); + + countDownLatch.await(30, SECONDS); + + Assert.assertNull(projectResourceDeletedListener.repositoryEvent); + } + + private RepositoryEventType kindToRepositoryEventType(Kind kind) throws Exception { + final Method kindToRepositoryEventTypeMethod = + JDKProjectWatchService.class.getDeclaredMethod("kindToRepositoryEventType", Kind.class); + kindToRepositoryEventTypeMethod.setAccessible(true); + + try { + + return (RepositoryEventType)kindToRepositoryEventTypeMethod.invoke(jdkProjectWatchService, kind); + + } catch (InvocationTargetException e) { + throw Throwables.propagate(e.getCause()); + } + } + + private Resource pathToResource(Kind kind, Project project, Path resourcePath) throws Exception { + final Method pathToResourceMethod = + JDKProjectWatchService.class.getDeclaredMethod("pathToResource", Kind.class, Project.class, Path.class); + pathToResourceMethod.setAccessible(true); + + try { + + return (Resource)pathToResourceMethod.invoke(jdkProjectWatchService, kind, project, resourcePath); + + } catch (InvocationTargetException e) { + throw Throwables.propagate(e.getCause()); + } + } + + private static abstract class AbstractRepositoryListener implements RepositoryListener { + private final CountDownLatch countDownLatch; + public RepositoryEvent repositoryEvent; + + public AbstractRepositoryListener(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + this.repositoryEvent = null; + } + + @Override + public void onEvent(RepositoryEvent event) { + try { + + if (repositoryEvent != null) { + throw new IllegalStateException(); + } + repositoryEvent = event; + + } finally { + countDownLatch.countDown(); + } + } + } + + @RepositoryEventTypes(PROJECT_RESOURCE_CREATED) + private static class ProjectResourceCreatedListener extends AbstractRepositoryListener { + public ProjectResourceCreatedListener(CountDownLatch countDownLatch) { + super(countDownLatch); + } + } + + @RepositoryEventTypes(PROJECT_RESOURCE_MODIFIED) + private static class ProjectResourceModifiedListener extends AbstractRepositoryListener { + public ProjectResourceModifiedListener(CountDownLatch countDownLatch) { + super(countDownLatch); + } + } + + @RepositoryEventTypes(PROJECT_RESOURCE_DELETED) + private static class ProjectResourceDeletedListener extends AbstractRepositoryListener { + public ProjectResourceDeletedListener(CountDownLatch countDownLatch) { + super(countDownLatch); + } + } +} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/utils/ResourceHelperTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/utils/ResourceHelperTest.java new file mode 100644 index 0000000..ffcb0d4 --- /dev/null +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/fs/utils/ResourceHelperTest.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2014 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.flux.watcher.fs.utils; + + +import org.eclipse.flux.watcher.core.utils.ResourceHelper; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Kevin Pollet + */ +public final class ResourceHelperTest { + @Test(expected = NullPointerException.class) + public void testSHA1WithNullBytes() { + ResourceHelper.sha1(null); + } + + @Test + public void testSHA1() { + final byte[] hello = "hello".getBytes(); + final byte[] helloWorld = "helloWorld".getBytes(); + + final String helloHash = ResourceHelper.sha1(hello); + final String helloWorldHash = ResourceHelper.sha1(helloWorld); + + Assert.assertNotNull(helloHash); + Assert.assertNotNull(helloWorldHash); + Assert.assertNotEquals(helloHash, helloWorldHash); + } +} From 3b4ee6e5fd9f8b32b4b363929889be26e05f82db Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Mon, 15 Aug 2016 15:19:52 +0300 Subject: [PATCH 10/34] Refactored: Repository to RepositoryAdapter Signed-off-by: Fjodor Vershinin --- .../src/org/eclipse/flux/core/Activator.java | 8 ++++---- .../{Repository.java => RepositoryAdapter.java} | 14 +++++++------- .../core/internal/CloudSyncMetadataListener.java | 6 +++--- .../jdt/services/InitializeServiceEnvironment.java | 6 +++--- .../eclipse/flux/jdt/services/JDTComponent.java | 4 ++-- .../eclipse/flux/jdt/services/LiveEditUnits.java | 6 +++--- .../org/eclipse/flux/ui/integration/UiStartup.java | 4 ++-- .../ui/integration/handlers/LiveEditConnector.java | 8 ++++---- .../integration/handlers/SyncConnectHandler.java | 6 +++--- .../handlers/SyncDisconnectHandler.java | 6 +++--- .../integration/handlers/SyncDownloadHandler.java | 6 +++--- 11 files changed, 37 insertions(+), 37 deletions(-) rename org.eclipse.flux.core/src/org/eclipse/flux/core/{Repository.java => RepositoryAdapter.java} (92%) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java index ed5a794..b01d8d9 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java @@ -63,7 +63,7 @@ public class Activator extends Plugin { private MessageConnector messageConnector; private ChannelSwitcher channelSwitcher; - private Repository repository; + private RepositoryAdapter repository; private LiveEditCoordinator liveEditCoordinator; private boolean lazyStart = false; @@ -175,7 +175,7 @@ public void stop(BundleContext context) throws Exception { } private void initCoreService(String userChannel) throws CoreException { - repository = new Repository(messageConnector, fluxRepository, userChannel); + repository = new RepositoryAdapter(fluxRepository, userChannel); liveEditCoordinator = new LiveEditCoordinator(messageConnector); IWorkspace workspace = ResourcesPlugin.getWorkspace(); @@ -248,7 +248,7 @@ private void updateProjectConnections() throws CoreException { if (!project.isOpen()) { project.open(null); } - Repository repository = org.eclipse.flux.core.Activator.getDefault() + RepositoryAdapter repository = org.eclipse.flux.core.Activator.getDefault() .getRepository(); repository.addProject(project); } @@ -316,7 +316,7 @@ public MessageConnector getMessageConnector() { return messageConnector; } - public Repository getRepository() { + public RepositoryAdapter getRepository() { return repository; } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java similarity index 92% rename from org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java rename to org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index 6d32fd9..ea2b792 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Repository.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -19,11 +19,11 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.core.listeners.MetadataRequestHandler; import org.eclipse.flux.core.listeners.ResourceListener; import org.eclipse.flux.watcher.core.FluxMessage; import org.eclipse.flux.watcher.core.FluxMessageType; +import org.eclipse.flux.watcher.core.Repository; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; import org.json.JSONObject; @@ -31,23 +31,23 @@ /** * @author Martin Lippert */ -public class Repository { +public class RepositoryAdapter { private String username; private ConcurrentMap syncedProjects; private Collection repositoryListeners; - private org.eclipse.flux.watcher.core.Repository repository; + private Repository repository; - public Repository(MessageConnector messagingConnector, org.eclipse.flux.watcher.core.Repository fluxRepository, String user) { - this.repository = fluxRepository; + public RepositoryAdapter(Repository repository, String user) { + this.repository = repository; this.username = user; this.syncedProjects = new ConcurrentHashMap(); this.repositoryListeners = new ConcurrentLinkedDeque<>(); - fluxRepository.getMessageBus().addMessageHandler(new ResourceListener()); - fluxRepository.getMessageBus().addMessageHandler(new MetadataRequestHandler()); + repository.getMessageBus().addMessageHandler(new ResourceListener()); + repository.getMessageBus().addMessageHandler(new MetadataRequestHandler()); } public String getUsername() { diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/internal/CloudSyncMetadataListener.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/internal/CloudSyncMetadataListener.java index 9e395ae..caeff39 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/internal/CloudSyncMetadataListener.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/internal/CloudSyncMetadataListener.java @@ -15,16 +15,16 @@ import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.runtime.CoreException; -import org.eclipse.flux.core.Repository; +import org.eclipse.flux.core.RepositoryAdapter; /** * @author Martin Lippert */ public class CloudSyncMetadataListener implements IResourceChangeListener{ - private Repository repository; + private RepositoryAdapter repository; - public CloudSyncMetadataListener(Repository repository) { + public CloudSyncMetadataListener(RepositoryAdapter repository) { this.repository = repository; } diff --git a/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/InitializeServiceEnvironment.java b/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/InitializeServiceEnvironment.java index 764693c..a4ea5e0 100644 --- a/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/InitializeServiceEnvironment.java +++ b/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/InitializeServiceEnvironment.java @@ -19,7 +19,7 @@ import org.eclipse.flux.client.MessageHandler; import org.eclipse.flux.core.DownloadProject; import org.eclipse.flux.core.DownloadProject.CompletionCallback; -import org.eclipse.flux.core.Repository; +import org.eclipse.flux.core.RepositoryAdapter; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -34,12 +34,12 @@ public class InitializeServiceEnvironment { private static int GET_PROJECTS_CALLBACK = "InitializeServiceEnvironment - getProjectsCallback".hashCode(); private final MessageConnector messagingConnector; - final Repository repository; + final RepositoryAdapter repository; private IMessageHandler getProjectsResponseHandler; private IMessageHandler projectConnectedHandler; - public InitializeServiceEnvironment(MessageConnector messagingConnector, Repository repository) { + public InitializeServiceEnvironment(MessageConnector messagingConnector, RepositoryAdapter repository) { this.messagingConnector = messagingConnector; this.repository = repository; } diff --git a/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/JDTComponent.java b/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/JDTComponent.java index 5bed097..5b1bb14 100644 --- a/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/JDTComponent.java +++ b/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/JDTComponent.java @@ -17,7 +17,7 @@ import org.eclipse.flux.core.ChannelSwitcher; import org.eclipse.flux.core.KeepAliveConnector; import org.eclipse.flux.core.LiveEditCoordinator; -import org.eclipse.flux.core.Repository; +import org.eclipse.flux.core.RepositoryAdapter; import org.eclipse.flux.core.ServiceDiscoveryConnector; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; @@ -109,7 +109,7 @@ public void connected(String userChannel) { } MessageConnector messagingConnector = org.eclipse.flux.core.Activator .getDefault().getMessageConnector(); - Repository repository = org.eclipse.flux.core.Activator.getDefault() + RepositoryAdapter repository = org.eclipse.flux.core.Activator.getDefault() .getRepository(); LiveEditCoordinator liveEditCoordinator = org.eclipse.flux.core.Activator .getDefault().getLiveEditCoordinator(); diff --git a/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/LiveEditUnits.java b/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/LiveEditUnits.java index bbb8518..6333f23 100644 --- a/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/LiveEditUnits.java +++ b/org.eclipse.flux.jdt.service/src/org/eclipse/flux/jdt/services/LiveEditUnits.java @@ -32,7 +32,7 @@ import org.eclipse.flux.core.ILiveEditConnector; import org.eclipse.flux.core.IRepositoryListener; import org.eclipse.flux.core.LiveEditCoordinator; -import org.eclipse.flux.core.Repository; +import org.eclipse.flux.core.RepositoryAdapter; import org.eclipse.jdt.core.IBuffer; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IProblemRequestor; @@ -53,7 +53,7 @@ public class LiveEditUnits { private static int GET_LIVE_RESOURCES_CALLBACK = "LiveEditUnits - getLiveResourcesCallback".hashCode(); private ConcurrentMap liveEditUnits; - private Repository repository; + private RepositoryAdapter repository; private MessageConnector messagingConnector; private LiveEditCoordinator liveEditCoordinator; @@ -62,7 +62,7 @@ public class LiveEditUnits { private IResourceChangeListener metadataChangeListener; private IMessageHandler liveResourcesResponseHandler; - public LiveEditUnits(MessageConnector messagingConnector, LiveEditCoordinator liveEditCoordinator, Repository repository) { + public LiveEditUnits(MessageConnector messagingConnector, LiveEditCoordinator liveEditCoordinator, RepositoryAdapter repository) { this.messagingConnector = messagingConnector; this.liveEditCoordinator = liveEditCoordinator; this.repository = repository; diff --git a/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/UiStartup.java b/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/UiStartup.java index d31a00f..03b779b 100644 --- a/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/UiStartup.java +++ b/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/UiStartup.java @@ -17,7 +17,7 @@ import org.eclipse.flux.core.ChannelSwitcher; import org.eclipse.flux.core.IRepositoryListener; import org.eclipse.flux.core.LiveEditCoordinator; -import org.eclipse.flux.core.Repository; +import org.eclipse.flux.core.RepositoryAdapter; import org.eclipse.flux.ui.integration.handlers.LiveEditConnector; import org.eclipse.jface.viewers.LabelProviderChangedEvent; import org.eclipse.swt.widgets.Display; @@ -84,7 +84,7 @@ public void resourceChanged(IResource resource) { @Override public void connected(String userChannel) { - Repository repository = org.eclipse.flux.core.Activator + RepositoryAdapter repository = org.eclipse.flux.core.Activator .getDefault().getRepository(); repository.addRepositoryListener(repositoryListener); diff --git a/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/LiveEditConnector.java b/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/LiveEditConnector.java index 95879f9..58f611b 100644 --- a/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/LiveEditConnector.java +++ b/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/LiveEditConnector.java @@ -44,7 +44,7 @@ import org.eclipse.flux.core.IRepositoryListener; import org.eclipse.flux.core.LiveEditCoordinator; import org.eclipse.flux.core.LiveEditCoordinator.ResourceData; -import org.eclipse.flux.core.Repository; +import org.eclipse.flux.core.RepositoryAdapter; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentListener; @@ -73,7 +73,7 @@ public class LiveEditConnector { private IResourceChangeListener workspaceListener; private IPartListener2 partListener; private ILiveEditConnector liveEditConnector; - private Repository repository; + private RepositoryAdapter repository; private ConcurrentMap resourceMappings; private ConcurrentMap documentMappings; @@ -81,7 +81,7 @@ public class LiveEditConnector { private ConcurrentHashMap pendingLiveEditStartedResponses; - public LiveEditConnector(LiveEditCoordinator liveEditCoordinator, Repository repository) { + public LiveEditConnector(LiveEditCoordinator liveEditCoordinator, RepositoryAdapter repository) { this.liveEditCoordinator = liveEditCoordinator; this.repository = repository; @@ -151,7 +151,7 @@ public void bufferContentReplaced(IFileBuffer buffer) { } // Send a message to get the latest edits. - Repository repository = LiveEditConnector.this.repository; + RepositoryAdapter repository = LiveEditConnector.this.repository; if (repository.isConnected(project)) { ConnectedProject connectedProject = repository.getProject(project); String hash = connectedProject.getHash(resourcePath); diff --git a/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncConnectHandler.java b/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncConnectHandler.java index dbe091e..4619225 100644 --- a/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncConnectHandler.java +++ b/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncConnectHandler.java @@ -19,7 +19,7 @@ import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.flux.core.Repository; +import org.eclipse.flux.core.RepositoryAdapter; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.ISources; @@ -37,7 +37,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException { ISelection selection = HandlerUtil.getCurrentSelection(event); IProject[] selectedProjects = getSelectedProjects(selection); - Repository repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); + RepositoryAdapter repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); if (repository != null) { for (IProject project : selectedProjects) { @@ -51,7 +51,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException { @Override public void setEnabled(Object evaluationContext) { - Repository repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); + RepositoryAdapter repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); if (repository != null && evaluationContext instanceof IEvaluationContext) { IEvaluationContext evalContext = (IEvaluationContext) evaluationContext; Object selection = evalContext.getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME); diff --git a/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncDisconnectHandler.java b/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncDisconnectHandler.java index 8cd465b..0dd1422 100644 --- a/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncDisconnectHandler.java +++ b/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncDisconnectHandler.java @@ -19,7 +19,7 @@ import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.flux.core.Repository; +import org.eclipse.flux.core.RepositoryAdapter; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.ISources; @@ -38,7 +38,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException { // selectedProjects[0].getLocalTimeStamp(); // selectedProjects[0].getFile(".project").getLocalTimeStamp(); - Repository repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); + RepositoryAdapter repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); if (repository != null) { for (IProject project : selectedProjects) { @@ -53,7 +53,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException { @Override public void setEnabled(Object evaluationContext) { - Repository repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); + RepositoryAdapter repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); if (repository != null && evaluationContext instanceof IEvaluationContext) { IEvaluationContext evalContext = (IEvaluationContext) evaluationContext; Object selection = evalContext.getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME); diff --git a/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncDownloadHandler.java b/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncDownloadHandler.java index 756a3bb..35f7bb7 100644 --- a/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncDownloadHandler.java +++ b/org.eclipse.flux.ui.integration/src/org/eclipse/flux/ui/integration/handlers/SyncDownloadHandler.java @@ -17,7 +17,7 @@ import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.core.DownloadProject; import org.eclipse.flux.core.DownloadProject.CompletionCallback; -import org.eclipse.flux.core.Repository; +import org.eclipse.flux.core.RepositoryAdapter; import org.eclipse.flux.ui.integration.FluxUiPlugin; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.LabelProvider; @@ -32,7 +32,7 @@ public class SyncDownloadHandler extends AbstractHandler { @Override public Object execute(final ExecutionEvent event) throws ExecutionException { - final Repository repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); + final RepositoryAdapter repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); final MessageConnector messagingConnector = org.eclipse.flux.core.Activator.getDefault().getMessageConnector(); if (repository == null || messagingConnector == null) { @@ -68,7 +68,7 @@ public void downloadComplete(IProject project) { @Override public boolean isEnabled() { - final Repository repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); + final RepositoryAdapter repository = org.eclipse.flux.core.Activator.getDefault().getRepository(); final MessageConnector messagingConnector = org.eclipse.flux.core.Activator.getDefault().getMessageConnector(); return repository != null && messagingConnector != null; } From e0b82c009698157033f9951a1a03f64f28bc38f7 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Mon, 15 Aug 2016 16:58:48 +0300 Subject: [PATCH 11/34] Methon toJson was rewritten Signed-off-by: Fjodor Vershinin --- .../eclipse/flux/core/RepositoryAdapter.java | 42 +++++++++---------- .../listeners/MetadataRequestHandler.java | 40 +++++++++--------- 2 files changed, 38 insertions(+), 44 deletions(-) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index ea2b792..a2a5279 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -26,6 +26,7 @@ import org.eclipse.flux.watcher.core.Repository; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; /** @@ -106,38 +107,33 @@ public void sendMetadataUpdate(IResource resource) { message.put("type", "marker"); IMarker[] markers = resource.findMarkers(null, true, IResource.DEPTH_INFINITE); - String markerJSON = toJSON(markers); - JSONArray content = new JSONArray(markerJSON); + JSONArray content = toJSON(markers); message.put("metadata", content); - repository.getMessageBus().sendMessages(new FluxMessage(FluxMessageType.METADATA_CHANGED, message)); } catch (Exception e) { } } - public String toJSON(IMarker[] markers) { - StringBuilder result = new StringBuilder(); - boolean flag = false; - result.append("["); - for (IMarker m : markers) { - if (flag) { - result.append(","); + public JSONArray toJSON(IMarker[] markers) throws JSONException{ + JSONArray objects = new JSONArray(); + for(IMarker marker : markers){ + JSONObject object = new JSONObject(); + object.put("description", marker.getAttribute("message", "")); + object.put("line", marker.getAttribute("lineNumber", 0)); + switch(marker.getAttribute("severity", IMarker.SEVERITY_WARNING)){ + case IMarker.SEVERITY_WARNING: + object.put("severity", marker.getAttribute("severity", "warning")); + break; + case IMarker.SEVERITY_ERROR: + object.put("severity", marker.getAttribute("severity", "error")); + break; } - - result.append("{"); - result.append("\"description\":" + JSONObject.quote(m.getAttribute("message", ""))); - result.append(",\"line\":" + m.getAttribute("lineNumber", 0)); - result.append(",\"severity\":\"" + (m.getAttribute("severity", IMarker.SEVERITY_WARNING) == IMarker.SEVERITY_ERROR ? "error" : "warning") - + "\""); - result.append(",\"start\":" + m.getAttribute("charStart", 0)); - result.append(",\"end\":" + m.getAttribute("charEnd", 0)); - result.append("}"); - - flag = true; + object.put("start", marker.getAttribute("charStart", 0)); + object.put("end", marker.getAttribute("charEnd", 0)); + objects.put(object); } - result.append("]"); - return result.toString(); + return objects; } public void addRepositoryListener(IRepositoryListener listener) { diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/MetadataRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/MetadataRequestHandler.java index 31af94a..dccafcd 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/MetadataRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/MetadataRequestHandler.java @@ -15,6 +15,7 @@ import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; import com.google.inject.Singleton; @@ -35,33 +36,30 @@ public void onMessage(FluxMessage message, Repository repository) throws Excepti Path path = new Path(MessageFormat.format("{0}/{1}", projectName, resourcePath)); IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); content.put("type", "marker"); - content.put("metadata", new JSONArray(toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE)))); + content.put("metadata", toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE))); message.source().sendMessage(new FluxMessage(FluxMessageType.GET_METADATA_RESPONSE, content)); } } } - private String toJSON(IMarker[] markers) { - StringBuilder result = new StringBuilder(); - boolean flag = false; - result.append("["); - for (IMarker m : markers) { - if (flag) { - result.append(","); + public JSONArray toJSON(IMarker[] markers) throws JSONException{ + JSONArray objects = new JSONArray(); + for(IMarker marker : markers){ + JSONObject object = new JSONObject(); + object.put("description", marker.getAttribute("message", "")); + object.put("line", marker.getAttribute("lineNumber", 0)); + switch(marker.getAttribute("severity", IMarker.SEVERITY_WARNING)){ + case IMarker.SEVERITY_WARNING: + object.put("severity", marker.getAttribute("severity", "warning")); + break; + case IMarker.SEVERITY_ERROR: + object.put("severity", marker.getAttribute("severity", "error")); + break; } - - result.append("{"); - result.append("\"description\":" + JSONObject.quote(m.getAttribute("message", ""))); - result.append(",\"line\":" + m.getAttribute("lineNumber", 0)); - result.append(",\"severity\":\"" + (m.getAttribute("severity", IMarker.SEVERITY_WARNING) == IMarker.SEVERITY_ERROR ? "error" : "warning") - + "\""); - result.append(",\"start\":" + m.getAttribute("charStart", 0)); - result.append(",\"end\":" + m.getAttribute("charEnd", 0)); - result.append("}"); - - flag = true; + object.put("start", marker.getAttribute("charStart", 0)); + object.put("end", marker.getAttribute("charEnd", 0)); + objects.put(object); } - result.append("]"); - return result.toString(); + return objects; } } \ No newline at end of file From cbb159d93b3be41bb9fcfefaca2eee3fca54a2b1 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Mon, 15 Aug 2016 18:33:42 +0300 Subject: [PATCH 12/34] Refactored handlers Signed-off-by: Fjodor Vershinin --- .../src/org/eclipse/flux/core/Activator.java | 5 +++-- .../org/eclipse/flux/core/RepositoryAdapter.java | 15 +++++++++++---- .../EclipseResourceResponseHandler.java} | 4 ++-- .../MetadataRequestHandler.java | 2 +- 4 files changed, 17 insertions(+), 9 deletions(-) rename org.eclipse.flux.core/src/org/eclipse/flux/core/{listeners/ResourceListener.java => handlers/EclipseResourceResponseHandler.java} (89%) rename org.eclipse.flux.core/src/org/eclipse/flux/core/{listeners => handlers}/MetadataRequestHandler.java (98%) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java index b01d8d9..39d14ce 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java @@ -38,6 +38,7 @@ import org.eclipse.flux.core.internal.CloudSyncMetadataListener; import org.eclipse.flux.core.util.ExceptionUtil; import org.eclipse.flux.watcher.core.Credentials; +import org.eclipse.flux.watcher.core.Repository; import org.eclipse.flux.watcher.core.RepositoryModule; import org.eclipse.flux.watcher.fs.JDKProjectModule; import org.osgi.framework.BundleContext; @@ -71,7 +72,7 @@ public class Activator extends Plugin { private IRepositoryListener repositoryListener; private IResourceChangeListener workspaceListener; - private org.eclipse.flux.watcher.core.Repository fluxRepository; + private Repository fluxRepository; private final IChannelListener SERVICE_STARTER = new IChannelListener() { @Override @@ -117,7 +118,7 @@ public void start(BundleContext context) throws Exception { final String userChannel = lazyStart ? MessageConstants.SUPER_USER : channel; Injector injector = Guice.createInjector(new RepositoryModule(), new JDKProjectModule()); - fluxRepository = injector.getInstance(org.eclipse.flux.watcher.core.Repository.class); + fluxRepository = injector.getInstance(Repository.class); fluxRepository.addRemote(new URL(host), new Credentials(login, token)); //Connecting to channel done asynchronously. To avoid blocking plugin state initialization. FluxClient.DEFAULT_INSTANCE.getExecutor().execute(new Runnable() { diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index a2a5279..a84bd92 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -19,9 +19,10 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.flux.core.listeners.MetadataRequestHandler; -import org.eclipse.flux.core.listeners.ResourceListener; +import org.eclipse.flux.core.handlers.MetadataRequestHandler; +import org.eclipse.flux.core.handlers.EclipseResourceResponseHandler; import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageBus; import org.eclipse.flux.watcher.core.FluxMessageType; import org.eclipse.flux.watcher.core.Repository; import org.eclipse.flux.watcher.core.spi.Project; @@ -40,15 +41,21 @@ public class RepositoryAdapter { private Collection repositoryListeners; private Repository repository; + private FluxMessageBus messageBus; public RepositoryAdapter(Repository repository, String user) { this.repository = repository; + this.messageBus = repository.getMessageBus(); this.username = user; this.syncedProjects = new ConcurrentHashMap(); this.repositoryListeners = new ConcurrentLinkedDeque<>(); - repository.getMessageBus().addMessageHandler(new ResourceListener()); - repository.getMessageBus().addMessageHandler(new MetadataRequestHandler()); + messageBus.addMessageHandler(new EclipseResourceResponseHandler()); + messageBus.addMessageHandler(new MetadataRequestHandler()); + } + + public FluxMessageBus getMessageBus(){ + return this.messageBus; } public String getUsername() { diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceListener.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/EclipseResourceResponseHandler.java similarity index 89% rename from org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceListener.java rename to org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/EclipseResourceResponseHandler.java index 5772594..264421a 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceListener.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/EclipseResourceResponseHandler.java @@ -1,4 +1,4 @@ -package org.eclipse.flux.core.listeners; +package org.eclipse.flux.core.handlers; import java.text.MessageFormat; @@ -16,7 +16,7 @@ @Singleton @FluxMessageTypes(FluxMessageType.GET_RESOURCE_RESPONSE) -public class ResourceListener implements FluxMessageHandler { +public class EclipseResourceResponseHandler implements FluxMessageHandler { @Override public void onMessage(FluxMessage message, Repository repository) throws Exception { diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/MetadataRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java similarity index 98% rename from org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/MetadataRequestHandler.java rename to org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java index dccafcd..1b4204b 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/MetadataRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java @@ -1,4 +1,4 @@ -package org.eclipse.flux.core.listeners; +package org.eclipse.flux.core.handlers; import java.text.MessageFormat; From 8503e4bed1e505ad688941875f72f6c133d522ff Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Wed, 17 Aug 2016 00:01:07 +0300 Subject: [PATCH 13/34] Fixed move issue for linux Signed-off-by: Fjodor Vershinin --- node.server/repository-message-api.js | 2 +- .../eclipse/flux/watcher/fs/JDKProjectWatchService.java | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/node.server/repository-message-api.js b/node.server/repository-message-api.js index 5d8222b..5ac3b5d 100644 --- a/node.server/repository-message-api.js +++ b/node.server/repository-message-api.js @@ -236,7 +236,7 @@ MessagesRepository.prototype.resourceCreated = function(data) { var type = data.type; this.repository.hasResource(username, projectName, resource, function(err, resourceExists) { - if (err === null && !resourceExists) { + if (err === null) { this.socket.emit('getResourceRequest', { 'callback_id' : 0, 'username' : username, diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java index a3059e0..8685ff0 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java @@ -249,7 +249,13 @@ private Resource pathToResource(Kind kind, Project project, Path resourceP final Path projectPath = fileSystem.getPath(project.path()); final String relativeResourcePath = projectPath.relativize(resourcePath).toString(); - final long timestamp = exists ? getLastModifiedTime(resourcePath).toMillis() : System.currentTimeMillis(); + long timestamp; + if (exists){ + timestamp = getLastModifiedTime(resourcePath).toMillis(); + } + else { + timestamp = (System.currentTimeMillis()); + } if (exists) { final boolean isDirectory = isDirectory(resourcePath); From 18a6f34a4193c0b7392520d76770585096646fd4 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Thu, 18 Aug 2016 18:31:42 +0300 Subject: [PATCH 14/34] Temporary fix for vim issue Signed-off-by: Fjodor Vershinin --- .../watcher/fs/JDKProjectWatchService.java | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java index 8685ff0..d5e1a23 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java @@ -14,6 +14,7 @@ import org.eclipse.flux.watcher.core.RepositoryEventBus; import org.eclipse.flux.watcher.core.RepositoryEventType; import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.eclipse.flux.watcher.core.spi.Project; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; @@ -22,6 +23,7 @@ import java.nio.file.ClosedWatchServiceException; import java.nio.file.FileSystem; import java.nio.file.FileVisitResult; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.WatchEvent; @@ -38,7 +40,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static java.nio.file.FileVisitResult.CONTINUE; import static java.nio.file.Files.exists; -import static java.nio.file.Files.getLastModifiedTime; import static java.nio.file.Files.isDirectory; import static java.nio.file.Files.readAllBytes; import static java.nio.file.Files.walkFileTree; @@ -244,31 +245,42 @@ private Resource pathToResource(Kind kind, Project project, Path resourceP try { - final boolean exists = exists(resourcePath); - checkArgument(kind == ENTRY_DELETE || exists); - - final Path projectPath = fileSystem.getPath(project.path()); - final String relativeResourcePath = projectPath.relativize(resourcePath).toString(); - long timestamp; - if (exists){ - timestamp = getLastModifiedTime(resourcePath).toMillis(); - } - else { - timestamp = (System.currentTimeMillis()); + Path projectPath = fileSystem.getPath(project.path()); + String relativeResourcePath = projectPath.relativize(resourcePath).toString(); + long timestamp = getLastModifiedTime(resourcePath); + switch (getResourceType(resourcePath)) { + case FILE: + return Resource.newFile(relativeResourcePath, timestamp, readAllBytes(resourcePath)); + case FOLDER: + return Resource.newFolder(relativeResourcePath, timestamp); + default: + return Resource.newUnknown(relativeResourcePath, timestamp); } + } catch (IOException e) { + throw new RuntimeException(e); + } + } - if (exists) { - final boolean isDirectory = isDirectory(resourcePath); - return isDirectory ? Resource.newFolder(relativeResourcePath, timestamp) - : Resource.newFile(relativeResourcePath, timestamp, readAllBytes(resourcePath)); + private long getLastModifiedTime(Path resourcePath) { + try { + return Files.getLastModifiedTime(resourcePath).toMillis() / 1000 * 1000; + } catch (IOException | NullPointerException e) { + return System.currentTimeMillis() / 1000 * 1000; + } + } + private ResourceType getResourceType(Path path) { + boolean isExists = Files.exists(path); + boolean isDirectory = Files.isDirectory(path); + if (isExists) { + if (isDirectory) { + return ResourceType.FOLDER; } else { - return Resource.newUnknown(relativeResourcePath, timestamp); + return ResourceType.FILE; } - } catch (IOException e) { - throw new RuntimeException(e); } + return ResourceType.UNKNOWN; } /** From 6cd36416f6b413e4fe97e8a3b1b0bdc5c072084c Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Thu, 18 Aug 2016 16:00:10 +0300 Subject: [PATCH 15/34] Refactored: Changed enum filelds to static final Signed-off-by: Fjodor Vershinin --- .../EclipseResourceResponseHandler.java | 4 +- .../core/handlers/MetadataRequestHandler.java | 8 +- .../flux/watcher/core/FluxConnection.java | 18 +- .../flux/watcher/core/FluxMessage.java | 171 +++++++++--------- .../flux/watcher/core/FluxMessageBus.java | 8 +- .../eclipse/flux/watcher/core/Repository.java | 6 +- .../internal/GetProjectRequestHandler.java | 26 +-- .../internal/GetProjectResponseHandler.java | 30 +-- .../internal/GetResourceRequestHandler.java | 32 ++-- .../internal/GetResourceResponseHandler.java | 26 +-- .../ProjectResourceCreatedListener.java | 10 +- .../ProjectResourceDeletedListener.java | 6 +- .../ProjectResourceModifiedListener.java | 8 +- .../core/internal/ResourceChangedHandler.java | 20 +- .../core/internal/ResourceCreatedHandler.java | 28 ++- .../core/internal/ResourceDeletedHandler.java | 8 +- 16 files changed, 200 insertions(+), 209 deletions(-) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/EclipseResourceResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/EclipseResourceResponseHandler.java index 264421a..57a1ad2 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/EclipseResourceResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/EclipseResourceResponseHandler.java @@ -20,8 +20,8 @@ public class EclipseResourceResponseHandler implements FluxMessageHandler { @Override public void onMessage(FluxMessage message, Repository repository) throws Exception { - final String resourcePath = message.content().getString("resource"); - final String project = message.content().getString("project"); + final String resourcePath = message.getContent().getString("resource"); + final String project = message.getContent().getString("project"); Path path = new Path(MessageFormat.format("{0}/{1}", project, resourcePath)); IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); file.refreshLocal(IResource.DEPTH_ZERO, null); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java index 1b4204b..a9be0d7 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java @@ -26,9 +26,9 @@ public class MetadataRequestHandler implements FluxMessageHandler { @Override public void onMessage(FluxMessage message, Repository repository) throws Exception { - JSONObject content = message.content(); - String projectName = message.content().getString("project"); - String resourcePath = message.content().getString("resource"); + JSONObject content = message.getContent(); + String projectName = message.getContent().getString("project"); + String resourcePath = message.getContent().getString("resource"); Project project = repository.getProject(projectName); if(project != null){ Resource resource = project.getResource(resourcePath); @@ -37,7 +37,7 @@ public void onMessage(FluxMessage message, Repository repository) throws Excepti IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); content.put("type", "marker"); content.put("metadata", toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE))); - message.source().sendMessage(new FluxMessage(FluxMessageType.GET_METADATA_RESPONSE, content)); + message.getSource().sendMessage(new FluxMessage(FluxMessageType.GET_METADATA_RESPONSE, content)); } } } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxConnection.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxConnection.java index d3b2a48..da4c617 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxConnection.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxConnection.java @@ -82,7 +82,7 @@ public void onDisconnect() { public void onConnect() { try { - final JSONObject content = new JSONObject().put(CHANNEL.value(), credentials.username()); + final JSONObject content = new JSONObject().put(CHANNEL, credentials.username()); socket.emit(CONNECT_TO_CHANNEL.value(), new IOAcknowledge() { @Override public void ack(Object... objects) { @@ -90,7 +90,7 @@ public void ack(Object... objects) { final JSONObject ack = (JSONObject)objects[0]; try { - if (ack.has(CONNECTED_TO_CHANNEL.value()) && ack.getBoolean(CONNECTED_TO_CHANNEL.value())) { + if (ack.has(CONNECTED_TO_CHANNEL) && ack.getBoolean(CONNECTED_TO_CHANNEL)) { return; } @@ -156,16 +156,16 @@ void close() { public void sendMessage(FluxMessage message) { checkNotNull(message); - final JSONObject content = message.content(); + final JSONObject content = message.getContent(); try { - if (!content.has(USERNAME.value())) { - content.put(USERNAME.value(), credentials.username()); + if (!content.has(USERNAME)) { + content.put(USERNAME, credentials.username()); } - if (!content.has(CALLBACK_ID.value())) { - if (message.type() == GET_RESOURCE_REQUEST || message.type() == GET_PROJECT_REQUEST) { - content.put(CALLBACK_ID.value(), messageBus.id()); + if (!content.has(CALLBACK_ID)) { + if (message.getType() == GET_RESOURCE_REQUEST || message.getType() == GET_PROJECT_REQUEST) { + content.put(CALLBACK_ID, messageBus.id()); } } @@ -173,6 +173,6 @@ public void sendMessage(FluxMessage message) { throw new RuntimeException(e); } - socket.emit(message.type().value(), message.content()); + socket.emit(message.getType().value(), message.getContent()); } } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java index 42646eb..b0463b8 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java @@ -20,99 +20,92 @@ * @author Kevin Pollet */ public class FluxMessage { - private final FluxConnection source; - private final FluxMessageType type; - private final JSONObject content; + /** + * Fields used in {@link org.json.JSONObject} of Flux messages. + * + * @author Kevin Pollet + */ + public static interface Fields { + public static final String CALLBACK_ID = "callback_id"; + public static final String CHANNEL = "channel"; + public static final String CONNECTED_TO_CHANNEL = "connectedToChannel"; + public static final String CONTENT = "content"; + public static final String DELETED = "deleted"; + public static final String FILES = "files"; + public static final String HASH = "hash"; + public static final String INCLUDE_DELETED = "includeDeleted"; + public static final String PATH = "path"; + public static final String PROJECT = "project"; + public static final String REQUEST_SENDER_ID = "requestSenderID"; + public static final String RESOURCE = "resource"; + public static final String TIMESTAMP = "timestamp"; + public static final String TYPE = "type"; + public static final String USERNAME = "username"; + } - /** - * Constructs an instance of {@link FluxMessage}. - * - * @param type - * the {@link FluxMessageType}. - * @param content - * the message {@link org.json.JSONObject} content. - * @throws java.lang.NullPointerException - * if {@code type} or {@code content} parameter is {@code null}. - */ - public FluxMessage(FluxMessageType type, JSONObject content) { - this(null, type, content); - } + private final FluxConnection source; + private final FluxMessageType type; + private final JSONObject content; - /** - * Constructs an instance of {@link FluxMessage}. - * - * @param source - * the {@code FluxConnection} where the {@link FluxMessage} comes from. - * @param type - * the {@link FluxMessageType}. - * @param content - * the message {@link org.json.JSONObject} content. - * @throws java.lang.NullPointerException - * if {@code type} or {@code content} parameter is {@code null}. - */ - public FluxMessage(FluxConnection source, FluxMessageType type, JSONObject content) { - this.source = source; - this.type = checkNotNull(type); - this.content = checkNotNull(content); - } + /** + * Constructs an instance of {@link FluxMessage}. + * + * @param type + * the {@link FluxMessageType}. + * @param content + * the message {@link org.json.JSONObject} content. + * @throws java.lang.NullPointerException + * if {@code type} or {@code content} parameter is {@code null}. + */ + public FluxMessage(FluxMessageType type, JSONObject content) { + this(null, type, content); + } - /** - * Returns the {@code FluxConnection} where the {@link FluxMessage} comes from. - * - * @return the {@code FluxConnection} where the {@link FluxMessage} comes from or {@code null} if none. - */ - public FluxConnection source() { - return source; - } + /** + * Constructs an instance of {@link FluxMessage}. + * + * @param source + * the {@code FluxConnection} where the {@link FluxMessage} comes + * from. + * @param type + * the {@link FluxMessageType}. + * @param content + * the message {@link org.json.JSONObject} content. + * @throws java.lang.NullPointerException + * if {@code type} or {@code content} parameter is {@code null}. + */ + public FluxMessage(FluxConnection source, FluxMessageType type, JSONObject content) { + this.source = source; + this.type = checkNotNull(type); + this.content = checkNotNull(content); + } - /** - * Returns the {@link FluxMessageType}. - * - * @return the {@link FluxMessageType}, never {@code null}. - */ - public FluxMessageType type() { - return type; - } + /** + * Returns the {@code FluxConnection} where the {@link FluxMessage} comes + * from. + * + * @return the {@code FluxConnection} where the {@link FluxMessage} comes + * from or {@code null} if none. + */ + public FluxConnection getSource() { + return source; + } - /** - * Returns the {@link FluxMessage} content. - * - * @return the {@link FluxMessage} content, never {@code null}. - */ - public JSONObject content() { - return content; - } + /** + * Returns the {@link FluxMessageType}. + * + * @return the {@link FluxMessageType}, never {@code null}. + */ + public FluxMessageType getType() { + return type; + } - /** - * Fields used in {@link org.json.JSONObject} of Flux messages. - * - * @author Kevin Pollet - */ - public enum Fields { - CALLBACK_ID("callback_id"), - CHANNEL("channel"), - CONNECTED_TO_CHANNEL("connectedToChannel"), - CONTENT("content"), - DELETED("deleted"), - FILES("files"), - HASH("hash"), - INCLUDE_DELETED("includeDeleted"), - PATH("path"), - PROJECT("project"), - REQUEST_SENDER_ID("requestSenderID"), - RESOURCE("resource"), - TIMESTAMP("timestamp"), - TYPE("type"), - USERNAME("username"); - - private final String value; - - Fields(String value) { - this.value = value; - } - - public String value() { - return value; - } - } + /** + * Returns the {@link FluxMessage} content. + * + * @return the {@link FluxMessage} content, never {@code null}. + */ + public JSONObject getContent() { + return content; + } } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageBus.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageBus.java index 3bdf051..22ab8bf 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageBus.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageBus.java @@ -177,14 +177,14 @@ public void sendMessages(FluxMessage... messages) { public void messageReceived(FluxMessage message) { checkNotNull(message); - if (message.type() == GET_RESOURCE_RESPONSE || message.type() == GET_PROJECT_RESPONSE) { - final JSONObject content = message.content(); - if (content.optInt(CALLBACK_ID.value()) != id) { + if (message.getType() == GET_RESOURCE_RESPONSE || message.getType() == GET_PROJECT_RESPONSE) { + final JSONObject content = message.getContent(); + if (content.optInt(CALLBACK_ID) != id) { return; } } - final Set messageHandlers = getMessageHandlersFor(message.type().value()); + final Set messageHandlers = getMessageHandlersFor(message.getType().value()); for (FluxMessageHandler oneMessageHandler : messageHandlers) { try { diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java index 283d052..bbd8f2f 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java @@ -115,10 +115,10 @@ public Project addProject(String projectId, String projectPath) { try { - JSONObject content = new JSONObject().put(PROJECT.value(), projectId); + JSONObject content = new JSONObject().put(PROJECT, projectId); messageBus.sendMessages(new FluxMessage(PROJECT_CONNECTED, content)); - content = new JSONObject().put(PROJECT.value(), projectId).put(INCLUDE_DELETED.value(), true); + content = new JSONObject().put(PROJECT, projectId).put(INCLUDE_DELETED, true); messageBus.sendMessages(new FluxMessage(GET_PROJECT_REQUEST, content)); } catch (JSONException e) { @@ -143,7 +143,7 @@ public Project removeProject(String projectId) { try { - final JSONObject content = new JSONObject().put(PROJECT.value(), projectId); + final JSONObject content = new JSONObject().put(PROJECT, projectId); messageBus.sendMessages(new FluxMessage(PROJECT_DISCONNECTED, content)); } catch (JSONException e) { diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java index 4c71e77..be3f2ab 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java @@ -44,29 +44,29 @@ public final class GetProjectRequestHandler implements FluxMessageHandler { @Override public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.content(); - final int callbackId = request.getInt(CALLBACK_ID.value()); - final String requestSenderId = request.getString(REQUEST_SENDER_ID.value()); - final String projectName = request.getString(PROJECT.value()); + final JSONObject request = message.getContent(); + final int callbackId = request.getInt(CALLBACK_ID); + final String requestSenderId = request.getString(REQUEST_SENDER_ID); + final String projectName = request.getString(PROJECT); final Project project = repository.getProject(projectName); if (project != null) { final JSONArray files = new JSONArray(); for (Resource oneResource : project.getResources()) { files.put(new JSONObject() - .put(PATH.value(), oneResource.path()) - .put(TIMESTAMP.value(), oneResource.timestamp()) - .put(HASH.value(), oneResource.hash()) - .put(TYPE.value(), oneResource.type().name().toLowerCase())); + .put(PATH, oneResource.path()) + .put(TIMESTAMP, oneResource.timestamp()) + .put(HASH, oneResource.hash()) + .put(TYPE, oneResource.type().name().toLowerCase())); } final JSONObject content = new JSONObject() - .put(CALLBACK_ID.value(), callbackId) - .put(REQUEST_SENDER_ID.value(), requestSenderId) - .put(PROJECT.value(), projectName) - .put(FILES.value(), files); + .put(CALLBACK_ID, callbackId) + .put(REQUEST_SENDER_ID, requestSenderId) + .put(PROJECT, projectName) + .put(FILES, files); - message.source() + message.getSource() .sendMessage(new FluxMessage(GET_PROJECT_RESPONSE, content)); } } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java index 5376868..b512226 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java @@ -48,20 +48,20 @@ public final class GetProjectResponseHandler implements FluxMessageHandler { @Override public void onMessage(FluxMessage message, Repository repository) throws Exception { - final JSONObject request = message.content(); - final String projectName = request.getString(PROJECT.value()); - final JSONArray files = request.getJSONArray(FILES.value()); - final JSONArray deleted = request.optJSONArray(DELETED.value()); + final JSONObject request = message.getContent(); + final String projectName = request.getString(PROJECT); + final JSONArray files = request.getJSONArray(FILES); + final JSONArray deleted = request.optJSONArray(DELETED); final Project project = repository.getProject(projectName); if (project != null) { // new files for (int i = 0; i < files.length(); i++) { final JSONObject resource = files.getJSONObject(i); - final String resourcePath = resource.getString(PATH.value()); - final long resourceTimestamp = resource.getLong(TIMESTAMP.value()); - final ResourceType resourceType = ResourceType.valueOf(resource.optString(TYPE.value(), UNKNOWN.name()).toUpperCase()); - final String resourceHash = resource.optString(HASH.value(), "0"); + final String resourcePath = resource.getString(PATH); + final long resourceTimestamp = resource.getLong(TIMESTAMP); + final ResourceType resourceType = ResourceType.valueOf(resource.optString(TYPE, UNKNOWN.name()).toUpperCase()); + final String resourceHash = resource.optString(HASH, "0"); final Resource localResource = project.getResource(resourcePath); if (resourceType == FILE) { @@ -70,12 +70,12 @@ public void onMessage(FluxMessage message, Repository repository) throws Excepti && !Objects.equals(resourceHash, localResource.hash())) { final JSONObject content = new JSONObject() - .put(PROJECT.value(), projectName) - .put(RESOURCE.value(), resourcePath) - .put(TIMESTAMP.value(), resourceTimestamp) - .put(HASH.value(), resourceHash); + .put(PROJECT, projectName) + .put(RESOURCE, resourcePath) + .put(TIMESTAMP, resourceTimestamp) + .put(HASH, resourceHash); - message.source() + message.getSource() .sendMessage(new FluxMessage(GET_RESOURCE_REQUEST, content)); } @@ -88,8 +88,8 @@ public void onMessage(FluxMessage message, Repository repository) throws Excepti if (deleted != null) { for (int i = 0; i < deleted.length(); i++) { final JSONObject resource = deleted.getJSONObject(i); - final String resourcePath = resource.getString(PATH.value()); - final long resourceTimestamp = resource.getLong(TIMESTAMP.value()); + final String resourcePath = resource.getString(PATH); + final long resourceTimestamp = resource.getLong(TIMESTAMP); final Resource localResource = project.getResource(resourcePath); if (localResource != null && localResource.timestamp() < resourceTimestamp) { diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java index bb35102..0a7ffaa 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java @@ -44,34 +44,34 @@ public final class GetResourceRequestHandler implements FluxMessageHandler { @Override public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.content(); - final int callbackId = request.getInt(CALLBACK_ID.value()); - final String requestSenderId = request.getString(REQUEST_SENDER_ID.value()); - final String projectName = request.getString(PROJECT.value()); - final String resourcePath = request.getString(RESOURCE.value()); + final JSONObject request = message.getContent(); + final int callbackId = request.getInt(CALLBACK_ID); + final String requestSenderId = request.getString(REQUEST_SENDER_ID); + final String projectName = request.getString(PROJECT); + final String resourcePath = request.getString(RESOURCE); final Project project = repository.getProject(projectName); if (project != null) { final Resource resource = project.getResource(resourcePath); // compare the time stamp and allow a nearly difference for now TODO find out why CodenvyVFS -> Eclipse has different timestamp - long requestTimeStamp = request.has(TIMESTAMP.value()) ? request.getLong(TIMESTAMP.value()) : 0; + long requestTimeStamp = request.has(TIMESTAMP) ? request.getLong(TIMESTAMP) : 0; long resourceTimeStamp = resource.timestamp(); - if (!request.has(TIMESTAMP.value()) || Math.abs(requestTimeStamp - resourceTimeStamp) < 10000) { + if (!request.has(TIMESTAMP) || Math.abs(requestTimeStamp - resourceTimeStamp) < 10000) { final JSONObject content = new JSONObject() - .put(CALLBACK_ID.value(), callbackId) - .put(REQUEST_SENDER_ID.value(), requestSenderId) - .put(PROJECT.value(), projectName) - .put(RESOURCE.value(), resourcePath) - .put(TIMESTAMP.value(), resourceTimeStamp) - .put(HASH.value(), resource.hash()) - .put(TYPE.value(), resource.type().name().toLowerCase()); + .put(CALLBACK_ID, callbackId) + .put(REQUEST_SENDER_ID, requestSenderId) + .put(PROJECT, projectName) + .put(RESOURCE, resourcePath) + .put(TIMESTAMP, resourceTimeStamp) + .put(HASH, resource.hash()) + .put(TYPE, resource.type().name().toLowerCase()); if (resource.type() == FILE) { - content.put(CONTENT.value(), new String(resource.content())); + content.put(CONTENT, new String(resource.content())); } - message.source() + message.getSource() .sendMessage(new FluxMessage(GET_RESOURCE_RESPONSE, content)); } } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java index 656bfa4..742d433 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java @@ -43,16 +43,16 @@ public final class GetResourceResponseHandler implements FluxMessageHandler { @Override public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.content(); - final String projectName = request.getString(PROJECT.value()); - final String resourcePath = request.getString(RESOURCE.value()); - final long resourceTimestamp = request.getLong(TIMESTAMP.value()); - final String resourceHash = request.getString(HASH.value()); - final String resourceContent = request.getString(CONTENT.value()); + final JSONObject request = message.getContent(); + final String projectName = request.getString(PROJECT); + final String resourcePath = request.getString(RESOURCE); + final long resourceTimestamp = request.getLong(TIMESTAMP); + final String resourceHash = request.getString(HASH); + final String resourceContent = request.getString(CONTENT); final Project project = repository.getProject(projectName); if (project != null) { - final ResourceType resourceType = ResourceType.valueOf(request.getString(TYPE.value()).toUpperCase()); + final ResourceType resourceType = ResourceType.valueOf(request.getString(TYPE).toUpperCase()); if (resourceType == FILE) { boolean isResourceStored = false; @@ -70,13 +70,13 @@ public void onMessage(FluxMessage message, Repository repository) throws JSONExc if (isResourceStored) { final JSONObject content = new JSONObject() - .put(PROJECT.value(), projectName) - .put(RESOURCE.value(), resourcePath) - .put(TIMESTAMP.value(), resourceTimestamp) - .put(HASH.value(), resourceHash) - .put(TYPE.value(), resourceType.name().toLowerCase()); + .put(PROJECT, projectName) + .put(RESOURCE, resourcePath) + .put(TIMESTAMP, resourceTimestamp) + .put(HASH, resourceHash) + .put(TYPE, resourceType.name().toLowerCase()); - message.source() + message.getSource() .sendMessage(new FluxMessage(RESOURCE_STORED, content)); } } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java index 9d3a7a1..edeadea 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java @@ -58,11 +58,11 @@ public final class ProjectResourceCreatedListener implements RepositoryListener @Override public void onEvent(RepositoryEvent event) throws JSONException { final JSONObject content = new JSONObject() - .put(PROJECT.value(), event.project().id()) - .put(RESOURCE.value(), event.resource().path()) - .put(TIMESTAMP.value(), event.resource().timestamp()) - .put(HASH.value(), event.resource().hash()) - .put(TYPE.value(), event.resource().type().name().toLowerCase()); + .put(PROJECT, event.project().id()) + .put(RESOURCE, event.resource().path()) + .put(TIMESTAMP, event.resource().timestamp()) + .put(HASH, event.resource().hash()) + .put(TYPE, event.resource().type().name().toLowerCase()); messageBus.sendMessages(new FluxMessage(RESOURCE_CREATED, content), new FluxMessage(RESOURCE_STORED, content)); } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java index 519a032..3a3f0c1 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java @@ -55,9 +55,9 @@ public final class ProjectResourceDeletedListener implements RepositoryListener @Override public void onEvent(RepositoryEvent event) throws JSONException { final JSONObject content = new JSONObject() - .put(PROJECT.value(), event.project().id()) - .put(RESOURCE.value(), event.resource().path()) - .put(TIMESTAMP.value(), event.resource().timestamp()); + .put(PROJECT, event.project().id()) + .put(RESOURCE, event.resource().path()) + .put(TIMESTAMP, event.resource().timestamp()); messageBus.sendMessages(new FluxMessage(RESOURCE_DELETED, content)); } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java index 4d242ee..5208c73 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java @@ -59,10 +59,10 @@ public final class ProjectResourceModifiedListener implements RepositoryListener public void onEvent(RepositoryEvent event) throws JSONException { if (event.resource().type() == FILE) { final JSONObject content = new JSONObject() - .put(PROJECT.value(), event.project().id()) - .put(RESOURCE.value(), event.resource().path()) - .put(TIMESTAMP.value(), event.resource().timestamp()) - .put(HASH.value(), event.resource().hash()); + .put(PROJECT, event.project().id()) + .put(RESOURCE, event.resource().path()) + .put(TIMESTAMP, event.resource().timestamp()) + .put(HASH, event.resource().hash()); messageBus.sendMessages(new FluxMessage(RESOURCE_CHANGED, content), new FluxMessage(RESOURCE_STORED, content)); } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java index e40bb70..3450e69 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java @@ -39,11 +39,11 @@ public final class ResourceChangedHandler implements FluxMessageHandler { @Override public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.content(); - final String projectName = request.getString(PROJECT.value()); - final String resourcePath = request.getString(RESOURCE.value()); - final long resourceTimestamp = request.getLong(TIMESTAMP.value()); - final String resourceHash = request.getString(HASH.value()); + final JSONObject request = message.getContent(); + final String projectName = request.getString(PROJECT); + final String resourcePath = request.getString(RESOURCE); + final long resourceTimestamp = request.getLong(TIMESTAMP); + final String resourceHash = request.getString(HASH); final Project project = repository.getProject(projectName); if (project != null) { @@ -54,12 +54,12 @@ public void onMessage(FluxMessage message, Repository repository) throws JSONExc && localResource.timestamp() < resourceTimestamp) { final JSONObject content = new JSONObject() - .put(PROJECT.value(), projectName) - .put(RESOURCE.value(), resourcePath) - .put(TIMESTAMP.value(), resourceTimestamp) - .put(HASH.value(), resourceHash); + .put(PROJECT, projectName) + .put(RESOURCE, resourcePath) + .put(TIMESTAMP, resourceTimestamp) + .put(HASH, resourceHash); - message.source() + message.getSource() .sendMessage(new FluxMessage(GET_RESOURCE_REQUEST, content)); } } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java index 1ae676c..234f2a1 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java @@ -43,29 +43,27 @@ public final class ResourceCreatedHandler implements FluxMessageHandler { @Override public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.content(); - final String projectName = request.getString(PROJECT.value()); - final String resourcePath = request.getString(RESOURCE.value()); - final long resourceTimestamp = request.getLong(TIMESTAMP.value()); - final String resourceHash = request.getString(HASH.value()); + final JSONObject request = message.getContent(); + final String projectName = request.getString(PROJECT); + final String resourcePath = request.getString(RESOURCE); + final long resourceTimestamp = request.getLong(TIMESTAMP); + final String resourceHash = request.getString(HASH); final Project project = repository.getProject(projectName); if (project != null && project.getResource(resourcePath) == null) { - final ResourceType resourceType = ResourceType.valueOf(request.getString(TYPE.value()).toUpperCase()); + final ResourceType resourceType = ResourceType.valueOf(request.getString(TYPE).toUpperCase()); if (resourceType == FOLDER) { final Resource folder = Resource.newFolder(resourcePath, resourceTimestamp); project.createResource(folder); } - final JSONObject content = new JSONObject() - .put(PROJECT.value(), projectName) - .put(RESOURCE.value(), resourcePath) - .put(TIMESTAMP.value(), resourceTimestamp) - .put(HASH.value(), resourceHash) - .put(TYPE.value(), resourceType.name().toLowerCase()); - - message.source() - .sendMessage(new FluxMessage(resourceType == FOLDER ? RESOURCE_STORED : GET_RESOURCE_REQUEST, content)); + .put(PROJECT, projectName) + .put(RESOURCE, resourcePath) + .put(TIMESTAMP, resourceTimestamp) + .put(HASH, resourceHash) + .put(TYPE, resourceType.name().toLowerCase()); + + message.getSource().sendMessage(new FluxMessage(resourceType == FOLDER ? RESOURCE_STORED : GET_RESOURCE_REQUEST, content)); } } } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java index 2f42609..8ff7c23 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java @@ -37,10 +37,10 @@ public final class ResourceDeletedHandler implements FluxMessageHandler { @Override public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.content(); - final String projectName = request.getString(PROJECT.value()); - final String resourcePath = request.getString(RESOURCE.value()); - final long resourceTimestamp = request.getLong(TIMESTAMP.value()); + final JSONObject request = message.getContent(); + final String projectName = request.getString(PROJECT); + final String resourcePath = request.getString(RESOURCE); + final long resourceTimestamp = request.getLong(TIMESTAMP); final Project project = repository.getProject(projectName); if (project != null) { From fff65a7e01b24bf4a6cb5a7ef12a5ea087d802db Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Thu, 18 Aug 2016 16:23:33 +0300 Subject: [PATCH 16/34] Implemented method hasResource and refactored ResourceDeleteHandler Signed-off-by: Fjodor Vershinin --- .../core/internal/ResourceDeletedHandler.java | 12 +++++------- .../org/eclipse/flux/watcher/core/spi/Project.java | 2 ++ .../java/org/eclipse/flux/watcher/fs/JDKProject.java | 5 +++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java index 8ff7c23..0954c38 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java @@ -43,12 +43,10 @@ public void onMessage(FluxMessage message, Repository repository) throws JSONExc final long resourceTimestamp = request.getLong(TIMESTAMP); final Project project = repository.getProject(projectName); - if (project != null) { - final Resource localResource = project.getResource(resourcePath); - - if (localResource != null && localResource.timestamp() < resourceTimestamp) { - project.deleteResource(Resource.newUnknown(resourcePath, resourceTimestamp)); - } - } + if(project == null || !project.hasResource(resourcePath)) + return; + Resource localResource = project.getResource(resourcePath); + if(localResource.timestamp() < resourceTimestamp) + project.deleteResource(Resource.newUnknown(resourcePath, resourceTimestamp)); } } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/spi/Project.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/spi/Project.java index f6ffde9..bc9def6 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/spi/Project.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/spi/Project.java @@ -58,6 +58,8 @@ public interface Project { */ Set getResources(); + boolean hasResource(String resourcePath); + /** * Returns the {@link com.codenvy.flux.watcher.core.Resource} with the given relative resource path. * diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProject.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProject.java index 2cf88c2..3ff6491 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProject.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProject.java @@ -251,4 +251,9 @@ public int hashCode() { result = 31 * result + path.hashCode(); return result; } + + @Override + public boolean hasResource(String resourcePath) { + return exists(path.resolve(resourcePath)); + } } From 9b1364845ec3bf3333e297e0b5ed902fa23b0ccb Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Fri, 19 Aug 2016 08:02:03 +0300 Subject: [PATCH 17/34] Refactored listeners for watcher Signed-off-by: Fjodor Vershinin --- .../ProjectResourceCreatedListener.java | 12 ++++++------ .../ProjectResourceDeletedListener.java | 8 ++++---- .../ProjectResourceModifiedListener.java | 17 +++++++++-------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java index edeadea..165d6ec 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java @@ -57,12 +57,12 @@ public final class ProjectResourceCreatedListener implements RepositoryListener @Override public void onEvent(RepositoryEvent event) throws JSONException { - final JSONObject content = new JSONObject() - .put(PROJECT, event.project().id()) - .put(RESOURCE, event.resource().path()) - .put(TIMESTAMP, event.resource().timestamp()) - .put(HASH, event.resource().hash()) - .put(TYPE, event.resource().type().name().toLowerCase()); + JSONObject content = new JSONObject(); + content.put(PROJECT, event.project().id()); + content.put(RESOURCE, event.resource().path()); + content.put(TIMESTAMP, event.resource().timestamp()); + content.put(HASH, event.resource().hash()); + content.put(TYPE, event.resource().type().name().toLowerCase()); messageBus.sendMessages(new FluxMessage(RESOURCE_CREATED, content), new FluxMessage(RESOURCE_STORED, content)); } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java index 3a3f0c1..ef942f1 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java @@ -54,10 +54,10 @@ public final class ProjectResourceDeletedListener implements RepositoryListener @Override public void onEvent(RepositoryEvent event) throws JSONException { - final JSONObject content = new JSONObject() - .put(PROJECT, event.project().id()) - .put(RESOURCE, event.resource().path()) - .put(TIMESTAMP, event.resource().timestamp()); + JSONObject content = new JSONObject(); + content.put(PROJECT, event.project().id()); + content.put(RESOURCE, event.resource().path()); + content.put(TIMESTAMP, event.resource().timestamp()); messageBus.sendMessages(new FluxMessage(RESOURCE_DELETED, content)); } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java index 5208c73..022c377 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java @@ -57,14 +57,15 @@ public final class ProjectResourceModifiedListener implements RepositoryListener @Override public void onEvent(RepositoryEvent event) throws JSONException { - if (event.resource().type() == FILE) { - final JSONObject content = new JSONObject() - .put(PROJECT, event.project().id()) - .put(RESOURCE, event.resource().path()) - .put(TIMESTAMP, event.resource().timestamp()) - .put(HASH, event.resource().hash()); - - messageBus.sendMessages(new FluxMessage(RESOURCE_CHANGED, content), new FluxMessage(RESOURCE_STORED, content)); + if (event.resource().type() != FILE) { + return; } + JSONObject content = new JSONObject(); + content.put(PROJECT, event.project().id()); + content.put(RESOURCE, event.resource().path()); + content.put(TIMESTAMP, event.resource().timestamp()); + content.put(HASH, event.resource().hash()); + + messageBus.sendMessages(new FluxMessage(RESOURCE_CHANGED, content), new FluxMessage(RESOURCE_STORED, content)); } } From da92db4efb5851f7e047c4619e59331b9420f9c7 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Fri, 19 Aug 2016 10:18:41 +0300 Subject: [PATCH 18/34] Fixed updated on move from external directory Signed-off-by: Fjodor Vershinin --- node.server/repository-message-api.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/node.server/repository-message-api.js b/node.server/repository-message-api.js index 5ac3b5d..940bd29 100644 --- a/node.server/repository-message-api.js +++ b/node.server/repository-message-api.js @@ -235,8 +235,11 @@ MessagesRepository.prototype.resourceCreated = function(data) { var hash = data.hash; var type = data.type; + var repoProject = this.repository._getProjectStorage(username, projectName); + var repoResource = repoProject.resources[resource]; + this.repository.hasResource(username, projectName, resource, function(err, resourceExists) { - if (err === null) { + if (err === null && (!resourceExists || repoResource.hash !== hash)) { this.socket.emit('getResourceRequest', { 'callback_id' : 0, 'username' : username, From 8744abf2b2777295866ade50bbf0e7bdc04c6a57 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Fri, 19 Aug 2016 14:01:02 +0300 Subject: [PATCH 19/34] Changed mechanism of creating/receiving/sending messages for LiveEditCoordinator Signed-off-by: Fjodor Vershinin --- .../src/org/eclipse/flux/core/Activator.java | 2 +- .../flux/core/LiveEditCoordinator.java | 150 +++--------------- .../handlers/LiveResourceChangedHandler.java | 42 +++++ .../handlers/LiveResourceRequestHandler.java | 40 +++++ .../handlers/LiveResourceStartedHandler.java | 43 +++++ .../LiveResourceStartedResponseHandler.java | 42 +++++ .../org/eclipse/flux/core/util/JSONUtils.java | 14 ++ .../flux/watcher/core/FluxMessage.java | 10 ++ .../flux/watcher/core/FluxMessageType.java | 8 +- 9 files changed, 219 insertions(+), 132 deletions(-) create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceRequestHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/util/JSONUtils.java diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java index 39d14ce..92db71c 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java @@ -177,7 +177,7 @@ public void stop(BundleContext context) throws Exception { private void initCoreService(String userChannel) throws CoreException { repository = new RepositoryAdapter(fluxRepository, userChannel); - liveEditCoordinator = new LiveEditCoordinator(messageConnector); + liveEditCoordinator = new LiveEditCoordinator(fluxRepository); IWorkspace workspace = ResourcesPlugin.getWorkspace(); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/LiveEditCoordinator.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/LiveEditCoordinator.java index 6b06ba6..7a9af2e 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/LiveEditCoordinator.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/LiveEditCoordinator.java @@ -10,15 +10,19 @@ *******************************************************************************/ package org.eclipse.flux.core; -import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; -import org.eclipse.flux.client.IMessageHandler; -import org.eclipse.flux.client.MessageConnector; -import org.eclipse.flux.client.MessageHandler; +import org.eclipse.flux.core.handlers.LiveResourceChangedHandler; +import org.eclipse.flux.core.handlers.LiveResourceRequestHandler; +import org.eclipse.flux.core.handlers.LiveResourceStartedHandler; +import org.eclipse.flux.core.handlers.LiveResourceStartedResponseHandler; +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageBus; +import org.eclipse.flux.watcher.core.FluxMessageType; +import org.eclipse.flux.watcher.core.Repository; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -28,129 +32,20 @@ */ public class LiveEditCoordinator { - private MessageConnector messagingConnector; private Collection liveEditConnectors; - private Collection messageHandlers; - public LiveEditCoordinator(MessageConnector messagingConnector) { - this.messagingConnector = messagingConnector; + private FluxMessageBus messageBus; + + public LiveEditCoordinator(Repository repository) { + this.messageBus = repository.getMessageBus(); this.liveEditConnectors = new CopyOnWriteArrayList<>(); - this.messageHandlers = new ArrayList(4); - - IMessageHandler startLiveUnit = new MessageHandler("liveResourceStarted") { - @Override - public void handle(String messageType, JSONObject message) { - startLiveUnit(message); - } - }; - messagingConnector.addMessageHandler(startLiveUnit); - messageHandlers.add(startLiveUnit); - - IMessageHandler startLiveUnitResponse = new MessageHandler("liveResourceStartedResponse") { - @Override - public void handle(String messageType, JSONObject message) { - startLiveUnitResponse(message); - } - }; - messagingConnector.addMessageHandler(startLiveUnitResponse); - messageHandlers.add(startLiveUnitResponse); - - IMessageHandler modelChangedHandler = new MessageHandler("liveResourceChanged") { - @Override - public void handle(String messageType, JSONObject message) { - modelChanged(message); - } - }; - messagingConnector.addMessageHandler(modelChangedHandler); - messageHandlers.add(modelChangedHandler); - // Listen to the internal broadcast channel to send out info about current live edit units - IMessageHandler liveUnits = new MessageHandler("getLiveResourcesRequest") { - @Override - public void handle(String messageType, JSONObject message) { - sendLiveUnits(message); - } - }; - messagingConnector.addMessageHandler(liveUnits); - messageHandlers.add(liveUnits); - } - - protected void startLiveUnit(JSONObject message) { - try { - String requestSenderID = message.getString("requestSenderID"); - int callbackID = message.getInt("callback_id"); - String username = message.getString("username"); - String projectName = message.getString("project"); - String resourcePath = message.getString("resource"); - String hash = message.getString("hash"); - long timestamp = message.getLong("timestamp"); - - String liveEditID = projectName + "/" + resourcePath; - for (ILiveEditConnector connector : liveEditConnectors) { - connector.liveEditingStarted(requestSenderID, callbackID, username, liveEditID, hash, timestamp); - } - } - catch (Exception e) { - e.printStackTrace(); - } + messageBus.addMessageHandler(new LiveResourceStartedHandler(liveEditConnectors)); + messageBus.addMessageHandler(new LiveResourceStartedResponseHandler(liveEditConnectors)); + messageBus.addMessageHandler(new LiveResourceChangedHandler(liveEditConnectors)); + messageBus.addMessageHandler(new LiveResourceRequestHandler(liveEditConnectors)); } - protected void startLiveUnitResponse(JSONObject message) { - try { - String requestSenderID = message.getString("requestSenderID"); - int callbackID = message.getInt("callback_id"); - String username = message.getString("username"); - String projectName = message.getString("project"); - String resourcePath = message.getString("resource"); - String savePointHash = message.getString("savePointHash"); - long savePointTimestamp = message.getLong("savePointTimestamp"); - String content = message.getString("liveContent"); - - for (ILiveEditConnector connector : liveEditConnectors) { - connector.liveEditingStartedResponse(requestSenderID, callbackID, username, projectName, resourcePath, savePointHash, savePointTimestamp, content); - } - } - catch (Exception e) { - e.printStackTrace(); - } - } - - protected void modelChanged(JSONObject message) { - try { - String username = message.getString("username"); - String projectName = message.getString("project"); - String resourcePath = message.getString("resource"); - - int offset = message.getInt("offset"); - int removedCharCount = message.getInt("removedCharCount"); - String addedChars = message.has("addedCharacters") ? message.getString("addedCharacters") : ""; - - String liveEditID = projectName + "/" + resourcePath; - - for (ILiveEditConnector connector : liveEditConnectors) { - connector.liveEditingEvent(username, liveEditID, offset, removedCharCount, addedChars); - } - } - catch (Exception e) { - e.printStackTrace(); - } - } - - protected void sendLiveUnits(JSONObject message) { - try { - String username = message.has("username") ? message.getString("username") : null; - String requestSenderID = message.getString("requestSenderID"); - String projectRegEx = message.has("projectRegEx") ? message.getString("projectRegEx") : null; - String resourceRegEx = message.has("resourceRegEx") ? message.getString("resourceRegEx") : null; - int callbackID = message.getInt("callback_id"); - for (ILiveEditConnector connector : liveEditConnectors) { - connector.liveEditors(requestSenderID, callbackID, username, projectRegEx, resourceRegEx); - } - } catch (JSONException e) { - e.printStackTrace(); - } - } - public void addLiveEditConnector(ILiveEditConnector connector) { liveEditConnectors.add(connector); } @@ -166,11 +61,10 @@ public void sendModelChangedMessage(String changeOriginID, String username, Stri message.put("project", projectName); message.put("resource", resourcePath); message.put("offset", offset); - message.put("offset", offset); message.put("removedCharCount", removedCharactersCount); message.put("addedCharacters", newText != null ? newText : ""); - this.messagingConnector.send("liveResourceChanged", message); + this.messageBus.sendMessages(new FluxMessage(FluxMessageType.LIVE_RESOURCE_CHANGED, message)); } catch (Exception e) { e.printStackTrace(); @@ -195,7 +89,7 @@ public void sendLiveEditStartedMessage(String changeOriginID, String username, S message.put("hash", hash); message.put("timestamp", timestamp); - this.messagingConnector.send("liveResourceStarted", message); + this.messageBus.sendMessages(new FluxMessage(FluxMessageType.LIVE_RESOURCE_STARTED, message)); } catch (Exception e) { e.printStackTrace(); @@ -221,7 +115,7 @@ public void sendLiveEditStartedResponse(String responseOriginID, String requestS message.put("savePointHash", savePointHash); message.put("liveContent", content); - this.messagingConnector.send("liveResourceStartedResponse", message); + this.messageBus.sendMessages(new FluxMessage(FluxMessageType.LIVE_RESOURCE_STARTED_RESPONSE, message)); } catch (Exception e) { e.printStackTrace(); @@ -252,7 +146,7 @@ public void sendLiveResourcesResponse(String requestSenderID, } message.put("liveEditUnits", liveEditUnits); - this.messagingConnector.send("getLiveResourcesResponse", message); + this.messageBus.sendMessages(new FluxMessage(FluxMessageType.GET_LIVE_RESOURCE_REQUEST, message)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -274,9 +168,7 @@ public ResourceData(String path, String hash, long timestamp) { } public void dispose() { - for (IMessageHandler messageHanlder : messageHandlers) { - messagingConnector.removeMessageHandler(messageHanlder); - } + } } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java new file mode 100644 index 0000000..db94ed2 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java @@ -0,0 +1,42 @@ +package org.eclipse.flux.core.handlers; + +import java.util.Collection; + +import org.eclipse.flux.core.ILiveEditConnector; +import org.eclipse.flux.core.util.JSONUtils; +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageType; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.json.JSONObject; + +import com.google.inject.Singleton; + +@Singleton +@FluxMessageTypes(FluxMessageType.LIVE_RESOURCE_CHANGED) +public class LiveResourceChangedHandler implements FluxMessageHandler { + + private Collection liveEditConnectors; + + public LiveResourceChangedHandler(Collection liveEditConnectors){ + this.liveEditConnectors = liveEditConnectors; + } + + @Override + public void onMessage(FluxMessage message, Repository repository) throws Exception { + JSONObject content = message.getContent(); + String username = content.getString(FluxMessage.Fields.USERNAME); + String projectName = content.getString(FluxMessage.Fields.PROJECT); + String resourcePath = content.getString(FluxMessage.Fields.RESOURCE); + int offset = content.getInt(FluxMessage.Fields.OFFSET); + int removedCharCount = content.getInt(FluxMessage.Fields.REMOVED_CHAR_COUNT); + String addedChars = JSONUtils.getString(content, FluxMessage.Fields.ADDED_CHARACTERS, ""); + String liveEditID = projectName + "/" + resourcePath; + + for (ILiveEditConnector connector : liveEditConnectors) { + connector.liveEditingEvent(username, liveEditID, offset, removedCharCount, addedChars); + } + } + +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceRequestHandler.java new file mode 100644 index 0000000..ac3ba97 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceRequestHandler.java @@ -0,0 +1,40 @@ +package org.eclipse.flux.core.handlers; + +import java.util.Collection; + +import org.eclipse.flux.core.ILiveEditConnector; +import org.eclipse.flux.core.util.JSONUtils; +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageType; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.json.JSONObject; + +import com.google.inject.Singleton; + +@Singleton +@FluxMessageTypes({ FluxMessageType.GET_LIVE_RESOURCE_REQUEST }) +public class LiveResourceRequestHandler implements FluxMessageHandler { + + private Collection liveEditConnectors; + + public LiveResourceRequestHandler(Collection liveEditConnectors) { + this.liveEditConnectors = liveEditConnectors; + } + + @Override + public void onMessage(FluxMessage message, Repository repository) throws Exception { + JSONObject content = message.getContent(); + String username = JSONUtils.getString(content, FluxMessage.Fields.USERNAME, null); + String requestSenderID = content.getString(FluxMessage.Fields.REQUEST_SENDER_ID); + String projectRegEx = JSONUtils.getString(content, FluxMessage.Fields.PROJECT_REG_EX, null); + String resourceRegEx = JSONUtils.getString(content, FluxMessage.Fields.RESOURCE_REG_EX, null); + int callbackID = content.getInt(FluxMessage.Fields.CALLBACK_ID); + + for (ILiveEditConnector connector : liveEditConnectors) { + connector.liveEditors(requestSenderID, callbackID, username, projectRegEx, resourceRegEx); + } + } + +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java new file mode 100644 index 0000000..804402e --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java @@ -0,0 +1,43 @@ +package org.eclipse.flux.core.handlers; + +import java.util.Collection; + +import org.eclipse.flux.core.ILiveEditConnector; +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageType; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.json.JSONObject; + +import com.google.inject.Singleton; + +@Singleton +@FluxMessageTypes({FluxMessageType.LIVE_RESOURCE_STARTED}) +public class LiveResourceStartedHandler implements FluxMessageHandler { + + private Collection liveEditConnectors; + + public LiveResourceStartedHandler(Collection liveEditConnectors){ + this.liveEditConnectors = liveEditConnectors; + } + + @Override + public void onMessage(FluxMessage message, Repository repository) throws Exception { + JSONObject content = message.getContent(); + String requestSenderID = content.getString(FluxMessage.Fields.REQUEST_SENDER_ID); + int callbackID = content.getInt(FluxMessage.Fields.CALLBACK_ID); + String username = content.getString(FluxMessage.Fields.USERNAME); + String projectName = content.getString(FluxMessage.Fields.PROJECT); + String resourcePath = content.getString(FluxMessage.Fields.RESOURCE); + String hash = content.getString(FluxMessage.Fields.HASH); + long timestamp = content.getLong(FluxMessage.Fields.TIMESTAMP); + String liveEditID = projectName + "/" + resourcePath; + + for (ILiveEditConnector connector : liveEditConnectors) { + connector.liveEditingStarted(requestSenderID, callbackID, username, liveEditID, hash, timestamp); + } + + } + +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java new file mode 100644 index 0000000..30e1248 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java @@ -0,0 +1,42 @@ +package org.eclipse.flux.core.handlers; + +import java.util.Collection; + +import org.eclipse.flux.core.ILiveEditConnector; +import org.eclipse.flux.watcher.core.FluxMessage; +import org.eclipse.flux.watcher.core.FluxMessageHandler; +import org.eclipse.flux.watcher.core.FluxMessageType; +import org.eclipse.flux.watcher.core.FluxMessageTypes; +import org.eclipse.flux.watcher.core.Repository; +import org.json.JSONObject; + +import com.google.inject.Singleton; + +@Singleton +@FluxMessageTypes({FluxMessageType.LIVE_RESOURCE_STARTED_RESPONSE}) +public class LiveResourceStartedResponseHandler implements FluxMessageHandler { + + private Collection liveEditConnectors; + + public LiveResourceStartedResponseHandler(Collection liveEditConnectors) { + this.liveEditConnectors = liveEditConnectors; + } + + @Override + public void onMessage(FluxMessage message, Repository repository) throws Exception { + JSONObject content = message.getContent(); + String requestSenderID = content.getString(FluxMessage.Fields.REQUEST_SENDER_ID); + int callbackID = content.getInt(FluxMessage.Fields.CALLBACK_ID); + String username = content.getString(FluxMessage.Fields.USERNAME); + String projectName = content.getString(FluxMessage.Fields.PROJECT); + String resourcePath = content.getString(FluxMessage.Fields.RESOURCE); + String savePointHash = content.getString(FluxMessage.Fields.SAVE_POINT_HASH); + long savePointTimestamp = content.getLong(FluxMessage.Fields.SAVE_POINT_TIMESTAMP); + String liveContent = content.getString(FluxMessage.Fields.LIVE_CONTENT); + + for (ILiveEditConnector connector : liveEditConnectors) { + connector.liveEditingStartedResponse(requestSenderID, callbackID, username, projectName, resourcePath, savePointHash, savePointTimestamp, liveContent); + } + } + +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/util/JSONUtils.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/util/JSONUtils.java new file mode 100644 index 0000000..cfc3999 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/util/JSONUtils.java @@ -0,0 +1,14 @@ +package org.eclipse.flux.core.util; + +import org.json.JSONObject; + +public class JSONUtils { + public static String getString(JSONObject object, String key, String defaultValue){ + try { + return object.getString(key); + } + catch (Exception e) { + return defaultValue; + } + } +} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java index b0463b8..bfe2fb1 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java @@ -41,6 +41,16 @@ public static interface Fields { public static final String TIMESTAMP = "timestamp"; public static final String TYPE = "type"; public static final String USERNAME = "username"; + public static final String SAVE_POINT_HASH = "savePointHash"; + public static final String SAVE_POINT_TIMESTAMP = "savePointTimestamp"; + public static final String LIVE_CONTENT = "liveContent"; + public static final String OFFSET = "offset"; + public static final String REMOVED_CHAR_COUNT = "removedCharCount"; + public static final String ADDED_CHARACTERS = "addedCharacters"; + public static final String PROJECT_REG_EX = "projectRegEx"; + public static final String RESOURCE_REG_EX = "resourceRegEx"; + + } private final FluxConnection source; diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageType.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageType.java index 54bb533..6173d1e 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageType.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageType.java @@ -25,14 +25,18 @@ public enum FluxMessageType { GET_RESOURCE_RESPONSE("getResourceResponse"), GET_METADATA_REQUEST("getMetadataRequest"), GET_METADATA_RESPONSE("getMetadataResponse"), + GET_LIVE_RESOURCE_REQUEST("getLiveResourcesRequest"), PROJECT_CONNECTED("projectConnected"), PROJECT_DISCONNECTED("projectDisconnected"), RESOURCE_CHANGED("resourceChanged"), RESOURCE_CREATED("resourceCreated"), RESOURCE_DELETED("resourceDeleted"), RESOURCE_STORED("resourceStored"), - METADATA_CHANGED("metadataChanged"); - + METADATA_CHANGED("metadataChanged"), + LIVE_RESOURCE_STARTED("liveResourceStarted"), + LIVE_RESOURCE_STARTED_RESPONSE("liveResourceStartedResponse"), + LIVE_RESOURCE_CHANGED("liveResourceChanged"); + private final String value; /** From 0dc37f55c6d5ecb9d1017521b43a58e52d7b4756 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Fri, 19 Aug 2016 17:54:55 +0300 Subject: [PATCH 20/34] Cleanup code Signed-off-by: Fjodor Vershinin --- .../eclipse/flux/core/RepositoryAdapter.java | 27 +++---------------- .../core/handlers/MetadataRequestHandler.java | 27 ++----------------- .../org/eclipse/flux/core/util/JSONUtils.java | 24 +++++++++++++++++ 3 files changed, 29 insertions(+), 49 deletions(-) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index a84bd92..3565fbc 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -20,6 +20,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.flux.core.handlers.MetadataRequestHandler; +import org.eclipse.flux.core.util.JSONUtils; import org.eclipse.flux.core.handlers.EclipseResourceResponseHandler; import org.eclipse.flux.watcher.core.FluxMessage; import org.eclipse.flux.watcher.core.FluxMessageBus; @@ -27,7 +28,6 @@ import org.eclipse.flux.watcher.core.Repository; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; -import org.json.JSONException; import org.json.JSONObject; /** @@ -114,34 +114,13 @@ public void sendMetadataUpdate(IResource resource) { message.put("type", "marker"); IMarker[] markers = resource.findMarkers(null, true, IResource.DEPTH_INFINITE); - JSONArray content = toJSON(markers); + JSONArray content = JSONUtils.toJSON(markers); message.put("metadata", content); - repository.getMessageBus().sendMessages(new FluxMessage(FluxMessageType.METADATA_CHANGED, message)); + messageBus.sendMessages(new FluxMessage(FluxMessageType.METADATA_CHANGED, message)); } catch (Exception e) { } } - - public JSONArray toJSON(IMarker[] markers) throws JSONException{ - JSONArray objects = new JSONArray(); - for(IMarker marker : markers){ - JSONObject object = new JSONObject(); - object.put("description", marker.getAttribute("message", "")); - object.put("line", marker.getAttribute("lineNumber", 0)); - switch(marker.getAttribute("severity", IMarker.SEVERITY_WARNING)){ - case IMarker.SEVERITY_WARNING: - object.put("severity", marker.getAttribute("severity", "warning")); - break; - case IMarker.SEVERITY_ERROR: - object.put("severity", marker.getAttribute("severity", "error")); - break; - } - object.put("start", marker.getAttribute("charStart", 0)); - object.put("end", marker.getAttribute("charEnd", 0)); - objects.put(object); - } - return objects; - } public void addRepositoryListener(IRepositoryListener listener) { this.repositoryListeners.add(listener); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java index a9be0d7..f8e4178 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java @@ -3,10 +3,10 @@ import java.text.MessageFormat; import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Path; +import org.eclipse.flux.core.util.JSONUtils; import org.eclipse.flux.watcher.core.FluxMessage; import org.eclipse.flux.watcher.core.FluxMessageHandler; import org.eclipse.flux.watcher.core.FluxMessageType; @@ -14,8 +14,6 @@ import org.eclipse.flux.watcher.core.Repository; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; -import org.json.JSONArray; -import org.json.JSONException; import org.json.JSONObject; import com.google.inject.Singleton; @@ -36,30 +34,9 @@ public void onMessage(FluxMessage message, Repository repository) throws Excepti Path path = new Path(MessageFormat.format("{0}/{1}", projectName, resourcePath)); IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); content.put("type", "marker"); - content.put("metadata", toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE))); + content.put("metadata", JSONUtils.toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE))); message.getSource().sendMessage(new FluxMessage(FluxMessageType.GET_METADATA_RESPONSE, content)); } } } - - public JSONArray toJSON(IMarker[] markers) throws JSONException{ - JSONArray objects = new JSONArray(); - for(IMarker marker : markers){ - JSONObject object = new JSONObject(); - object.put("description", marker.getAttribute("message", "")); - object.put("line", marker.getAttribute("lineNumber", 0)); - switch(marker.getAttribute("severity", IMarker.SEVERITY_WARNING)){ - case IMarker.SEVERITY_WARNING: - object.put("severity", marker.getAttribute("severity", "warning")); - break; - case IMarker.SEVERITY_ERROR: - object.put("severity", marker.getAttribute("severity", "error")); - break; - } - object.put("start", marker.getAttribute("charStart", 0)); - object.put("end", marker.getAttribute("charEnd", 0)); - objects.put(object); - } - return objects; - } } \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/util/JSONUtils.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/util/JSONUtils.java index cfc3999..9c15f9f 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/util/JSONUtils.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/util/JSONUtils.java @@ -1,5 +1,8 @@ package org.eclipse.flux.core.util; +import org.eclipse.core.resources.IMarker; +import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; public class JSONUtils { @@ -11,4 +14,25 @@ public static String getString(JSONObject object, String key, String defaultValu return defaultValue; } } + + public static JSONArray toJSON(IMarker[] markers) throws JSONException{ + JSONArray objects = new JSONArray(); + for(IMarker marker : markers){ + JSONObject object = new JSONObject(); + object.put("description", marker.getAttribute("message", "")); + object.put("line", marker.getAttribute("lineNumber", 0)); + switch(marker.getAttribute("severity", IMarker.SEVERITY_WARNING)){ + case IMarker.SEVERITY_WARNING: + object.put("severity", marker.getAttribute("severity", "warning")); + break; + case IMarker.SEVERITY_ERROR: + object.put("severity", marker.getAttribute("severity", "error")); + break; + } + object.put("start", marker.getAttribute("charStart", 0)); + object.put("end", marker.getAttribute("charEnd", 0)); + objects.put(object); + } + return objects; + } } From 3558b3d5f01fd1991c0bd6a4083854ae03db9c01 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Sat, 20 Aug 2016 09:31:47 +0300 Subject: [PATCH 21/34] Adopted ConnectedProject for Flux Project Signed-off-by: Fjodor Vershinin --- .../eclipse/flux/core/ConnectedProject.java | 141 ++++++++---------- .../eclipse/flux/core/RepositoryAdapter.java | 17 ++- 2 files changed, 72 insertions(+), 86 deletions(-) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/ConnectedProject.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/ConnectedProject.java index 996616f..e6c7079 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/ConnectedProject.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/ConnectedProject.java @@ -10,93 +10,78 @@ *******************************************************************************/ package org.eclipse.flux.core; -import java.io.IOException; import java.io.InputStream; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.commons.codec.digest.DigestUtils; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceVisitor; -import org.eclipse.core.runtime.CoreException; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; /** * @author Martin Lippert */ public class ConnectedProject { - - private IProject project; - private Map resourceHash; - private Map resourceTimestamp; - - public ConnectedProject(IProject project) { - this.project = project; - this.resourceHash = new ConcurrentHashMap(); - this.resourceTimestamp = new ConcurrentHashMap(); - - try { - project.refreshLocal(IResource.DEPTH_INFINITE, null); - project.accept(new IResourceVisitor() { - @Override - public boolean visit(IResource resource) throws CoreException { - String path = resource.getProjectRelativePath().toString(); - ConnectedProject.this.setTimestamp(path, resource.getLocalTimeStamp()); - - if (resource instanceof IFile) { - try { - IFile file = (IFile) resource; - ConnectedProject.this.setHash(path, DigestUtils.shaHex(file.getContents())); - } catch (IOException e) { - e.printStackTrace(); - } - } - else if (resource instanceof IFolder) { - ConnectedProject.this.setHash(path, "0"); - } - - return true; - } - }, IResource.DEPTH_INFINITE, IContainer.EXCLUDE_DERIVED); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public IProject getProject() { - return project; - } - - public String getName() { - return this.project.getName(); - } + private String name; + private Project project; + + public ConnectedProject(Project project) { + this.project = project; + this.name = project.id(); + } + + public IProject getProject() { + return null; + } + + public String getName() { + return this.project.id(); + } + + public static ConnectedProject readFromJSON(InputStream inputStream, IProject project) { + return null; + } + + public long getTimestamp(String resourcePath) { + Resource resource = this.project.getResource(resourcePath); + return resource.timestamp(); + } + + public String getHash(String resourcePath) { + Resource resource = this.project.getResource(resourcePath); + return resource.hash(); + } + + public boolean containsResource(String resourcePath) { + return this.project.hasResource(resourcePath); + } - public static ConnectedProject readFromJSON(InputStream inputStream, IProject project) { - return new ConnectedProject(project); - } - - public void setTimestamp(String resourcePath, long newTimestamp) { - this.resourceTimestamp.put(resourcePath, newTimestamp); - } - - public long getTimestamp(String resourcePath) { - return this.resourceTimestamp.get(resourcePath); - } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } - public void setHash(String resourcePath, String hash) { - this.resourceHash.put(resourcePath, hash); - } - - public String getHash(String resourcePath) { - return this.resourceHash.get(resourcePath); - } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof ConnectedProject)) { + return false; + } + ConnectedProject other = (ConnectedProject)obj; + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + return true; + } - public boolean containsResource(String resourcePath) { - return this.resourceTimestamp.containsKey(resourcePath); - } - } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index 3565fbc..de27c97 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -11,9 +11,9 @@ package org.eclipse.flux.core; import java.util.Collection; -import java.util.concurrent.ConcurrentHashMap; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.concurrent.ConcurrentMap; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IProject; @@ -37,7 +37,6 @@ public class RepositoryAdapter { private String username; - private ConcurrentMap syncedProjects; private Collection repositoryListeners; private Repository repository; @@ -47,7 +46,6 @@ public RepositoryAdapter(Repository repository, String user) { this.repository = repository; this.messageBus = repository.getMessageBus(); this.username = user; - this.syncedProjects = new ConcurrentHashMap(); this.repositoryListeners = new ConcurrentLinkedDeque<>(); messageBus.addMessageHandler(new EclipseResourceResponseHandler()); @@ -67,7 +65,7 @@ public ConnectedProject getProject(IProject project) { } public ConnectedProject getProject(String projectName) { - return this.syncedProjects.get(projectName); + return new ConnectedProject(repository.getProject(projectName)); } public boolean isConnected(IProject project) { @@ -90,8 +88,12 @@ public void removeProject(IProject project) { } public ConnectedProject[] getConnectedProjects() { - return syncedProjects.values().toArray( - new ConnectedProject[syncedProjects.size()]); + Set projects = repository.getSynchronizedProjects(); + Set connectedProjects = new HashSet<>(); + for(Project project : projects){ + connectedProjects.add(new ConnectedProject(project)); + } + return connectedProjects.toArray(new ConnectedProject[connectedProjects.size()]); } public void metadataChanged(IResourceDelta delta) { @@ -149,7 +151,6 @@ protected void notifyResourceChanged(IResource resource) { } public void dispose() { - syncedProjects.clear(); } } From 04054a9c3ebb2c8f8500c91eb5de3f1bedbdb463 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Sat, 20 Aug 2016 09:48:32 +0300 Subject: [PATCH 22/34] Set Java 7 for Watcher Library Signed-off-by: Fjodor Vershinin --- org.eclipse.flux.watcher/META-INF/MANIFEST.MF | 2 +- org.eclipse.flux.watcher/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/org.eclipse.flux.watcher/META-INF/MANIFEST.MF b/org.eclipse.flux.watcher/META-INF/MANIFEST.MF index 57f975f..9e90801 100644 --- a/org.eclipse.flux.watcher/META-INF/MANIFEST.MF +++ b/org.eclipse.flux.watcher/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Watch Bundle-SymbolicName: org.eclipse.flux.watcher Bundle-Version: 1.0.0.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Require-Bundle: org.eclipse.flux.client.java.osgi;bundle-version="1.0.0", org.mockito, org.junit diff --git a/org.eclipse.flux.watcher/pom.xml b/org.eclipse.flux.watcher/pom.xml index 20a1a40..599fa3a 100644 --- a/org.eclipse.flux.watcher/pom.xml +++ b/org.eclipse.flux.watcher/pom.xml @@ -16,8 +16,8 @@ maven-compiler-plugin 3.1 - 1.8 - 1.8 + 1.7 + 1.7 From 2bf1853112d5119b487c1a8b55c572b8ba82c6cd Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Sat, 20 Aug 2016 16:03:05 +0300 Subject: [PATCH 23/34] Commented INTERSECTION_CAST_TYPE visitor Signed-off-by: Fjodor Vershinin --- .../jdt/internal/compiler/lookup/TypeBindingVisitor.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/org.eclipse.flux.jdt.service/jdt ui/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java b/org.eclipse.flux.jdt.service/jdt ui/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java index 610f6fd..d6b4003 100644 --- a/org.eclipse.flux.jdt.service/jdt ui/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java +++ b/org.eclipse.flux.jdt.service/jdt ui/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java @@ -42,9 +42,9 @@ public boolean visit(ParameterizedTypeBinding parameterizedTypeBinding) { return true; // continue traversal. } - public boolean visit(IntersectionCastTypeBinding intersectionCastTypeBinding) { + /*public boolean visit(IntersectionCastTypeBinding intersectionCastTypeBinding) { return true; // continue traversal. - } + }*/ public boolean visit(RawTypeBinding rawTypeBinding) { return true; // continue traversal. @@ -128,11 +128,11 @@ public static void visit(TypeBindingVisitor visitor, TypeBinding type) { } break; - case Binding.INTERSECTION_CAST_TYPE: + /*case Binding.INTERSECTION_CAST_TYPE: IntersectionCastTypeBinding intersectionCastTypeBinding = (IntersectionCastTypeBinding) type; if (visitor.visit(intersectionCastTypeBinding)) visit(visitor, intersectionCastTypeBinding.intersectingTypes); - break; + break;*/ case Binding.POLY_TYPE: visitor.visit((PolyTypeBinding) type); From 7f18a84f06c8dea7a4ca308d4a345d36ceffb3ec Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Sun, 21 Aug 2016 08:06:09 +0300 Subject: [PATCH 24/34] Added static fields in order to store message types Signed-off-by: Fjodor Vershinin --- .../org/eclipse/flux/client/IMessageHandler.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java b/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java index 470159f..a777be7 100644 --- a/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java +++ b/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java @@ -19,6 +19,22 @@ * */ public interface IMessageHandler { + public static final String GET_PROJECT_REQUEST = "getProjectRequest"; + public static final String GET_PROJECT_RESPONSE = "getProjectResponse"; + public static final String GET_LIVE_RESOURCE_REQUEST = "getLiveResourcesRequest"; + public static final String GET_METADATA_REQUEST = "getMetadataRequest"; + public static final String GET_METADATA_RESPONSE = "getMetadataResponse"; + public static final String GET_RESOURCE_REQUEST = "getResourceRequest"; + public static final String GET_RESOURCE_RESPONSE = "getResourceResponse"; + public static final String LIVE_RESOURCE_STARTED = "liveResourceStarted"; + public static final String LIVE_RESOURCE_STARTED_RESPONSE = "liveResourceStartedResponse"; + public static final String LIVE_RESOURCE_CHANGED = "liveResourceChanged"; + public static final String PROJECT_CONNECTED = "projectConnected"; + public static final String PROJECT_DISCONNECTED = "projectDisconnected"; + public static final String RESOURCE_CHANGED = "resourceChanged"; + public static final String RESOURCE_CREATED = "resourceCreated"; + public static final String RESOURCE_DELETED = "resourceDeleted"; + public static final String RESOURCE_STORED = "resourceStored"; boolean canHandle(String type, JSONObject message); From 5a47d5b722a370f43c14ab3d27ee4a3e996be7e0 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Sun, 21 Aug 2016 08:50:29 +0300 Subject: [PATCH 25/34] Added static fields in order to store message fields Signed-off-by: Fjodor Vershinin --- .../eclipse/flux/client/MessageConstants.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/MessageConstants.java b/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/MessageConstants.java index b522b55..4b7bd94 100644 --- a/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/MessageConstants.java +++ b/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/MessageConstants.java @@ -56,5 +56,26 @@ public abstract class MessageConstants { * Name of the Flux super user. */ public static final String SUPER_USER = "$super$"; + + public static final String CHANNEL = "channel"; + public static final String CONNECTED_TO_CHANNEL = "connectedToChannel"; + public static final String CONTENT = "content"; + public static final String DELETED = "deleted"; + public static final String FILES = "files"; + public static final String HASH = "hash"; + public static final String INCLUDE_DELETED = "includeDeleted"; + public static final String PATH = "path"; + public static final String PROJECT = "project"; + public static final String RESOURCE = "resource"; + public static final String TIMESTAMP = "timestamp"; + public static final String TYPE = "type"; + public static final String SAVE_POINT_HASH = "savePointHash"; + public static final String SAVE_POINT_TIMESTAMP = "savePointTimestamp"; + public static final String LIVE_CONTENT = "liveContent"; + public static final String OFFSET = "offset"; + public static final String REMOVED_CHAR_COUNT = "removedCharCount"; + public static final String ADDED_CHARACTERS = "addedCharacters"; + public static final String PROJECT_REG_EX = "projectRegEx"; + public static final String RESOURCE_REG_EX = "resourceRegEx"; } From 1d7a00b2cb180810ef00b074398297c62e20df46 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Sun, 21 Aug 2016 15:15:03 +0300 Subject: [PATCH 26/34] Switched back to the old mechanism of sending/receiving messages Signed-off-by: Fjodor Vershinin --- .../eclipse/flux/client/IMessageHandler.java | 1 + .../src/org/eclipse/flux/core/Activator.java | 2 +- .../eclipse/flux/core/RepositoryAdapter.java | 169 +++++++++++++++--- .../handlers/AbstractFluxMessageHandler.java | 43 +++++ .../EclipseResourceResponseHandler.java | 30 ---- .../core/handlers/MetadataRequestHandler.java | 46 +++-- .../core/handlers/ProjectRequestHandler.java | 34 ++++ .../core/handlers/ProjectResponseHandler.java | 71 ++++++++ .../handlers/ProjectsResponseHandler.java | 37 ++++ .../core/handlers/ResourceChangedHandler.java | 43 +++++ .../core/handlers/ResourceCreatedHandler.java | 48 +++++ .../core/handlers/ResourceDeletedHandler.java | 33 ++++ .../core/handlers/ResourceRequestHandler.java | 34 ++++ .../handlers/ResourceResponseHandler.java | 76 ++++++++ .../eclipse/flux/watcher/core/Repository.java | 8 +- .../flux/watcher/core/RepositoryEventBus.java | 2 + .../flux/watcher/core/RepositoryModule.java | 20 +-- .../internal/GetProjectRequestHandler.java | 1 - .../internal/GetProjectResponseHandler.java | 1 - .../internal/GetResourceRequestHandler.java | 1 - .../internal/GetResourceResponseHandler.java | 1 - .../ProjectResourceCreatedListener.java | 2 +- .../ProjectResourceDeletedListener.java | 2 +- .../ProjectResourceModifiedListener.java | 2 +- .../core/internal/ResourceChangedHandler.java | 1 - .../core/internal/ResourceCreatedHandler.java | 1 - .../core/internal/ResourceDeletedHandler.java | 1 - .../watcher/core/utils/ResourceHelper.java | 2 +- .../watcher/fs/JDKProjectWatchService.java | 4 +- 29 files changed, 611 insertions(+), 105 deletions(-) create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractFluxMessageHandler.java delete mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/EclipseResourceResponseHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java diff --git a/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java b/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java index a777be7..14b2917 100644 --- a/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java +++ b/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java @@ -29,6 +29,7 @@ public interface IMessageHandler { public static final String LIVE_RESOURCE_STARTED = "liveResourceStarted"; public static final String LIVE_RESOURCE_STARTED_RESPONSE = "liveResourceStartedResponse"; public static final String LIVE_RESOURCE_CHANGED = "liveResourceChanged"; + public static final String METADATA_CHANGED = "metadataChanged"; public static final String PROJECT_CONNECTED = "projectConnected"; public static final String PROJECT_DISCONNECTED = "projectDisconnected"; public static final String RESOURCE_CHANGED = "resourceChanged"; diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java index 92db71c..3a2628a 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java @@ -176,7 +176,7 @@ public void stop(BundleContext context) throws Exception { } private void initCoreService(String userChannel) throws CoreException { - repository = new RepositoryAdapter(fluxRepository, userChannel); + repository = new RepositoryAdapter(messageConnector, fluxRepository, userChannel); liveEditCoordinator = new LiveEditCoordinator(fluxRepository); IWorkspace workspace = ResourcesPlugin.getWorkspace(); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index de27c97..0fb8f6f 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -1,31 +1,43 @@ /******************************************************************************* * Copyright (c) 2013, 2014 Pivotal Software, Inc. and others. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 - * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution - * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 + * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution + * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). * * Contributors: * Pivotal Software, Inc. - initial API and implementation -*******************************************************************************/ + *******************************************************************************/ package org.eclipse.flux.core; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ConcurrentLinkedDeque; + import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.flux.core.handlers.MetadataRequestHandler; +import org.eclipse.flux.core.handlers.ProjectRequestHandler; +import org.eclipse.flux.core.handlers.ProjectResponseHandler; +import org.eclipse.flux.core.handlers.ProjectsResponseHandler; +import org.eclipse.flux.core.handlers.ResourceChangedHandler; +import org.eclipse.flux.core.handlers.ResourceCreatedHandler; +import org.eclipse.flux.core.handlers.ResourceDeletedHandler; +import org.eclipse.flux.core.handlers.ResourceRequestHandler; +import org.eclipse.flux.core.handlers.ResourceResponseHandler; import org.eclipse.flux.core.util.JSONUtils; -import org.eclipse.flux.core.handlers.EclipseResourceResponseHandler; -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageBus; -import org.eclipse.flux.watcher.core.FluxMessageType; +import org.eclipse.flux.client.IMessageHandler; +import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventBus; +import org.eclipse.flux.watcher.core.RepositoryListener; +import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; import org.json.JSONObject; @@ -34,26 +46,102 @@ * @author Martin Lippert */ public class RepositoryAdapter { + private static int GET_PROJECT_CALLBACK = "Repository - getProjectCallback".hashCode(); + private static int GET_RESOURCE_CALLBACK = "Repository - getResourceCallback".hashCode(); private String username; private Collection repositoryListeners; - + + private RepositoryEventBus repositoryEventBus; private Repository repository; - private FluxMessageBus messageBus; + private MessageConnector messageConnector; + private Collection messageHandlers; - public RepositoryAdapter(Repository repository, String user) { + public RepositoryAdapter(MessageConnector messageConnector, Repository repository, String user) { this.repository = repository; - this.messageBus = repository.getMessageBus(); + this.repositoryEventBus = repository.repositoryEventBus(); + this.messageConnector = messageConnector; this.username = user; + this.messageHandlers = new ArrayList<>(); this.repositoryListeners = new ConcurrentLinkedDeque<>(); - - messageBus.addMessageHandler(new EclipseResourceResponseHandler()); - messageBus.addMessageHandler(new MetadataRequestHandler()); - } - - public FluxMessageBus getMessageBus(){ - return this.messageBus; + + IMessageHandler metadataRequestHandler = new MetadataRequestHandler(messageConnector, repository); + this.messageConnector.addMessageHandler(metadataRequestHandler); + this.messageHandlers.add(metadataRequestHandler); + + IMessageHandler projectsRequestHandler = new ProjectsResponseHandler(messageConnector, repository); + this.messageConnector.addMessageHandler(projectsRequestHandler); + this.messageHandlers.add(projectsRequestHandler); + + IMessageHandler projectRequestHandler = new ProjectRequestHandler(messageConnector, repository); + this.messageConnector.addMessageHandler(projectRequestHandler); + this.messageHandlers.add(projectRequestHandler); + + IMessageHandler projectResponseHandler = new ProjectResponseHandler(messageConnector, repository, GET_PROJECT_CALLBACK); + this.messageConnector.addMessageHandler(projectResponseHandler); + this.messageHandlers.add(projectResponseHandler); + + IMessageHandler resourceRequestHandler = new ResourceRequestHandler(messageConnector, repository); + this.messageConnector.addMessageHandler(resourceRequestHandler); + this.messageHandlers.add(resourceRequestHandler); + + IMessageHandler resourceResponseHandler = new ResourceResponseHandler(messageConnector, repository, GET_RESOURCE_CALLBACK); + this.messageConnector.addMessageHandler(resourceResponseHandler); + this.messageHandlers.add(resourceResponseHandler); + + IMessageHandler resourceCreatedHandler = new ResourceCreatedHandler(messageConnector, repository, GET_RESOURCE_CALLBACK); + this.messageConnector.addMessageHandler(resourceCreatedHandler); + this.messageHandlers.add(resourceCreatedHandler); + + IMessageHandler resourceChangedHandler = new ResourceChangedHandler(messageConnector, repository, GET_RESOURCE_CALLBACK); + this.messageConnector.addMessageHandler(resourceChangedHandler); + this.messageHandlers.add(resourceChangedHandler); + + IMessageHandler resourceDeletedHandler = new ResourceDeletedHandler(messageConnector, repository); + this.messageConnector.addMessageHandler(resourceDeletedHandler); + this.messageHandlers.add(resourceDeletedHandler); + + this.repositoryEventBus.addRepositoryListener(new RepositoryListener() { + @Override + public void onEvent(RepositoryEvent event) throws Exception { + Project project = event.project(); + Resource resource = event.resource(); + switch (event.type()) { + case PROJECT_RESOURCE_CREATED: + JSONObject createdStoredMessage = new JSONObject(); + createdStoredMessage.put("username", RepositoryAdapter.this.username); + createdStoredMessage.put("project", project.id()); + createdStoredMessage.put("resource", resource.path()); + createdStoredMessage.put("timestamp", resource.timestamp()); + createdStoredMessage.put("hash", resource.hash()); + createdStoredMessage.put("type", resource.type().name().toLowerCase()); + RepositoryAdapter.this.messageConnector.send("resourceCreated", createdStoredMessage); + RepositoryAdapter.this.messageConnector.send("resourceStored", createdStoredMessage); + break; + case PROJECT_RESOURCE_MODIFIED: + JSONObject modifiedStoredMessage = new JSONObject(); + modifiedStoredMessage.put("username", RepositoryAdapter.this.username); + modifiedStoredMessage.put("project", project.id()); + modifiedStoredMessage.put("resource", resource.path()); + modifiedStoredMessage.put("timestamp", resource.timestamp()); + modifiedStoredMessage.put("hash", resource.hash()); + RepositoryAdapter.this.messageConnector.send("resourceChanged", modifiedStoredMessage); + RepositoryAdapter.this.messageConnector.send("resourceStored", modifiedStoredMessage); + break; + case PROJECT_RESOURCE_DELETED: + JSONObject message = new JSONObject(); + message.put("username", RepositoryAdapter.this.username); + message.put("project", project.id()); + message.put("resource", resource.path()); + message.put("timestamp", resource.timestamp()); + RepositoryAdapter.this.messageConnector.send("resourceDeleted", message); + break; + default: + break; + } + } + }); } public String getUsername() { @@ -67,6 +155,7 @@ public ConnectedProject getProject(IProject project) { public ConnectedProject getProject(String projectName) { return new ConnectedProject(repository.getProject(projectName)); } + public boolean isConnected(IProject project) { return isConnected(project.getName()); @@ -80,13 +169,22 @@ public boolean isConnected(String projectName) { public void addProject(IProject project) { this.repository.addProject(project.getName(), project.getLocationURI().getPath()); notifyProjectConnected(project); + sendProjectConnectedMessage(project.getName()); + syncConnectedProject(project.getName()); } public void removeProject(IProject project) { this.repository.removeProject(project.getName()); notifyProjectDisonnected(project); + JSONObject message = new JSONObject(); + try { + message.put("username", this.username); + message.put("project", project.getName()); + messageConnector.send("projectDisconnected", message); + } catch (Exception e) { + e.printStackTrace(); + } } - public ConnectedProject[] getConnectedProjects() { Set projects = repository.getSynchronizedProjects(); Set connectedProjects = new HashSet<>(); @@ -118,7 +216,7 @@ public void sendMetadataUpdate(IResource resource) { IMarker[] markers = resource.findMarkers(null, true, IResource.DEPTH_INFINITE); JSONArray content = JSONUtils.toJSON(markers); message.put("metadata", content); - messageBus.sendMessages(new FluxMessage(FluxMessageType.METADATA_CHANGED, message)); + messageConnector.send(IMessageHandler.METADATA_CHANGED, message); } catch (Exception e) { } @@ -132,6 +230,30 @@ public void removeRepositoryListener(IRepositoryListener listener) { this.repositoryListeners.remove(listener); } + protected void syncConnectedProject(String projectName) { + try { + JSONObject message = new JSONObject(); + message.put("username", this.username); + message.put("project", projectName); + message.put("includeDeleted", true); + message.put("callback_id", GET_PROJECT_CALLBACK); + messageConnector.send("getProjectRequest", message); + } catch (Exception e) { + e.printStackTrace(); + } + } + + protected void sendProjectConnectedMessage(String projectName) { + try { + JSONObject message = new JSONObject(); + message.put("username", this.username); + message.put("project", projectName); + messageConnector.send("projectConnected", message); + } catch (Exception e) { + e.printStackTrace(); + } + } + protected void notifyProjectConnected(IProject project) { for (IRepositoryListener listener : this.repositoryListeners) { listener.projectConnected(project); @@ -151,6 +273,9 @@ protected void notifyResourceChanged(IResource resource) { } public void dispose() { + for(IMessageHandler messageHandler : messageHandlers){ + messageConnector.removeMessageHandler(messageHandler); + } } } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractFluxMessageHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractFluxMessageHandler.java new file mode 100644 index 0000000..12b4892 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractFluxMessageHandler.java @@ -0,0 +1,43 @@ +package org.eclipse.flux.core.handlers; + +import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.client.MessageHandler; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.Resource.ResourceType; +import org.json.JSONObject; + +public abstract class AbstractFluxMessageHandler extends MessageHandler { + protected Repository repository; + protected MessageConnector messageConnector; + + public AbstractFluxMessageHandler(MessageConnector messageConnector, Repository repository, String type) { + super(type); + this.repository = repository; + this.messageConnector = messageConnector; + } + + @Override + public void handle(String type, JSONObject message) { + try{ + onMessage(type, message); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + protected abstract void onMessage(String type, JSONObject message) throws Exception; + + protected ResourceType getResourceType(JSONObject jsonObject){ + String type = jsonObject.optString(MessageConstants.TYPE, ResourceType.UNKNOWN.name()); + return ResourceType.valueOf(type.toUpperCase()); + } + + protected boolean IsResourcesNotEquals(Resource resource, String hash, long timestamp){ + boolean isLocalResourceOutdated = resource.timestamp() < timestamp; + boolean isEquals = resource.hash().equals(hash); + return isLocalResourceOutdated && !isEquals; + } +} \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/EclipseResourceResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/EclipseResourceResponseHandler.java deleted file mode 100644 index 57a1ad2..0000000 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/EclipseResourceResponseHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.eclipse.flux.core.handlers; - -import java.text.MessageFormat; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.Path; -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageType; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; - -import com.google.inject.Singleton; - -@Singleton -@FluxMessageTypes(FluxMessageType.GET_RESOURCE_RESPONSE) -public class EclipseResourceResponseHandler implements FluxMessageHandler { - - @Override - public void onMessage(FluxMessage message, Repository repository) throws Exception { - final String resourcePath = message.getContent().getString("resource"); - final String project = message.getContent().getString("project"); - Path path = new Path(MessageFormat.format("{0}/{1}", project, resourcePath)); - IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); - file.refreshLocal(IResource.DEPTH_ZERO, null); - } - -} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java index f8e4178..703109b 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java @@ -6,37 +6,33 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Path; +import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.core.util.JSONUtils; -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageType; -import org.eclipse.flux.watcher.core.FluxMessageTypes; import org.eclipse.flux.watcher.core.Repository; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; -import com.google.inject.Singleton; +public class MetadataRequestHandler extends AbstractFluxMessageHandler { -@Singleton -@FluxMessageTypes({FluxMessageType.GET_METADATA_REQUEST}) -public class MetadataRequestHandler implements FluxMessageHandler { + public MetadataRequestHandler(MessageConnector messageConnector, Repository repository) { + super(messageConnector, repository, GET_METADATA_REQUEST); + } - @Override - public void onMessage(FluxMessage message, Repository repository) throws Exception { - JSONObject content = message.getContent(); - String projectName = message.getContent().getString("project"); - String resourcePath = message.getContent().getString("resource"); - Project project = repository.getProject(projectName); - if(project != null){ - Resource resource = project.getResource(resourcePath); - if(resource != null){ - Path path = new Path(MessageFormat.format("{0}/{1}", projectName, resourcePath)); - IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); - content.put("type", "marker"); - content.put("metadata", JSONUtils.toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE))); - message.getSource().sendMessage(new FluxMessage(FluxMessageType.GET_METADATA_RESPONSE, content)); - } - } - } + @Override + protected void onMessage(String type, JSONObject message) throws Exception { + String projectName = message.getString("project"); + String resourcePath = message.getString("resource"); + Project project = repository.getProject(projectName); + if(project != null){ + Resource resource = project.getResource(resourcePath); + if(resource != null){ + Path path = new Path(MessageFormat.format("{0}/{1}", projectName, resourcePath)); + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); + message.put("type", "marker"); + message.put("metadata", JSONUtils.toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE))); + messageConnector.send(GET_METADATA_RESPONSE, message); + } + } + } } \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java new file mode 100644 index 0000000..7058c18 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java @@ -0,0 +1,34 @@ +package org.eclipse.flux.core.handlers; + +import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; +import org.json.JSONArray; +import org.json.JSONObject; + +public class ProjectRequestHandler extends AbstractFluxMessageHandler { + + public ProjectRequestHandler(MessageConnector messageConnector, Repository repository) { + super(messageConnector, repository, GET_PROJECT_REQUEST); + } + + @Override + protected void onMessage(String type, JSONObject message) throws Exception { + Project project = repository.getProject(message.getString(MessageConstants.PROJECT_NAME)); + if(project == null) + return; + JSONArray files = new JSONArray(); + for(Resource resource : project.getResources()){ + JSONObject file = new JSONObject(); + file.put(MessageConstants.PATH, resource.path()); + file.put(MessageConstants.TIMESTAMP, resource.timestamp()); + file.put(MessageConstants.HASH, resource.hash()); + file.put(MessageConstants.TYPE, resource.type().name().toLowerCase()); + files.put(file); + } + message.put(MessageConstants.FILES, files); + messageConnector.send(GET_PROJECT_RESPONSE, message); + } +} \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java new file mode 100644 index 0000000..e70c068 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java @@ -0,0 +1,71 @@ +package org.eclipse.flux.core.handlers; + +import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; +import org.json.JSONArray; +import org.json.JSONObject; + +public class ProjectResponseHandler extends AbstractFluxMessageHandler { + private int callbackID; + + public ProjectResponseHandler(MessageConnector messageConnector, Repository repository, int callbackID) { + super(messageConnector, repository, GET_PROJECT_RESPONSE); + this.callbackID = callbackID; + } + + @Override + protected void onMessage(String type, JSONObject message) throws Exception { + JSONArray files = message.getJSONArray(MessageConstants.FILES); + JSONArray deleted = message.getJSONArray(MessageConstants.DELETED); + Project project = repository.getProject(message.getString(MessageConstants.PROJECT_NAME)); + if(project == null) + return; + for(int i = 0; i < files.length(); i++){ + JSONObject resource = files.getJSONObject(i); + String path = resource.getString(MessageConstants.PATH); + long timestamp = resource.getLong(MessageConstants.TIMESTAMP); + String hash = resource.optString(MessageConstants.HASH); + Resource localResource = project.getResource(path); + switch(getResourceType(resource)){ + case FILE: + if(localResource == null || IsResourcesNotEquals(localResource, hash, timestamp)){ + JSONObject content = new JSONObject(); + content.put(MessageConstants.CALLBACK_ID, callbackID); + content.put(MessageConstants.PROJECT, project.id()); + content.put(MessageConstants.RESOURCE, path); + content.put(MessageConstants.TIMESTAMP, timestamp); + content.put(MessageConstants.HASH, hash); + messageConnector.send(GET_RESOURCE_REQUEST, content); + } + break; + case FOLDER: + if(localResource == null) + project.createResource(Resource.newFolder(path, timestamp)); + break; + default: + break; + } + } + if(deleted != null){ + for(int i = 0; i < deleted.length(); i++){ + JSONObject resource = deleted.getJSONObject(i); + String path = resource.getString(MessageConstants.PATH); + long timestamp = resource.getLong(MessageConstants.TIMESTAMP); + Resource localResource = project.getResource(path); + if(localResource != null && localResource.timestamp() < timestamp) + project.deleteResource(localResource); + } + } + + } + + @Override + public boolean canHandle(String messageType, JSONObject message) { + return super.canHandle(messageType, message) && message.has("callback_id") + && message.optInt("callback_id") == this.callbackID; + } + +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java new file mode 100644 index 0000000..47f9415 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java @@ -0,0 +1,37 @@ +package org.eclipse.flux.core.handlers; + +import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.spi.Project; +import org.json.JSONArray; +import org.json.JSONObject; + +public class ProjectsResponseHandler extends AbstractFluxMessageHandler { + + public ProjectsResponseHandler(MessageConnector messageConnector, Repository repository) { + super(messageConnector, repository, "getProjectsRequest"); + } + + @Override + protected void onMessage(String type, JSONObject message) throws Exception { + int callbackID = message.optInt(MessageConstants.CALLBACK_ID); + String requestSenderId = message.getString(MessageConstants.REQUEST_SENDER_ID); + String username = message.getString(MessageConstants.USERNAME); + + JSONArray projects = new JSONArray(); + for (Project fluxProject : repository.getSynchronizedProjects()) { + JSONObject project = new JSONObject(); + project.put("name", fluxProject.id()); + projects.put(project); + } + + JSONObject content = new JSONObject(); + content.put("callback_id", callbackID); + content.put("requestSenderID", requestSenderId); + content.put("username", username); + content.put("projects", projects); + + messageConnector.send("getProjectsResponse", content); + } +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java new file mode 100644 index 0000000..5c04170 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java @@ -0,0 +1,43 @@ +package org.eclipse.flux.core.handlers; + +import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.Resource.ResourceType; +import org.eclipse.flux.watcher.core.spi.Project; +import org.json.JSONObject; +//Add listener for notifyResourceChanged +public class ResourceChangedHandler extends AbstractFluxMessageHandler { + private int callbackId; + + public ResourceChangedHandler(MessageConnector messageConnector, Repository repository, int callbackID) { + super(messageConnector, repository, RESOURCE_CHANGED); + this.callbackId = callbackID; + } + + @Override + protected void onMessage(String type, JSONObject message) throws Exception { + String username = message.getString(MessageConstants.USERNAME); + String projectName = message.getString(MessageConstants.PROJECT_NAME); + String resourcePath = message.getString(MessageConstants.RESOURCE); + long resourceTimestamp = message.getLong(MessageConstants.TIMESTAMP); + String resourceHash = message.getString(MessageConstants.HASH); + Project project = repository.getProject(projectName); + if(project == null) + return; + Resource localResource = project.getResource(resourcePath); + if(localResource == null || localResource.type() != ResourceType.FILE) + return; + if (localResource != null && IsResourcesNotEquals(localResource, resourceHash, resourceTimestamp)) { + JSONObject content = new JSONObject(); + content.put(MessageConstants.CALLBACK_ID, this.callbackId); + content.put(MessageConstants.USERNAME, username); + content.put(MessageConstants.PROJECT_NAME, projectName); + content.put(MessageConstants.RESOURCE, resourcePath); + content.put(MessageConstants.TIMESTAMP, resourceTimestamp); + content.put(MessageConstants.HASH, resourceHash); + messageConnector.send(GET_RESOURCE_REQUEST, content); + } + } +} \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java new file mode 100644 index 0000000..14ba970 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java @@ -0,0 +1,48 @@ +package org.eclipse.flux.core.handlers; + +import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; +import org.json.JSONObject; + +public class ResourceCreatedHandler extends AbstractFluxMessageHandler { + private int callbackID; + + public ResourceCreatedHandler(MessageConnector messageConnector, Repository repository, int callbackID) { + super(messageConnector, repository, RESOURCE_CREATED); + this.callbackID = callbackID; + } + + @Override + protected void onMessage(String type, JSONObject message) throws Exception { + String projectName = message.getString(MessageConstants.PROJECT_NAME); + String resourcePath = message.getString(MessageConstants.RESOURCE); + long resourceTimestamp = message.getLong(MessageConstants.TIMESTAMP); + String resourceHash = message.getString(MessageConstants.HASH); + String username = message.getString(MessageConstants.USERNAME); + Project project = repository.getProject(projectName); + if(project == null || project.hasResource(resourcePath)) + return; + JSONObject content = new JSONObject(); + content.put(MessageConstants.USERNAME, username); + content.put(MessageConstants.PROJECT_NAME, projectName); + content.put(MessageConstants.RESOURCE, resourcePath); + content.put(MessageConstants.TIMESTAMP, resourceTimestamp); + content.put(MessageConstants.HASH, resourceHash); + content.put(MessageConstants.TYPE, getResourceType(message).name().toLowerCase()); + switch(getResourceType(message)){ + case FILE: + content.put(MessageConstants.CALLBACK_ID, callbackID); + messageConnector.send(GET_RESOURCE_REQUEST, content); + break; + case FOLDER: + project.createResource(Resource.newFolder(resourcePath, resourceTimestamp)); + messageConnector.send(RESOURCE_STORED, content); + break; + default: + break; + } + } +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java new file mode 100644 index 0000000..1fe342a --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java @@ -0,0 +1,33 @@ +package org.eclipse.flux.core.handlers; + +import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; +import org.json.JSONObject; + +public class ResourceDeletedHandler extends AbstractFluxMessageHandler { + + public ResourceDeletedHandler(MessageConnector messageConnector, Repository repository) { + super(messageConnector, repository, RESOURCE_DELETED); + } + + @Override + protected void onMessage(String type, JSONObject message) throws Exception { + String projectName = message.getString(MessageConstants.PROJECT_NAME); + String resourcePath = message.getString(MessageConstants.RESOURCE); + long resourceTimestamp = message.getLong(MessageConstants.TIMESTAMP); + Project project = repository.getProject(projectName); + if(project == null) + return; + Resource localResource = project.getResource(resourcePath); + if(localResource == null) + return; + boolean isLocalResourceOutdated = localResource.timestamp() < resourceTimestamp; + if (isLocalResourceOutdated) { + project.deleteResource(Resource.newUnknown(resourcePath, resourceTimestamp)); + } + } + +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java new file mode 100644 index 0000000..9a2697e --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java @@ -0,0 +1,34 @@ +package org.eclipse.flux.core.handlers; + +import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.Resource.ResourceType; +import org.eclipse.flux.watcher.core.spi.Project; +import org.json.JSONObject; + +public class ResourceRequestHandler extends AbstractFluxMessageHandler { + public ResourceRequestHandler(MessageConnector messageConnector, Repository repository) { + super(messageConnector, repository, GET_RESOURCE_REQUEST); + } + + @Override + protected void onMessage(String type, JSONObject message) throws Exception { + Project project = repository.getProject(message.getString(MessageConstants.PROJECT_NAME)); + if (project == null) + return; + Resource resource = project.getResource(message.getString(MessageConstants.RESOURCE)); + if (resource == null || message.has("timestamp") && message.getLong("timestamp") != resource.timestamp()) + return; + message.put(MessageConstants.TIMESTAMP, resource.timestamp()); + message.put(MessageConstants.HASH, resource.hash()); + message.put(MessageConstants.TYPE, resource.type().name().toLowerCase()); + if (resource.type() == ResourceType.FILE) { + if(message.has("hash") && !message.getString("hash").equals(resource.hash())) + return; + message.put(MessageConstants.CONTENT, new String(resource.content())); + } + messageConnector.send(GET_RESOURCE_RESPONSE, message); + } +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java new file mode 100644 index 0000000..685d179 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java @@ -0,0 +1,76 @@ +package org.eclipse.flux.core.handlers; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Path; +import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.Resource.ResourceType; +import org.eclipse.flux.watcher.core.spi.Project; +import org.json.JSONObject; + +public class ResourceResponseHandler extends AbstractFluxMessageHandler { + private int callbackID; + + public ResourceResponseHandler(MessageConnector messageConnector, Repository repository, int callbackID) { + super(messageConnector, repository, GET_RESOURCE_RESPONSE); + this.callbackID = callbackID; + } + + @Override + protected void onMessage(String type, JSONObject message) throws Exception { + String projectName = message.getString(MessageConstants.PROJECT_NAME); + String resourcePath = message.getString(MessageConstants.RESOURCE); + long resourceTimestamp = message.getLong(MessageConstants.TIMESTAMP); + String resourceHash = message.getString(MessageConstants.HASH); + String resourceContent = message.getString(MessageConstants.CONTENT); + String username = message.getString(MessageConstants.USERNAME); + + Project project = repository.getProject(projectName); + if(project == null) + return; + boolean isResourceStore = false; + Resource localResource = project.getResource(resourcePath); + Resource newResource = Resource.newFile(resourcePath, resourceTimestamp, resourceContent.getBytes()); + if(localResource != null && localResource.type() == ResourceType.FILE) + { + if(IsResourcesNotEquals(localResource, resourceHash, resourceTimestamp)){ + project.updateResource(newResource); + isResourceStore = true; + } + } + else { + project.createResource(newResource); + isResourceStore = true; + } + + if(isResourceStore){ + updateEclipseEditor(projectName, resourcePath); + JSONObject content = new JSONObject(); + content.put(MessageConstants.USERNAME, username); + content.put(MessageConstants.PROJECT_NAME, projectName); + content.put(MessageConstants.RESOURCE, resourcePath); + content.put(MessageConstants.TIMESTAMP, resourceTimestamp); + content.put(MessageConstants.HASH, resourceHash); + content.put(MessageConstants.TYPE, "file"); + messageConnector.send(RESOURCE_STORED, content); + } + } + + private void updateEclipseEditor(String projectName, String resourcePath) throws CoreException { + Path path = new Path(projectName + "/" + resourcePath); + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); + file.refreshLocal(IResource.DEPTH_ZERO, null); + } + + @Override + public boolean canHandle(String messageType, JSONObject message) { + return super.canHandle(messageType, message) + && message.has("callback_id") + && message.optInt("callback_id") == callbackID; + } +} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java index bbd8f2f..7d4ee5e 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java @@ -113,7 +113,7 @@ public Project addProject(String projectId, String projectPath) { project.setSynchronized(true); projects.add(project); - try { + /*try { JSONObject content = new JSONObject().put(PROJECT, projectId); messageBus.sendMessages(new FluxMessage(PROJECT_CONNECTED, content)); @@ -123,7 +123,7 @@ public Project addProject(String projectId, String projectPath) { } catch (JSONException e) { throw new RuntimeException(e); - } + }*/ } return project; } @@ -141,14 +141,14 @@ public Project removeProject(String projectId) { projects.remove(project); project.setSynchronized(false); - try { + /*try { final JSONObject content = new JSONObject().put(PROJECT, projectId); messageBus.sendMessages(new FluxMessage(PROJECT_DISCONNECTED, content)); } catch (JSONException e) { throw new RuntimeException(e); - } + }*/ } return project; } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEventBus.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEventBus.java index ee08c42..40e4e5d 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEventBus.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryEventBus.java @@ -102,6 +102,8 @@ public void fireRepositoryEvent(final RepositoryEvent event) { @Override public boolean apply(RepositoryListener listener) { final RepositoryEventTypes repositoryEventTypes = listener.getClass().getAnnotation(RepositoryEventTypes.class); + if(repositoryEventTypes == null) + return true; return asList(repositoryEventTypes.value()).contains(event.type()); } }));; diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryModule.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryModule.java index 93453cb..8748944 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryModule.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryModule.java @@ -28,18 +28,18 @@ protected void configure() { // message handler bindings final Multibinder messageHandlers = Multibinder.newSetBinder(binder(), FluxMessageHandler.class); - messageHandlers.addBinding().to(GetResourceRequestHandler.class); - messageHandlers.addBinding().to(GetResourceResponseHandler.class); - messageHandlers.addBinding().to(GetProjectRequestHandler.class); - messageHandlers.addBinding().to(GetProjectResponseHandler.class); - messageHandlers.addBinding().to(ResourceCreatedHandler.class); - messageHandlers.addBinding().to(ResourceDeletedHandler.class); - messageHandlers.addBinding().to(ResourceChangedHandler.class); + //messageHandlers.addBinding().to(GetResourceRequestHandler.class); + //messageHandlers.addBinding().to(GetResourceResponseHandler.class); + //messageHandlers.addBinding().to(GetProjectRequestHandler.class); + //messageHandlers.addBinding().to(GetProjectResponseHandler.class); + //messageHandlers.addBinding().to(ResourceCreatedHandler.class); + //messageHandlers.addBinding().to(ResourceDeletedHandler.class); + //messageHandlers.addBinding().to(ResourceChangedHandler.class); // repository listener bindings final Multibinder repositoryListeners = Multibinder.newSetBinder(binder(), RepositoryListener.class); - repositoryListeners.addBinding().to(ProjectResourceCreatedListener.class); - repositoryListeners.addBinding().to(ProjectResourceDeletedListener.class); - repositoryListeners.addBinding().to(ProjectResourceModifiedListener.class); + //repositoryListeners.addBinding().to(ProjectResourceCreatedListener.class); + //repositoryListeners.addBinding().to(ProjectResourceDeletedListener.class); + //repositoryListeners.addBinding().to(ProjectResourceModifiedListener.class); } } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java index be3f2ab..029db71 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java @@ -39,7 +39,6 @@ * * @author Kevin Pollet */ -@Singleton @FluxMessageTypes(GET_PROJECT_REQUEST) public final class GetProjectRequestHandler implements FluxMessageHandler { @Override diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java index b512226..a0fdef0 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java @@ -43,7 +43,6 @@ * * @author Kevin Pollet */ -@Singleton @FluxMessageTypes(GET_PROJECT_RESPONSE) public final class GetProjectResponseHandler implements FluxMessageHandler { @Override diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java index 0a7ffaa..c09adcd 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java @@ -39,7 +39,6 @@ * * @author Kevin Pollet */ -@Singleton @FluxMessageTypes(GET_RESOURCE_REQUEST) public final class GetResourceRequestHandler implements FluxMessageHandler { @Override diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java index 742d433..9e4e0c6 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java @@ -38,7 +38,6 @@ * * @author Kevin Pollet */ -@Singleton @FluxMessageTypes(GET_RESOURCE_RESPONSE) public final class GetResourceResponseHandler implements FluxMessageHandler { @Override diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java index 165d6ec..925326b 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java @@ -38,7 +38,7 @@ * @author Kevin Pollet */ @Singleton -@RepositoryEventTypes(PROJECT_RESOURCE_CREATED) +//@RepositoryEventTypes(PROJECT_RESOURCE_CREATED) public final class ProjectResourceCreatedListener implements RepositoryListener { private final FluxMessageBus messageBus; diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java index ef942f1..784f0a2 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java @@ -35,7 +35,7 @@ * @author Kevin Pollet */ @Singleton -@RepositoryEventTypes(PROJECT_RESOURCE_DELETED) +//@RepositoryEventTypes(PROJECT_RESOURCE_DELETED) public final class ProjectResourceDeletedListener implements RepositoryListener { private final FluxMessageBus messageBus; diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java index 022c377..d1d9402 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java @@ -38,7 +38,7 @@ * @author Kevin Pollet */ @Singleton -@RepositoryEventTypes(PROJECT_RESOURCE_MODIFIED) +//@RepositoryEventTypes(PROJECT_RESOURCE_MODIFIED) public final class ProjectResourceModifiedListener implements RepositoryListener { private final FluxMessageBus messageBus; diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java index 3450e69..849f901 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java @@ -34,7 +34,6 @@ * * @author Kevin Pollet */ -@Singleton @FluxMessageTypes(RESOURCE_CHANGED) public final class ResourceChangedHandler implements FluxMessageHandler { @Override diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java index 234f2a1..41255a2 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java @@ -38,7 +38,6 @@ * * @author Kevin Pollet */ -@Singleton @FluxMessageTypes(RESOURCE_CREATED) public final class ResourceCreatedHandler implements FluxMessageHandler { @Override diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java index 0954c38..684f1ac 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java @@ -32,7 +32,6 @@ * * @author Kevin Pollet */ -@Singleton @FluxMessageTypes(RESOURCE_DELETED) public final class ResourceDeletedHandler implements FluxMessageHandler { @Override diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/utils/ResourceHelper.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/utils/ResourceHelper.java index 44e52d8..da9d1cd 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/utils/ResourceHelper.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/utils/ResourceHelper.java @@ -45,7 +45,7 @@ public final class ResourceHelper { */ public static String sha1(byte[] bytes) { final byte[] digest = messageDigest.digest(checkNotNull(bytes)); - return DatatypeConverter.printHexBinary(digest); + return DatatypeConverter.printHexBinary(digest).toLowerCase(); } /** diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java index d5e1a23..b7f745c 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/fs/JDKProjectWatchService.java @@ -263,9 +263,9 @@ private Resource pathToResource(Kind kind, Project project, Path resourceP private long getLastModifiedTime(Path resourcePath) { try { - return Files.getLastModifiedTime(resourcePath).toMillis() / 1000 * 1000; + return Files.getLastModifiedTime(resourcePath).toMillis(); } catch (IOException | NullPointerException e) { - return System.currentTimeMillis() / 1000 * 1000; + return System.currentTimeMillis(); } } From f352ae7b2c95eba569bc85998bf50bf9a9672f99 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Mon, 22 Aug 2016 16:56:53 +0300 Subject: [PATCH 27/34] Improved code: Add callback to the constructor of AbstractMsgHandler Signed-off-by: Fjodor Vershinin --- .../flux/core/IRepositoryCallback.java | 14 ++++ .../eclipse/flux/core/RepositoryAdapter.java | 82 +++++++++---------- ...geHandler.java => AbstractMsgHandler.java} | 13 ++- .../core/handlers/MetadataRequestHandler.java | 17 ++-- .../core/handlers/ProjectRequestHandler.java | 14 ++-- .../core/handlers/ProjectResponseHandler.java | 13 ++- .../handlers/ProjectsResponseHandler.java | 13 ++- .../core/handlers/ResourceChangedHandler.java | 13 ++- .../core/handlers/ResourceCreatedHandler.java | 15 ++-- .../core/handlers/ResourceDeletedHandler.java | 11 ++- .../core/handlers/ResourceRequestHandler.java | 13 ++- .../handlers/ResourceResponseHandler.java | 13 ++- 12 files changed, 114 insertions(+), 117 deletions(-) create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java rename org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/{AbstractFluxMessageHandler.java => AbstractMsgHandler.java} (71%) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java new file mode 100644 index 0000000..2230dd2 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java @@ -0,0 +1,14 @@ +package org.eclipse.flux.core; + +import java.util.Set; + +import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.spi.Project; +import org.json.JSONObject; + +public interface IRepositoryCallback { + void notifyResourceChanged(Resource resource); + void sendMessage(String messageType, JSONObject content) throws Exception; + Project getProject(String projectName); + Set getSynchronizedProjects(); +} \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index 0fb8f6f..60de52f 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -45,7 +45,7 @@ /** * @author Martin Lippert */ -public class RepositoryAdapter { +public class RepositoryAdapter implements IRepositoryCallback{ private static int GET_PROJECT_CALLBACK = "Repository - getProjectCallback".hashCode(); private static int GET_RESOURCE_CALLBACK = "Repository - getResourceCallback".hashCode(); @@ -65,42 +65,16 @@ public RepositoryAdapter(MessageConnector messageConnector, Repository repositor this.username = user; this.messageHandlers = new ArrayList<>(); this.repositoryListeners = new ConcurrentLinkedDeque<>(); - - IMessageHandler metadataRequestHandler = new MetadataRequestHandler(messageConnector, repository); - this.messageConnector.addMessageHandler(metadataRequestHandler); - this.messageHandlers.add(metadataRequestHandler); - IMessageHandler projectsRequestHandler = new ProjectsResponseHandler(messageConnector, repository); - this.messageConnector.addMessageHandler(projectsRequestHandler); - this.messageHandlers.add(projectsRequestHandler); - - IMessageHandler projectRequestHandler = new ProjectRequestHandler(messageConnector, repository); - this.messageConnector.addMessageHandler(projectRequestHandler); - this.messageHandlers.add(projectRequestHandler); - - IMessageHandler projectResponseHandler = new ProjectResponseHandler(messageConnector, repository, GET_PROJECT_CALLBACK); - this.messageConnector.addMessageHandler(projectResponseHandler); - this.messageHandlers.add(projectResponseHandler); - - IMessageHandler resourceRequestHandler = new ResourceRequestHandler(messageConnector, repository); - this.messageConnector.addMessageHandler(resourceRequestHandler); - this.messageHandlers.add(resourceRequestHandler); - - IMessageHandler resourceResponseHandler = new ResourceResponseHandler(messageConnector, repository, GET_RESOURCE_CALLBACK); - this.messageConnector.addMessageHandler(resourceResponseHandler); - this.messageHandlers.add(resourceResponseHandler); - - IMessageHandler resourceCreatedHandler = new ResourceCreatedHandler(messageConnector, repository, GET_RESOURCE_CALLBACK); - this.messageConnector.addMessageHandler(resourceCreatedHandler); - this.messageHandlers.add(resourceCreatedHandler); - - IMessageHandler resourceChangedHandler = new ResourceChangedHandler(messageConnector, repository, GET_RESOURCE_CALLBACK); - this.messageConnector.addMessageHandler(resourceChangedHandler); - this.messageHandlers.add(resourceChangedHandler); - - IMessageHandler resourceDeletedHandler = new ResourceDeletedHandler(messageConnector, repository); - this.messageConnector.addMessageHandler(resourceDeletedHandler); - this.messageHandlers.add(resourceDeletedHandler); + addMessageHandler(new MetadataRequestHandler(this)); + addMessageHandler(new ProjectsResponseHandler(this)); + addMessageHandler(new ProjectRequestHandler(this)); + addMessageHandler(new ProjectResponseHandler(this, GET_PROJECT_CALLBACK)); + addMessageHandler(new ResourceRequestHandler(this)); + addMessageHandler(new ResourceResponseHandler(this, GET_RESOURCE_CALLBACK)); + addMessageHandler(new ResourceCreatedHandler(this, GET_RESOURCE_CALLBACK)); + addMessageHandler(new ResourceChangedHandler(this, GET_RESOURCE_CALLBACK)); + addMessageHandler(new ResourceDeletedHandler(this)); this.repositoryEventBus.addRepositoryListener(new RepositoryListener() { @Override @@ -149,13 +123,8 @@ public String getUsername() { } public ConnectedProject getProject(IProject project) { - return getProject(project.getName()); - } - - public ConnectedProject getProject(String projectName) { - return new ConnectedProject(repository.getProject(projectName)); - } - + return new ConnectedProject(repository.getProject(project.getName())); + } public boolean isConnected(IProject project) { return isConnected(project.getName()); @@ -278,4 +247,31 @@ public void dispose() { } } + private void addMessageHandler(IMessageHandler messageHandler){ + this.messageConnector.addMessageHandler(messageHandler); + this.messageHandlers.add(messageHandler); + } + + @Override + public void notifyResourceChanged(Resource resource) { + // TODO Auto-generated method stub + + } + + @Override + public void sendMessage(String messageType, JSONObject content) throws Exception { + messageConnector.send(messageType, content); + } + + @Override + public Project getProject(String projectName) { + return repository.getProject(projectName); + } + + @Override + public Set getSynchronizedProjects() { + return repository.getSynchronizedProjects(); + } + + } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractFluxMessageHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractMsgHandler.java similarity index 71% rename from org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractFluxMessageHandler.java rename to org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractMsgHandler.java index 12b4892..6eb6f99 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractFluxMessageHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractMsgHandler.java @@ -1,21 +1,18 @@ package org.eclipse.flux.core.handlers; -import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageConstants; import org.eclipse.flux.client.MessageHandler; -import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.json.JSONObject; -public abstract class AbstractFluxMessageHandler extends MessageHandler { - protected Repository repository; - protected MessageConnector messageConnector; +public abstract class AbstractMsgHandler extends MessageHandler { + protected IRepositoryCallback repositoryCallback; - public AbstractFluxMessageHandler(MessageConnector messageConnector, Repository repository, String type) { + public AbstractMsgHandler(IRepositoryCallback repositoryCallback, String type) { super(type); - this.repository = repository; - this.messageConnector = messageConnector; + this.repositoryCallback = repositoryCallback; } @Override diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java index 703109b..79af1a2 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java @@ -1,37 +1,34 @@ package org.eclipse.flux.core.handlers; -import java.text.MessageFormat; - import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Path; -import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.core.util.JSONUtils; -import org.eclipse.flux.watcher.core.Repository; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; -public class MetadataRequestHandler extends AbstractFluxMessageHandler { +public class MetadataRequestHandler extends AbstractMsgHandler { - public MetadataRequestHandler(MessageConnector messageConnector, Repository repository) { - super(messageConnector, repository, GET_METADATA_REQUEST); + public MetadataRequestHandler(IRepositoryCallback repositoryCallback) { + super(repositoryCallback, GET_METADATA_REQUEST); } @Override protected void onMessage(String type, JSONObject message) throws Exception { String projectName = message.getString("project"); String resourcePath = message.getString("resource"); - Project project = repository.getProject(projectName); + Project project = repositoryCallback.getProject(projectName); if(project != null){ Resource resource = project.getResource(resourcePath); if(resource != null){ - Path path = new Path(MessageFormat.format("{0}/{1}", projectName, resourcePath)); + Path path = new Path(projectName + "/" + resourcePath); IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); message.put("type", "marker"); message.put("metadata", JSONUtils.toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE))); - messageConnector.send(GET_METADATA_RESPONSE, message); + repositoryCallback.sendMessage(GET_METADATA_RESPONSE, message); } } } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java index 7058c18..9bbf3c3 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java @@ -1,22 +1,22 @@ package org.eclipse.flux.core.handlers; -import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; import org.json.JSONObject; -public class ProjectRequestHandler extends AbstractFluxMessageHandler { +public class ProjectRequestHandler extends AbstractMsgHandler { - public ProjectRequestHandler(MessageConnector messageConnector, Repository repository) { - super(messageConnector, repository, GET_PROJECT_REQUEST); + public ProjectRequestHandler(IRepositoryCallback repositoryCallback) { + super(repositoryCallback, GET_PROJECT_REQUEST); } @Override protected void onMessage(String type, JSONObject message) throws Exception { - Project project = repository.getProject(message.getString(MessageConstants.PROJECT_NAME)); + String projectName = message.getString(MessageConstants.PROJECT_NAME); + Project project = repositoryCallback.getProject(projectName); if(project == null) return; JSONArray files = new JSONArray(); @@ -29,6 +29,6 @@ protected void onMessage(String type, JSONObject message) throws Exception { files.put(file); } message.put(MessageConstants.FILES, files); - messageConnector.send(GET_PROJECT_RESPONSE, message); + repositoryCallback.sendMessage(GET_PROJECT_RESPONSE, message); } } \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java index e70c068..ad84fdb 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java @@ -1,18 +1,17 @@ package org.eclipse.flux.core.handlers; -import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; import org.json.JSONObject; -public class ProjectResponseHandler extends AbstractFluxMessageHandler { +public class ProjectResponseHandler extends AbstractMsgHandler { private int callbackID; - public ProjectResponseHandler(MessageConnector messageConnector, Repository repository, int callbackID) { - super(messageConnector, repository, GET_PROJECT_RESPONSE); + public ProjectResponseHandler(IRepositoryCallback repositoryCallback, int callbackID) { + super(repositoryCallback, GET_PROJECT_RESPONSE); this.callbackID = callbackID; } @@ -20,7 +19,7 @@ public ProjectResponseHandler(MessageConnector messageConnector, Repository repo protected void onMessage(String type, JSONObject message) throws Exception { JSONArray files = message.getJSONArray(MessageConstants.FILES); JSONArray deleted = message.getJSONArray(MessageConstants.DELETED); - Project project = repository.getProject(message.getString(MessageConstants.PROJECT_NAME)); + Project project = repositoryCallback.getProject(message.getString(MessageConstants.PROJECT_NAME)); if(project == null) return; for(int i = 0; i < files.length(); i++){ @@ -38,7 +37,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { content.put(MessageConstants.RESOURCE, path); content.put(MessageConstants.TIMESTAMP, timestamp); content.put(MessageConstants.HASH, hash); - messageConnector.send(GET_RESOURCE_REQUEST, content); + repositoryCallback.sendMessage(GET_RESOURCE_REQUEST, content); } break; case FOLDER: diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java index 47f9415..f91bdb6 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java @@ -1,16 +1,15 @@ package org.eclipse.flux.core.handlers; -import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; import org.json.JSONObject; -public class ProjectsResponseHandler extends AbstractFluxMessageHandler { +public class ProjectsResponseHandler extends AbstractMsgHandler { - public ProjectsResponseHandler(MessageConnector messageConnector, Repository repository) { - super(messageConnector, repository, "getProjectsRequest"); + public ProjectsResponseHandler(IRepositoryCallback repositoryCallback) { + super(repositoryCallback, "getProjectsRequest"); } @Override @@ -20,7 +19,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { String username = message.getString(MessageConstants.USERNAME); JSONArray projects = new JSONArray(); - for (Project fluxProject : repository.getSynchronizedProjects()) { + for (Project fluxProject : repositoryCallback.getSynchronizedProjects()) { JSONObject project = new JSONObject(); project.put("name", fluxProject.id()); projects.put(project); @@ -32,6 +31,6 @@ protected void onMessage(String type, JSONObject message) throws Exception { content.put("username", username); content.put("projects", projects); - messageConnector.send("getProjectsResponse", content); + repositoryCallback.sendMessage("getProjectsResponse", content); } } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java index 5c04170..83bec46 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java @@ -1,18 +1,17 @@ package org.eclipse.flux.core.handlers; -import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; //Add listener for notifyResourceChanged -public class ResourceChangedHandler extends AbstractFluxMessageHandler { +public class ResourceChangedHandler extends AbstractMsgHandler { private int callbackId; - public ResourceChangedHandler(MessageConnector messageConnector, Repository repository, int callbackID) { - super(messageConnector, repository, RESOURCE_CHANGED); + public ResourceChangedHandler(IRepositoryCallback repositoryCallback, int callbackID) { + super(repositoryCallback, RESOURCE_CHANGED); this.callbackId = callbackID; } @@ -23,7 +22,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { String resourcePath = message.getString(MessageConstants.RESOURCE); long resourceTimestamp = message.getLong(MessageConstants.TIMESTAMP); String resourceHash = message.getString(MessageConstants.HASH); - Project project = repository.getProject(projectName); + Project project = repositoryCallback.getProject(projectName); if(project == null) return; Resource localResource = project.getResource(resourcePath); @@ -37,7 +36,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { content.put(MessageConstants.RESOURCE, resourcePath); content.put(MessageConstants.TIMESTAMP, resourceTimestamp); content.put(MessageConstants.HASH, resourceHash); - messageConnector.send(GET_RESOURCE_REQUEST, content); + repositoryCallback.sendMessage(GET_RESOURCE_REQUEST, content); } } } \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java index 14ba970..9ccebf1 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java @@ -1,17 +1,16 @@ package org.eclipse.flux.core.handlers; -import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; -public class ResourceCreatedHandler extends AbstractFluxMessageHandler { +public class ResourceCreatedHandler extends AbstractMsgHandler { private int callbackID; - public ResourceCreatedHandler(MessageConnector messageConnector, Repository repository, int callbackID) { - super(messageConnector, repository, RESOURCE_CREATED); + public ResourceCreatedHandler(IRepositoryCallback repositoryCallback, int callbackID) { + super(repositoryCallback, RESOURCE_CREATED); this.callbackID = callbackID; } @@ -22,7 +21,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { long resourceTimestamp = message.getLong(MessageConstants.TIMESTAMP); String resourceHash = message.getString(MessageConstants.HASH); String username = message.getString(MessageConstants.USERNAME); - Project project = repository.getProject(projectName); + Project project = repositoryCallback.getProject(projectName); if(project == null || project.hasResource(resourcePath)) return; JSONObject content = new JSONObject(); @@ -35,11 +34,11 @@ protected void onMessage(String type, JSONObject message) throws Exception { switch(getResourceType(message)){ case FILE: content.put(MessageConstants.CALLBACK_ID, callbackID); - messageConnector.send(GET_RESOURCE_REQUEST, content); + repositoryCallback.sendMessage(GET_RESOURCE_REQUEST, content); break; case FOLDER: project.createResource(Resource.newFolder(resourcePath, resourceTimestamp)); - messageConnector.send(RESOURCE_STORED, content); + repositoryCallback.sendMessage(RESOURCE_STORED, content); break; default: break; diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java index 1fe342a..5846e07 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java @@ -1,16 +1,15 @@ package org.eclipse.flux.core.handlers; -import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; -public class ResourceDeletedHandler extends AbstractFluxMessageHandler { +public class ResourceDeletedHandler extends AbstractMsgHandler { - public ResourceDeletedHandler(MessageConnector messageConnector, Repository repository) { - super(messageConnector, repository, RESOURCE_DELETED); + public ResourceDeletedHandler(IRepositoryCallback repositoryCallback) { + super(repositoryCallback, RESOURCE_DELETED); } @Override @@ -18,7 +17,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { String projectName = message.getString(MessageConstants.PROJECT_NAME); String resourcePath = message.getString(MessageConstants.RESOURCE); long resourceTimestamp = message.getLong(MessageConstants.TIMESTAMP); - Project project = repository.getProject(projectName); + Project project = repositoryCallback.getProject(projectName); if(project == null) return; Resource localResource = project.getResource(resourcePath); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java index 9a2697e..8d10938 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java @@ -1,21 +1,20 @@ package org.eclipse.flux.core.handlers; -import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; -public class ResourceRequestHandler extends AbstractFluxMessageHandler { - public ResourceRequestHandler(MessageConnector messageConnector, Repository repository) { - super(messageConnector, repository, GET_RESOURCE_REQUEST); +public class ResourceRequestHandler extends AbstractMsgHandler { + public ResourceRequestHandler(IRepositoryCallback repositoryCallback) { + super(repositoryCallback, GET_RESOURCE_REQUEST); } @Override protected void onMessage(String type, JSONObject message) throws Exception { - Project project = repository.getProject(message.getString(MessageConstants.PROJECT_NAME)); + Project project = repositoryCallback.getProject(message.getString(MessageConstants.PROJECT_NAME)); if (project == null) return; Resource resource = project.getResource(message.getString(MessageConstants.RESOURCE)); @@ -29,6 +28,6 @@ protected void onMessage(String type, JSONObject message) throws Exception { return; message.put(MessageConstants.CONTENT, new String(resource.content())); } - messageConnector.send(GET_RESOURCE_RESPONSE, message); + repositoryCallback.sendMessage(GET_RESOURCE_RESPONSE, message); } } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java index 685d179..5bbfe7b 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java @@ -5,19 +5,18 @@ import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; -import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; -public class ResourceResponseHandler extends AbstractFluxMessageHandler { +public class ResourceResponseHandler extends AbstractMsgHandler { private int callbackID; - public ResourceResponseHandler(MessageConnector messageConnector, Repository repository, int callbackID) { - super(messageConnector, repository, GET_RESOURCE_RESPONSE); + public ResourceResponseHandler(IRepositoryCallback repositoryCallback, int callbackID) { + super(repositoryCallback, GET_RESOURCE_RESPONSE); this.callbackID = callbackID; } @@ -30,7 +29,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { String resourceContent = message.getString(MessageConstants.CONTENT); String username = message.getString(MessageConstants.USERNAME); - Project project = repository.getProject(projectName); + Project project = repositoryCallback.getProject(projectName); if(project == null) return; boolean isResourceStore = false; @@ -57,7 +56,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { content.put(MessageConstants.TIMESTAMP, resourceTimestamp); content.put(MessageConstants.HASH, resourceHash); content.put(MessageConstants.TYPE, "file"); - messageConnector.send(RESOURCE_STORED, content); + repositoryCallback.sendMessage(RESOURCE_STORED, content); } } From 8a4e8485927253a8bfe0a0269549cc601c5aeca5 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Mon, 22 Aug 2016 18:14:31 +0300 Subject: [PATCH 28/34] Added listeners for eclipse Signed-off-by: Fjodor Vershinin --- .../eclipse/flux/core/IRepositoryCallback.java | 2 +- .../org/eclipse/flux/core/RepositoryAdapter.java | 5 +++-- .../core/handlers/MetadataRequestHandler.java | 7 ++----- .../core/handlers/ResourceChangedHandler.java | 5 +++-- .../core/handlers/ResourceResponseHandler.java | 15 ++++----------- .../src/org/eclipse/flux/core/util/Utils.java | 14 ++++++++++++++ 6 files changed, 27 insertions(+), 21 deletions(-) create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/util/Utils.java diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java index 2230dd2..b4b624d 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java @@ -7,7 +7,7 @@ import org.json.JSONObject; public interface IRepositoryCallback { - void notifyResourceChanged(Resource resource); + void notifyResourceChanged(Resource resource, Project project); void sendMessage(String messageType, JSONObject content) throws Exception; Project getProject(String projectName); Set getSynchronizedProjects(); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index 60de52f..0747b8e 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -31,6 +31,7 @@ import org.eclipse.flux.core.handlers.ResourceRequestHandler; import org.eclipse.flux.core.handlers.ResourceResponseHandler; import org.eclipse.flux.core.util.JSONUtils; +import org.eclipse.flux.core.util.Utils; import org.eclipse.flux.client.IMessageHandler; import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.watcher.core.Repository; @@ -253,8 +254,8 @@ private void addMessageHandler(IMessageHandler messageHandler){ } @Override - public void notifyResourceChanged(Resource resource) { - // TODO Auto-generated method stub + public void notifyResourceChanged(Resource resource, Project project) { + notifyResourceChanged(Utils.getResourceByPath(project.id(), resource.path())); } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java index 79af1a2..d59455c 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java @@ -1,11 +1,9 @@ package org.eclipse.flux.core.handlers; -import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.Path; import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.core.util.JSONUtils; +import org.eclipse.flux.core.util.Utils; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; @@ -24,8 +22,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { if(project != null){ Resource resource = project.getResource(resourcePath); if(resource != null){ - Path path = new Path(projectName + "/" + resourcePath); - IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); + IResource file = Utils.getResourceByPath(projectName, resourcePath); message.put("type", "marker"); message.put("metadata", JSONUtils.toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE))); repositoryCallback.sendMessage(GET_METADATA_RESPONSE, message); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java index 83bec46..d50c7f2 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java @@ -6,7 +6,7 @@ import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; -//Add listener for notifyResourceChanged + public class ResourceChangedHandler extends AbstractMsgHandler { private int callbackId; @@ -36,7 +36,8 @@ protected void onMessage(String type, JSONObject message) throws Exception { content.put(MessageConstants.RESOURCE, resourcePath); content.put(MessageConstants.TIMESTAMP, resourceTimestamp); content.put(MessageConstants.HASH, resourceHash); - repositoryCallback.sendMessage(GET_RESOURCE_REQUEST, content); + repositoryCallback.sendMessage(GET_RESOURCE_REQUEST, content); + repositoryCallback.notifyResourceChanged(localResource, project); } } } \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java index 5bbfe7b..88b1186 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java @@ -1,12 +1,9 @@ package org.eclipse.flux.core.handlers; -import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.Path; import org.eclipse.flux.client.MessageConstants; import org.eclipse.flux.core.IRepositoryCallback; +import org.eclipse.flux.core.util.Utils; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.eclipse.flux.watcher.core.spi.Project; @@ -48,7 +45,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { } if(isResourceStore){ - updateEclipseEditor(projectName, resourcePath); + Utils.getResourceByPath(projectName, resourcePath).refreshLocal(IResource.DEPTH_ZERO, null); JSONObject content = new JSONObject(); content.put(MessageConstants.USERNAME, username); content.put(MessageConstants.PROJECT_NAME, projectName); @@ -57,14 +54,10 @@ protected void onMessage(String type, JSONObject message) throws Exception { content.put(MessageConstants.HASH, resourceHash); content.put(MessageConstants.TYPE, "file"); repositoryCallback.sendMessage(RESOURCE_STORED, content); + if(localResource != null) + repositoryCallback.notifyResourceChanged(localResource, project); } } - - private void updateEclipseEditor(String projectName, String resourcePath) throws CoreException { - Path path = new Path(projectName + "/" + resourcePath); - IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); - file.refreshLocal(IResource.DEPTH_ZERO, null); - } @Override public boolean canHandle(String messageType, JSONObject message) { diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/util/Utils.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/util/Utils.java new file mode 100644 index 0000000..e969a6b --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/util/Utils.java @@ -0,0 +1,14 @@ +package org.eclipse.flux.core.util; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.Path; + +public class Utils { + public static IResource getResourceByPath(String projectName, String resourcePath){ + Path path = new Path(projectName + "/" + resourcePath); + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); + return file; + } +} From 1134f62f26e1f1d1ad1822d04fa4ff67de834637 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Mon, 22 Aug 2016 19:28:51 +0300 Subject: [PATCH 29/34] Switched back to the old mechanism of sending/receiving messages[live edit] Signed-off-by: Fjodor Vershinin --- .../src/org/eclipse/flux/core/Activator.java | 2 +- .../flux/core/IRepositoryCallback.java | 2 +- .../flux/core/LiveEditCoordinator.java | 45 ++++++++++--------- .../eclipse/flux/core/RepositoryAdapter.java | 8 +++- .../handlers/LiveResourceChangedHandler.java | 35 ++++++--------- .../handlers/LiveResourceRequestHandler.java | 34 +++++--------- .../handlers/LiveResourceStartedHandler.java | 41 +++++++---------- .../LiveResourceStartedResponseHandler.java | 38 ++++++---------- .../core/handlers/MetadataRequestHandler.java | 2 +- .../core/handlers/ProjectRequestHandler.java | 2 +- .../core/handlers/ProjectResponseHandler.java | 2 +- .../core/handlers/ResourceChangedHandler.java | 2 +- .../core/handlers/ResourceCreatedHandler.java | 2 +- .../core/handlers/ResourceDeletedHandler.java | 2 +- .../core/handlers/ResourceRequestHandler.java | 2 +- .../handlers/ResourceResponseHandler.java | 2 +- 16 files changed, 94 insertions(+), 127 deletions(-) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java index 3a2628a..394fd0c 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java @@ -177,7 +177,7 @@ public void stop(BundleContext context) throws Exception { private void initCoreService(String userChannel) throws CoreException { repository = new RepositoryAdapter(messageConnector, fluxRepository, userChannel); - liveEditCoordinator = new LiveEditCoordinator(fluxRepository); + liveEditCoordinator = new LiveEditCoordinator(messageConnector); IWorkspace workspace = ResourcesPlugin.getWorkspace(); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java index b4b624d..cc3b5e3 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java @@ -9,6 +9,6 @@ public interface IRepositoryCallback { void notifyResourceChanged(Resource resource, Project project); void sendMessage(String messageType, JSONObject content) throws Exception; - Project getProject(String projectName); + Project getWatcherProject(String projectName); Set getSynchronizedProjects(); } \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/LiveEditCoordinator.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/LiveEditCoordinator.java index 7a9af2e..8af49d0 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/LiveEditCoordinator.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/LiveEditCoordinator.java @@ -10,19 +10,18 @@ *******************************************************************************/ package org.eclipse.flux.core; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; +import org.eclipse.flux.client.IMessageHandler; +import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.core.handlers.LiveResourceChangedHandler; import org.eclipse.flux.core.handlers.LiveResourceRequestHandler; import org.eclipse.flux.core.handlers.LiveResourceStartedHandler; import org.eclipse.flux.core.handlers.LiveResourceStartedResponseHandler; -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageBus; -import org.eclipse.flux.watcher.core.FluxMessageType; -import org.eclipse.flux.watcher.core.Repository; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -32,18 +31,19 @@ */ public class LiveEditCoordinator { + private MessageConnector messagingConnector; private Collection liveEditConnectors; + private Collection messageHandlers; - private FluxMessageBus messageBus; - - public LiveEditCoordinator(Repository repository) { - this.messageBus = repository.getMessageBus(); + public LiveEditCoordinator(MessageConnector messageConnector) { + this.messagingConnector = messageConnector; this.liveEditConnectors = new CopyOnWriteArrayList<>(); + this.messageHandlers = new ArrayList(4); - messageBus.addMessageHandler(new LiveResourceStartedHandler(liveEditConnectors)); - messageBus.addMessageHandler(new LiveResourceStartedResponseHandler(liveEditConnectors)); - messageBus.addMessageHandler(new LiveResourceChangedHandler(liveEditConnectors)); - messageBus.addMessageHandler(new LiveResourceRequestHandler(liveEditConnectors)); + addMessageHandler(new LiveResourceStartedHandler(liveEditConnectors)); + addMessageHandler(new LiveResourceStartedResponseHandler(liveEditConnectors)); + addMessageHandler(new LiveResourceChangedHandler(liveEditConnectors)); + addMessageHandler(new LiveResourceRequestHandler(liveEditConnectors)); } public void addLiveEditConnector(ILiveEditConnector connector) { @@ -63,8 +63,7 @@ public void sendModelChangedMessage(String changeOriginID, String username, Stri message.put("offset", offset); message.put("removedCharCount", removedCharactersCount); message.put("addedCharacters", newText != null ? newText : ""); - - this.messageBus.sendMessages(new FluxMessage(FluxMessageType.LIVE_RESOURCE_CHANGED, message)); + this.messagingConnector.send(IMessageHandler.LIVE_RESOURCE_CHANGED, message); } catch (Exception e) { e.printStackTrace(); @@ -88,8 +87,7 @@ public void sendLiveEditStartedMessage(String changeOriginID, String username, S message.put("resource", resourcePath); message.put("hash", hash); message.put("timestamp", timestamp); - - this.messageBus.sendMessages(new FluxMessage(FluxMessageType.LIVE_RESOURCE_STARTED, message)); + this.messagingConnector.send(IMessageHandler.LIVE_RESOURCE_STARTED, message); } catch (Exception e) { e.printStackTrace(); @@ -114,8 +112,7 @@ public void sendLiveEditStartedResponse(String responseOriginID, String requestS message.put("savePointTimestamp", savePointTimestamp); message.put("savePointHash", savePointHash); message.put("liveContent", content); - - this.messageBus.sendMessages(new FluxMessage(FluxMessageType.LIVE_RESOURCE_STARTED_RESPONSE, message)); + this.messagingConnector.send(IMessageHandler.LIVE_RESOURCE_STARTED_RESPONSE, message); } catch (Exception e) { e.printStackTrace(); @@ -145,8 +142,7 @@ public void sendLiveResourcesResponse(String requestSenderID, liveEditUnits.put(entry.getKey(), new JSONArray(entry.getValue())); } message.put("liveEditUnits", liveEditUnits); - - this.messageBus.sendMessages(new FluxMessage(FluxMessageType.GET_LIVE_RESOURCE_REQUEST, message)); + this.messagingConnector.send(IMessageHandler.GET_LIVE_RESOURCE_REQUEST, message); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -168,7 +164,14 @@ public ResourceData(String path, String hash, long timestamp) { } public void dispose() { - + for (IMessageHandler messageHanlder : messageHandlers) { + messagingConnector.removeMessageHandler(messageHanlder); + } } + + private void addMessageHandler(IMessageHandler messageHandler){ + this.messagingConnector.addMessageHandler(messageHandler); + this.messageHandlers.add(messageHandler); + } } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index 0747b8e..d7d5a0e 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -125,7 +125,11 @@ public String getUsername() { public ConnectedProject getProject(IProject project) { return new ConnectedProject(repository.getProject(project.getName())); - } + } + + public ConnectedProject getProject(String projectName) { + return new ConnectedProject(repository.getProject(projectName)); + } public boolean isConnected(IProject project) { return isConnected(project.getName()); @@ -265,7 +269,7 @@ public void sendMessage(String messageType, JSONObject content) throws Exception } @Override - public Project getProject(String projectName) { + public Project getWatcherProject(String projectName) { return repository.getProject(projectName); } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java index db94ed2..074ff62 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java @@ -2,41 +2,32 @@ import java.util.Collection; +import org.eclipse.flux.client.MessageConstants; import org.eclipse.flux.core.ILiveEditConnector; -import org.eclipse.flux.core.util.JSONUtils; -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageType; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; import org.json.JSONObject; -import com.google.inject.Singleton; - -@Singleton -@FluxMessageTypes(FluxMessageType.LIVE_RESOURCE_CHANGED) -public class LiveResourceChangedHandler implements FluxMessageHandler { - +public class LiveResourceChangedHandler extends AbstractMsgHandler { private Collection liveEditConnectors; - public LiveResourceChangedHandler(Collection liveEditConnectors){ + public LiveResourceChangedHandler(Collection liveEditConnectors) { + super(null, LIVE_RESOURCE_CHANGED); this.liveEditConnectors = liveEditConnectors; } @Override - public void onMessage(FluxMessage message, Repository repository) throws Exception { - JSONObject content = message.getContent(); - String username = content.getString(FluxMessage.Fields.USERNAME); - String projectName = content.getString(FluxMessage.Fields.PROJECT); - String resourcePath = content.getString(FluxMessage.Fields.RESOURCE); - int offset = content.getInt(FluxMessage.Fields.OFFSET); - int removedCharCount = content.getInt(FluxMessage.Fields.REMOVED_CHAR_COUNT); - String addedChars = JSONUtils.getString(content, FluxMessage.Fields.ADDED_CHARACTERS, ""); + protected void onMessage(String type, JSONObject message) throws Exception { + String username = message.getString(MessageConstants.USERNAME); + String projectName = message.getString(MessageConstants.PROJECT); + String resourcePath = message.getString(MessageConstants.RESOURCE); + int offset = message.getInt(MessageConstants.OFFSET); + int removedCharCount = message.getInt(MessageConstants.REMOVED_CHAR_COUNT); + String addedChars = message.optString(MessageConstants.ADDED_CHARACTERS); String liveEditID = projectName + "/" + resourcePath; for (ILiveEditConnector connector : liveEditConnectors) { connector.liveEditingEvent(username, liveEditID, offset, removedCharCount, addedChars); - } + } } + } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceRequestHandler.java index ac3ba97..0c1f84a 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceRequestHandler.java @@ -2,39 +2,29 @@ import java.util.Collection; +import org.eclipse.flux.client.MessageConstants; import org.eclipse.flux.core.ILiveEditConnector; -import org.eclipse.flux.core.util.JSONUtils; -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageType; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; import org.json.JSONObject; -import com.google.inject.Singleton; - -@Singleton -@FluxMessageTypes({ FluxMessageType.GET_LIVE_RESOURCE_REQUEST }) -public class LiveResourceRequestHandler implements FluxMessageHandler { - +public class LiveResourceRequestHandler extends AbstractMsgHandler { private Collection liveEditConnectors; public LiveResourceRequestHandler(Collection liveEditConnectors) { + super(null, GET_LIVE_RESOURCE_REQUEST); this.liveEditConnectors = liveEditConnectors; } @Override - public void onMessage(FluxMessage message, Repository repository) throws Exception { - JSONObject content = message.getContent(); - String username = JSONUtils.getString(content, FluxMessage.Fields.USERNAME, null); - String requestSenderID = content.getString(FluxMessage.Fields.REQUEST_SENDER_ID); - String projectRegEx = JSONUtils.getString(content, FluxMessage.Fields.PROJECT_REG_EX, null); - String resourceRegEx = JSONUtils.getString(content, FluxMessage.Fields.RESOURCE_REG_EX, null); - int callbackID = content.getInt(FluxMessage.Fields.CALLBACK_ID); - + protected void onMessage(String type, JSONObject message) throws Exception { + String username = message.optString(MessageConstants.USERNAME, null); + String requestSenderID = message.getString(MessageConstants.REQUEST_SENDER_ID); + String projectRegEx = message.optString(MessageConstants.PROJECT_REG_EX, null); + String resourceRegEx = message.optString(MessageConstants.RESOURCE_REG_EX, null); + int callbackID = message.getInt(MessageConstants.CALLBACK_ID); + for (ILiveEditConnector connector : liveEditConnectors) { connector.liveEditors(requestSenderID, callbackID, username, projectRegEx, resourceRegEx); - } + } } -} +} \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java index 804402e..36486c8 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java @@ -2,42 +2,31 @@ import java.util.Collection; +import org.eclipse.flux.client.MessageConstants; import org.eclipse.flux.core.ILiveEditConnector; -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageType; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; import org.json.JSONObject; -import com.google.inject.Singleton; - -@Singleton -@FluxMessageTypes({FluxMessageType.LIVE_RESOURCE_STARTED}) -public class LiveResourceStartedHandler implements FluxMessageHandler { - +public class LiveResourceStartedHandler extends AbstractMsgHandler { private Collection liveEditConnectors; - - public LiveResourceStartedHandler(Collection liveEditConnectors){ + + public LiveResourceStartedHandler(Collection liveEditConnectors) { + super(null, LIVE_RESOURCE_STARTED); this.liveEditConnectors = liveEditConnectors; } - + @Override - public void onMessage(FluxMessage message, Repository repository) throws Exception { - JSONObject content = message.getContent(); - String requestSenderID = content.getString(FluxMessage.Fields.REQUEST_SENDER_ID); - int callbackID = content.getInt(FluxMessage.Fields.CALLBACK_ID); - String username = content.getString(FluxMessage.Fields.USERNAME); - String projectName = content.getString(FluxMessage.Fields.PROJECT); - String resourcePath = content.getString(FluxMessage.Fields.RESOURCE); - String hash = content.getString(FluxMessage.Fields.HASH); - long timestamp = content.getLong(FluxMessage.Fields.TIMESTAMP); + protected void onMessage(String type, JSONObject message) throws Exception { + String requestSenderID = message.getString(MessageConstants.REQUEST_SENDER_ID); + int callbackID = message.getInt(MessageConstants.CALLBACK_ID); + String username = message.getString(MessageConstants.USERNAME); + String projectName = message.getString(MessageConstants.PROJECT); + String resourcePath = message.getString(MessageConstants.RESOURCE); + String hash = message.getString(MessageConstants.HASH); + long timestamp = message.getLong(MessageConstants.TIMESTAMP); String liveEditID = projectName + "/" + resourcePath; for (ILiveEditConnector connector : liveEditConnectors) { connector.liveEditingStarted(requestSenderID, callbackID, username, liveEditID, hash, timestamp); - } - + } } - } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java index 30e1248..9de53ea 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java @@ -2,41 +2,31 @@ import java.util.Collection; +import org.eclipse.flux.client.MessageConstants; import org.eclipse.flux.core.ILiveEditConnector; -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageType; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; import org.json.JSONObject; -import com.google.inject.Singleton; - -@Singleton -@FluxMessageTypes({FluxMessageType.LIVE_RESOURCE_STARTED_RESPONSE}) -public class LiveResourceStartedResponseHandler implements FluxMessageHandler { - +public class LiveResourceStartedResponseHandler extends AbstractMsgHandler { private Collection liveEditConnectors; public LiveResourceStartedResponseHandler(Collection liveEditConnectors) { + super(null, LIVE_RESOURCE_STARTED_RESPONSE); this.liveEditConnectors = liveEditConnectors; } @Override - public void onMessage(FluxMessage message, Repository repository) throws Exception { - JSONObject content = message.getContent(); - String requestSenderID = content.getString(FluxMessage.Fields.REQUEST_SENDER_ID); - int callbackID = content.getInt(FluxMessage.Fields.CALLBACK_ID); - String username = content.getString(FluxMessage.Fields.USERNAME); - String projectName = content.getString(FluxMessage.Fields.PROJECT); - String resourcePath = content.getString(FluxMessage.Fields.RESOURCE); - String savePointHash = content.getString(FluxMessage.Fields.SAVE_POINT_HASH); - long savePointTimestamp = content.getLong(FluxMessage.Fields.SAVE_POINT_TIMESTAMP); - String liveContent = content.getString(FluxMessage.Fields.LIVE_CONTENT); + protected void onMessage(String type, JSONObject message) throws Exception { + String requestSenderID = message.getString(MessageConstants.REQUEST_SENDER_ID); + int callbackID = message.getInt(MessageConstants.CALLBACK_ID); + String username = message.getString(MessageConstants.USERNAME); + String projectName = message.getString(MessageConstants.PROJECT); + String resourcePath = message.getString(MessageConstants.RESOURCE); + String savePointHash = message.getString(MessageConstants.SAVE_POINT_HASH); + long savePointTimestamp = message.getLong(MessageConstants.SAVE_POINT_TIMESTAMP); + String liveContent = message.getString(MessageConstants.LIVE_CONTENT); for (ILiveEditConnector connector : liveEditConnectors) { connector.liveEditingStartedResponse(requestSenderID, callbackID, username, projectName, resourcePath, savePointHash, savePointTimestamp, liveContent); - } + } } - -} +} \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java index d59455c..5e48b3d 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java @@ -18,7 +18,7 @@ public MetadataRequestHandler(IRepositoryCallback repositoryCallback) { protected void onMessage(String type, JSONObject message) throws Exception { String projectName = message.getString("project"); String resourcePath = message.getString("resource"); - Project project = repositoryCallback.getProject(projectName); + Project project = repositoryCallback.getWatcherProject(projectName); if(project != null){ Resource resource = project.getResource(resourcePath); if(resource != null){ diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java index 9bbf3c3..faec7f2 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java @@ -16,7 +16,7 @@ public ProjectRequestHandler(IRepositoryCallback repositoryCallback) { @Override protected void onMessage(String type, JSONObject message) throws Exception { String projectName = message.getString(MessageConstants.PROJECT_NAME); - Project project = repositoryCallback.getProject(projectName); + Project project = repositoryCallback.getWatcherProject(projectName); if(project == null) return; JSONArray files = new JSONArray(); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java index ad84fdb..31728d4 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java @@ -19,7 +19,7 @@ public ProjectResponseHandler(IRepositoryCallback repositoryCallback, int callba protected void onMessage(String type, JSONObject message) throws Exception { JSONArray files = message.getJSONArray(MessageConstants.FILES); JSONArray deleted = message.getJSONArray(MessageConstants.DELETED); - Project project = repositoryCallback.getProject(message.getString(MessageConstants.PROJECT_NAME)); + Project project = repositoryCallback.getWatcherProject(message.getString(MessageConstants.PROJECT_NAME)); if(project == null) return; for(int i = 0; i < files.length(); i++){ diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java index d50c7f2..fb38ec6 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java @@ -22,7 +22,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { String resourcePath = message.getString(MessageConstants.RESOURCE); long resourceTimestamp = message.getLong(MessageConstants.TIMESTAMP); String resourceHash = message.getString(MessageConstants.HASH); - Project project = repositoryCallback.getProject(projectName); + Project project = repositoryCallback.getWatcherProject(projectName); if(project == null) return; Resource localResource = project.getResource(resourcePath); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java index 9ccebf1..e8921cf 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java @@ -21,7 +21,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { long resourceTimestamp = message.getLong(MessageConstants.TIMESTAMP); String resourceHash = message.getString(MessageConstants.HASH); String username = message.getString(MessageConstants.USERNAME); - Project project = repositoryCallback.getProject(projectName); + Project project = repositoryCallback.getWatcherProject(projectName); if(project == null || project.hasResource(resourcePath)) return; JSONObject content = new JSONObject(); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java index 5846e07..5da7f84 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java @@ -17,7 +17,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { String projectName = message.getString(MessageConstants.PROJECT_NAME); String resourcePath = message.getString(MessageConstants.RESOURCE); long resourceTimestamp = message.getLong(MessageConstants.TIMESTAMP); - Project project = repositoryCallback.getProject(projectName); + Project project = repositoryCallback.getWatcherProject(projectName); if(project == null) return; Resource localResource = project.getResource(resourcePath); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java index 8d10938..fbd16ff 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java @@ -14,7 +14,7 @@ public ResourceRequestHandler(IRepositoryCallback repositoryCallback) { @Override protected void onMessage(String type, JSONObject message) throws Exception { - Project project = repositoryCallback.getProject(message.getString(MessageConstants.PROJECT_NAME)); + Project project = repositoryCallback.getWatcherProject(message.getString(MessageConstants.PROJECT_NAME)); if (project == null) return; Resource resource = project.getResource(message.getString(MessageConstants.RESOURCE)); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java index 88b1186..05e0e60 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java @@ -26,7 +26,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { String resourceContent = message.getString(MessageConstants.CONTENT); String username = message.getString(MessageConstants.USERNAME); - Project project = repositoryCallback.getProject(projectName); + Project project = repositoryCallback.getWatcherProject(projectName); if(project == null) return; boolean isResourceStore = false; From abd5ed8b6048bfa441f0b078d81070199cd723a6 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Mon, 22 Aug 2016 21:01:32 +0300 Subject: [PATCH 30/34] Removed connection for the Flux File Watcher Signed-off-by: Fjodor Vershinin --- org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java index 394fd0c..f728b7f 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java @@ -37,7 +37,6 @@ import org.eclipse.flux.client.config.SocketIOFluxConfig; import org.eclipse.flux.core.internal.CloudSyncMetadataListener; import org.eclipse.flux.core.util.ExceptionUtil; -import org.eclipse.flux.watcher.core.Credentials; import org.eclipse.flux.watcher.core.Repository; import org.eclipse.flux.watcher.core.RepositoryModule; import org.eclipse.flux.watcher.fs.JDKProjectModule; @@ -119,7 +118,6 @@ public void start(BundleContext context) throws Exception { Injector injector = Guice.createInjector(new RepositoryModule(), new JDKProjectModule()); fluxRepository = injector.getInstance(Repository.class); - fluxRepository.addRemote(new URL(host), new Credentials(login, token)); //Connecting to channel done asynchronously. To avoid blocking plugin state initialization. FluxClient.DEFAULT_INSTANCE.getExecutor().execute(new Runnable() { @Override From 9eb3fa9a704d8b158f7e535d2edd40490be35bf5 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Mon, 22 Aug 2016 23:55:56 +0300 Subject: [PATCH 31/34] Flux File Watcher: Removed functional for sending/receiving messages and functional for connection Signed-off-by: Fjodor Vershinin --- org.eclipse.flux.watcher/META-INF/MANIFEST.MF | 1 - .../flux/watcher/core/Credentials.java | 75 ------ .../flux/watcher/core/FluxConnection.java | 178 -------------- .../flux/watcher/core/FluxMessage.java | 121 ---------- .../flux/watcher/core/FluxMessageBus.java | 226 ------------------ .../flux/watcher/core/FluxMessageHandler.java | 31 --- .../flux/watcher/core/FluxMessageType.java | 85 ------- .../flux/watcher/core/FluxMessageTypes.java | 36 --- .../eclipse/flux/watcher/core/Repository.java | 63 +---- .../flux/watcher/core/RepositoryModule.java | 12 - .../flux/watcher/core/internal/.gitignore | 54 ----- .../internal/GetProjectRequestHandler.java | 72 ------ .../internal/GetProjectResponseHandler.java | 101 -------- .../internal/GetResourceRequestHandler.java | 78 ------ .../internal/GetResourceResponseHandler.java | 84 ------- .../ProjectResourceCreatedListener.java | 69 ------ .../ProjectResourceDeletedListener.java | 64 ----- .../ProjectResourceModifiedListener.java | 71 ------ .../core/internal/ResourceChangedHandler.java | 66 ----- .../core/internal/ResourceCreatedHandler.java | 68 ------ .../core/internal/ResourceDeletedHandler.java | 51 ---- .../watcher/core/FluxMessageTypeTest.java | 41 ---- .../flux/watcher/core/RepositoryTest.java | 58 ----- 23 files changed, 1 insertion(+), 1704 deletions(-) delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Credentials.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxConnection.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageBus.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageHandler.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageType.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageTypes.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/.gitignore delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java delete mode 100644 org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java delete mode 100644 org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/FluxMessageTypeTest.java diff --git a/org.eclipse.flux.watcher/META-INF/MANIFEST.MF b/org.eclipse.flux.watcher/META-INF/MANIFEST.MF index 9e90801..ad48fa7 100644 --- a/org.eclipse.flux.watcher/META-INF/MANIFEST.MF +++ b/org.eclipse.flux.watcher/META-INF/MANIFEST.MF @@ -14,7 +14,6 @@ Import-Package: com.google.common.base, com.google.inject.multibindings;version="1.3.0", javax.inject;version="1.0.0" Export-Package: org.eclipse.flux.watcher.core, - org.eclipse.flux.watcher.core.internal, org.eclipse.flux.watcher.core.spi, org.eclipse.flux.watcher.core.utils, org.eclipse.flux.watcher.fs diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Credentials.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Credentials.java deleted file mode 100644 index c0760d7..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Credentials.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Credentials used to connect to a Flux server. - * - * @author Kevin Pollet - */ -public class Credentials { - public static final Credentials DEFAULT_USER_CREDENTIALS; - private static final String DEFAULT_USER_USERNAME = "defaultuser"; - - static { - DEFAULT_USER_CREDENTIALS = new Credentials(DEFAULT_USER_USERNAME); - } - - private final String username; - private final String token; - - /** - * Constructs an instance of {@link com.codenvy.flux.watcher.core.Credentials}. - * - * @param username - * the username. - * @throws java.lang.NullPointerException - * if {@code username} parameter is {@code null}. - */ - public Credentials(String username) { - this(username, null); - } - - /** - * Constructs an instance of {@link com.codenvy.flux.watcher.core.Credentials}. - * - * @param username - * the username. - * @param token - * the user token. - * @throws java.lang.NullPointerException - * if {@code username} parameter is {@code null}. - */ - public Credentials(String username, String token) { - this.username = checkNotNull(username); - this.token = token; - } - - /** - * Returns the username. - * - * @return the username never {@code null}. - */ - public String username() { - return username; - } - - /** - * Returns the user token. - * - * @return the user token or {@code null} if none. - */ - public String token() { - return token; - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxConnection.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxConnection.java deleted file mode 100644 index da4c617..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxConnection.java +++ /dev/null @@ -1,178 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core; - -import io.socket.IOAcknowledge; -import io.socket.IOCallback; -import io.socket.SocketIO; -import io.socket.SocketIOException; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.net.URL; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CALLBACK_ID; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CHANNEL; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CONNECTED_TO_CHANNEL; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.USERNAME; -import static org.eclipse.flux.watcher.core.FluxMessageType.CONNECT_TO_CHANNEL; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_PROJECT_REQUEST; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_REQUEST; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Represents a connection to a Flux remote. - * - * @author Kevin Pollet - */ -public class FluxConnection { - private static final String FLUX_USER_NAME_HEADER_KEY = "X-flux-user-name"; - private static final String FLUX_USER_TOKEN_HEADER_KEY = "X-flux-user-token"; - - private final SocketIO socket; - private final FluxMessageBus messageBus; - private final Credentials credentials; - - /** - * Constructs an instance of {@code FluxConnection}. - * - * @param serverURL - * the server {@link java.net.URL} to connect to. - * @param credentials - * the {@link Credentials} used to connect. - * @param messageBus - * the {@link com.codenvy.flux.watcher.core.FluxMessageBus} instance. - * @throws java.lang.NullPointerException - * if {@code serverURL}, {@code credentials} or {@code messageBus} parameter is {@code null}. - */ - FluxConnection(URL serverURL, Credentials credentials, FluxMessageBus messageBus) { - this.messageBus = checkNotNull(messageBus); - this.credentials = checkNotNull(credentials); - - this.socket = new SocketIO(checkNotNull(serverURL)); - if (credentials.token() != null) { - this.socket.addHeader(FLUX_USER_NAME_HEADER_KEY, credentials.username()); - this.socket.addHeader(FLUX_USER_TOKEN_HEADER_KEY, credentials.token()); - } - } - - /** - * Open the connection. - * - * @return the opened {@link com.codenvy.flux.watcher.core.FluxConnection} instance. - */ - FluxConnection open() { - if (!socket.isConnected()) { - socket.connect(new IOCallback() { - @Override - public void onDisconnect() { - - } - - @Override - public void onConnect() { - try { - - final JSONObject content = new JSONObject().put(CHANNEL, credentials.username()); - socket.emit(CONNECT_TO_CHANNEL.value(), new IOAcknowledge() { - @Override - public void ack(Object... objects) { - if (objects.length == 1 && objects[0] instanceof JSONObject) { - final JSONObject ack = (JSONObject)objects[0]; - try { - - if (ack.has(CONNECTED_TO_CHANNEL) && ack.getBoolean(CONNECTED_TO_CHANNEL)) { - return; - } - - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - socket.disconnect(); - } - }, content); - - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public void onMessage(String s, IOAcknowledge ioAcknowledge) { - - } - - @Override - public void onMessage(JSONObject jsonObject, IOAcknowledge ioAcknowledge) { - - } - - //TODO in flux implementation the username is checked, what to do? - @Override - public void on(String name, IOAcknowledge ioAcknowledge, Object... objects) { - final FluxMessageType messageType = FluxMessageType.fromType(name); - if (messageType != null && objects.length > 0 && objects[0] instanceof JSONObject) { - final FluxMessage message = new FluxMessage(FluxConnection.this, messageType, (JSONObject)objects[0]); - messageBus.messageReceived(message); - } - } - - @Override - public void onError(SocketIOException e) { - throw new RuntimeException(e); - } - }); - } - return this; - } - - /** - * Close the connection. - */ - void close() { - if (socket.isConnected()) { - socket.disconnect(); - } - } - - /** - * Sends a {@link FluxMessage} on this connection - * - * @param message - * the {@link FluxMessage} instance to send. - * @throws java.lang.NullPointerException - * if {@code message} parameter is {@code null}. - */ - public void sendMessage(FluxMessage message) { - checkNotNull(message); - - final JSONObject content = message.getContent(); - - try { - if (!content.has(USERNAME)) { - content.put(USERNAME, credentials.username()); - } - - if (!content.has(CALLBACK_ID)) { - if (message.getType() == GET_RESOURCE_REQUEST || message.getType() == GET_PROJECT_REQUEST) { - content.put(CALLBACK_ID, messageBus.id()); - } - } - - } catch (JSONException e) { - throw new RuntimeException(e); - } - - socket.emit(message.getType().value(), message.getContent()); - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java deleted file mode 100644 index bfe2fb1..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessage.java +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core; - -import org.json.JSONObject; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Class representing a Flux message. - * - * @author Kevin Pollet - */ -public class FluxMessage { - /** - * Fields used in {@link org.json.JSONObject} of Flux messages. - * - * @author Kevin Pollet - */ - public static interface Fields { - public static final String CALLBACK_ID = "callback_id"; - public static final String CHANNEL = "channel"; - public static final String CONNECTED_TO_CHANNEL = "connectedToChannel"; - public static final String CONTENT = "content"; - public static final String DELETED = "deleted"; - public static final String FILES = "files"; - public static final String HASH = "hash"; - public static final String INCLUDE_DELETED = "includeDeleted"; - public static final String PATH = "path"; - public static final String PROJECT = "project"; - public static final String REQUEST_SENDER_ID = "requestSenderID"; - public static final String RESOURCE = "resource"; - public static final String TIMESTAMP = "timestamp"; - public static final String TYPE = "type"; - public static final String USERNAME = "username"; - public static final String SAVE_POINT_HASH = "savePointHash"; - public static final String SAVE_POINT_TIMESTAMP = "savePointTimestamp"; - public static final String LIVE_CONTENT = "liveContent"; - public static final String OFFSET = "offset"; - public static final String REMOVED_CHAR_COUNT = "removedCharCount"; - public static final String ADDED_CHARACTERS = "addedCharacters"; - public static final String PROJECT_REG_EX = "projectRegEx"; - public static final String RESOURCE_REG_EX = "resourceRegEx"; - - - } - - private final FluxConnection source; - private final FluxMessageType type; - private final JSONObject content; - - /** - * Constructs an instance of {@link FluxMessage}. - * - * @param type - * the {@link FluxMessageType}. - * @param content - * the message {@link org.json.JSONObject} content. - * @throws java.lang.NullPointerException - * if {@code type} or {@code content} parameter is {@code null}. - */ - public FluxMessage(FluxMessageType type, JSONObject content) { - this(null, type, content); - } - - /** - * Constructs an instance of {@link FluxMessage}. - * - * @param source - * the {@code FluxConnection} where the {@link FluxMessage} comes - * from. - * @param type - * the {@link FluxMessageType}. - * @param content - * the message {@link org.json.JSONObject} content. - * @throws java.lang.NullPointerException - * if {@code type} or {@code content} parameter is {@code null}. - */ - public FluxMessage(FluxConnection source, FluxMessageType type, JSONObject content) { - this.source = source; - this.type = checkNotNull(type); - this.content = checkNotNull(content); - } - - /** - * Returns the {@code FluxConnection} where the {@link FluxMessage} comes - * from. - * - * @return the {@code FluxConnection} where the {@link FluxMessage} comes - * from or {@code null} if none. - */ - public FluxConnection getSource() { - return source; - } - - /** - * Returns the {@link FluxMessageType}. - * - * @return the {@link FluxMessageType}, never {@code null}. - */ - public FluxMessageType getType() { - return type; - } - - /** - * Returns the {@link FluxMessage} content. - * - * @return the {@link FluxMessage} content, never {@code null}. - */ - public JSONObject getContent() { - return content; - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageBus.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageBus.java deleted file mode 100644 index 22ab8bf..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageBus.java +++ /dev/null @@ -1,226 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CALLBACK_ID; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_PROJECT_RESPONSE; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_RESPONSE; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Predicates.notNull; -import static java.util.Collections.emptySet; - -import java.net.URL; -import java.util.Arrays; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArraySet; - -import javax.inject.Inject; -import javax.inject.Provider; -import javax.inject.Singleton; - -import org.json.JSONObject; - -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableSet; - -/** - * Message bus connected to Flux instance. - * - * @author Kevin Pollet - */ -@Singleton -public class FluxMessageBus { - private final int id; - private final ConcurrentMap connections; - private final Provider repository; - private final Set messageHandlers; - - /** - * Constructs an instance of {@link com.codenvy.flux.watcher.core.FluxMessageBus}. - * - * @param messageHandlers - * the {@link FluxMessageHandler} to register. - * @param repository - * the {@link Repository} provider instance. - * @throws java.lang.NullPointerException - * if {@code messageHandlers} is {@code null}. - */ - @Inject - FluxMessageBus(Set messageHandlers, Provider repository) { - id = Long.valueOf(UUID.randomUUID().getMostSignificantBits()).intValue(); - this.repository = repository; - this.messageHandlers = new CopyOnWriteArraySet<>(checkNotNull(messageHandlers)); - connections = new ConcurrentHashMap<>(); - } - - /** - * Returns the {@link com.codenvy.flux.watcher.core.FluxMessageBus} unique id. - * - * @return the {@link com.codenvy.flux.watcher.core.FluxMessageBus} unique id. - */ - public int id() { - return id; - } - - /** - * Open a connection to the given server {@link java.net.URL}. - * - * @param serverURL - * the server {@link java.net.URL} to connect to. - * @param credentials - * the {@link Credentials} to use for the connection. - * @return the opened {@link com.codenvy.flux.watcher.core.FluxConnection} or the existing {@link - * com.codenvy.flux.watcher.core.FluxConnection} if already opened. - * @throws java.lang.NullPointerException - * if {@code serverURL} or {@code credentials} parameter is {@code null}. - */ - public FluxConnection connect(URL serverURL, Credentials credentials) { - checkNotNull(serverURL); - checkNotNull(credentials); - - FluxConnection connection = connections.get(serverURL); - if (connection == null) { - FluxConnection newConnection = new FluxConnection(serverURL, credentials, this); - connection = connections.putIfAbsent(serverURL, newConnection); - if (connection == null) { - connection = newConnection.open(); - } - } - - return connection; - } - - /** - * Close the connection to the given server {@link java.net.URL}. - * - * @param serverURL - * the server {@link java.net.URL} to disconnect from. - * @throws java.lang.NullPointerException - * if {@code serverURL} parameter is {@code null}. - */ - public void disconnect(URL serverURL) { - final FluxConnection connection = connections.remove(checkNotNull(serverURL)); - if (connection != null) { - connection.close(); - } - } - - /** - * Adds a {@link FluxMessageHandler}. - * - * @param handler - * the {@link FluxMessageHandler} to add. - * @return {@code true} if the {@code handler} is not already added, {@code false} otherwise. - * @throws java.lang.NullPointerException - * if {@code handler} parameter is {@code null}. - */ - public boolean addMessageHandler(FluxMessageHandler handler) { - return messageHandlers.add(checkNotNull(handler)); - } - - /** - * Removes a {@link FluxMessageHandler}. - * - * @param handler - * the {@link FluxMessageHandler} to remove. - * @return {@code true} if the {@code handler} was already added, {@code false} otherwise. - * @throws java.lang.NullPointerException - * if {@code handler} parameter is {@code null}. - */ - public boolean removeMessageHandler(FluxMessageHandler handler) { - return messageHandlers.remove(checkNotNull(handler)); - } - - /** - * Broadcast messages to all opened {@link com.codenvy.flux.watcher.core.FluxConnection}. - * - * @param messages - * the {@link FluxMessage} to broadcast. - * @throws java.lang.NullPointerException - * if {@code messages} parameter is {@code null}. - */ - public void sendMessages(FluxMessage... messages) { - checkNotNull(messages); - - for (FluxMessage oneMessage : messages) { - checkNotNull(oneMessage); - - for (FluxConnection oneConnection : connections.values()) { - oneConnection.sendMessage(oneMessage); - } - } - } - - /** - * Fires the given {@link FluxMessage} to all {@link FluxMessageHandler} - * registered. - * - * @param message - * the message. - * @throws java.lang.NullPointerException - * if {@code message} parameter is {@code null}. - */ - public void messageReceived(FluxMessage message) { - checkNotNull(message); - - if (message.getType() == GET_RESOURCE_RESPONSE || message.getType() == GET_PROJECT_RESPONSE) { - final JSONObject content = message.getContent(); - if (content.optInt(CALLBACK_ID) != id) { - return; - } - } - - final Set messageHandlers = getMessageHandlersFor(message.getType().value()); - for (FluxMessageHandler oneMessageHandler : messageHandlers) { - try { - - oneMessageHandler.onMessage(message, repository.get()); - - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - private Set getMessageHandlersFor(final String messageType) { - return ImmutableSet.copyOf(FluentIterable.from(messageHandlers) - .filter(notNull()) - .filter(new Predicate() { - @Override - public boolean apply(FluxMessageHandler messageHandler) { - final Set supportedTypes = getMessageTypesFor(messageHandler); - return supportedTypes.contains(messageType); - } - })); - } - - private Set getMessageTypesFor(FluxMessageHandler messageHandler) { - final FluxMessageTypes types = messageHandler.getClass().getAnnotation(FluxMessageTypes.class); - if (types == null) { - return emptySet(); - } - - return ImmutableSet.copyOf(FluentIterable.from(Arrays.asList(types.value())) - .filter(Predicates.notNull()) - .transform(new Function() { - @Override - public String apply(FluxMessageType messageType) { - return messageType.value(); - } - })); - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageHandler.java deleted file mode 100644 index e7414b8..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core; - -/** - * Interface implemented to be advise when a {@link com.codenvy.flux.watcher.core.FluxMessage} is received by a {@link - * com.codenvy.flux.watcher.core.FluxConnection}. - * - * @author Kevin Pollet - */ -public interface FluxMessageHandler { - /** - * Method called when a {@link com.codenvy.flux.watcher.core.FluxMessage} is received. - * - * @param message - * the {@link com.codenvy.flux.watcher.core.FluxMessage} instance, never {@code null}. - * @param repository - * the {@link com.codenvy.flux.watcher.core.Repository} instance, never {@code null}. - * @throws java.lang.Exception - * if something goes wrong. - */ - void onMessage(FluxMessage message, Repository repository) throws Exception; -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageType.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageType.java deleted file mode 100644 index 6173d1e..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageType.java +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * The types of {@link com.codenvy.flux.watcher.core.FluxMessage}. - * - * @author Kevin Pollet - */ -public enum FluxMessageType { - CONNECT_TO_CHANNEL("connectToChannel"), - GET_PROJECT_REQUEST("getProjectRequest"), - GET_PROJECT_RESPONSE("getProjectResponse"), - GET_RESOURCE_REQUEST("getResourceRequest"), - GET_RESOURCE_RESPONSE("getResourceResponse"), - GET_METADATA_REQUEST("getMetadataRequest"), - GET_METADATA_RESPONSE("getMetadataResponse"), - GET_LIVE_RESOURCE_REQUEST("getLiveResourcesRequest"), - PROJECT_CONNECTED("projectConnected"), - PROJECT_DISCONNECTED("projectDisconnected"), - RESOURCE_CHANGED("resourceChanged"), - RESOURCE_CREATED("resourceCreated"), - RESOURCE_DELETED("resourceDeleted"), - RESOURCE_STORED("resourceStored"), - METADATA_CHANGED("metadataChanged"), - LIVE_RESOURCE_STARTED("liveResourceStarted"), - LIVE_RESOURCE_STARTED_RESPONSE("liveResourceStartedResponse"), - LIVE_RESOURCE_CHANGED("liveResourceChanged"); - - private final String value; - - /** - * Constructs an instance of {@link com.codenvy.flux.watcher.core.FluxMessageType}. - * - * @param value - * the {@link com.codenvy.flux.watcher.core.FluxMessageType} value. - * @throws java.lang.NullPointerException - * if {@code value} parameter is {@code null}. - */ - FluxMessageType(String value) { - this.value = checkNotNull(value); - } - - /** - * Returns the {@link com.codenvy.flux.watcher.core.FluxMessageType} corresponding to the given type. - * - * @param type - * the {@link com.codenvy.flux.watcher.core.FluxMessageType} type. - * @return the {@link com.codenvy.flux.watcher.core.FluxMessageType} corresponding to the given type or {@code null} if none. - * @throws java.lang.NullPointerException - * if {@code type} parameter is {@code null}. - * @throws java.lang.IllegalArgumentException - * if no {@link com.codenvy.flux.watcher.core.FluxMessageType} exists for the given type. - */ - public static FluxMessageType fromType(String type) { - checkNotNull(type); - - final FluxMessageType[] messageTypes = FluxMessageType.values(); - for (FluxMessageType oneMessageType : messageTypes) { - if (oneMessageType.value.equals(type)) { - return oneMessageType; - } - } - throw new IllegalArgumentException("No enum found for type '" + type + "'"); - } - - /** - * Returns the {@link com.codenvy.flux.watcher.core.FluxMessageType} value. - * - * @return the {@link com.codenvy.flux.watcher.core.FluxMessageType} value, never {@code null}. - */ - public String value() { - return value; - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageTypes.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageTypes.java deleted file mode 100644 index bf79b86..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/FluxMessageTypes.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * Annotation used to indicate which {@link com.codenvy.flux.watcher.core.FluxMessageType} the {@link - * com.codenvy.flux.watcher.core.FluxMessageHandler} can handle. - * - * @author Kevin Pollet - */ -@Target(TYPE) -@Retention(RUNTIME) -public @interface FluxMessageTypes { - /** - * Returns the {@link com.codenvy.flux.watcher.core.FluxMessageType} the {@link - * com.codenvy.flux.watcher.core.FluxMessageHandler} can handle. - * - * @return the {@link com.codenvy.flux.watcher.core.FluxMessageType} the {@link - * com.codenvy.flux.watcher.core.FluxMessageHandler} can handle. - */ - FluxMessageType[] value(); -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java index 7d4ee5e..ab311cc 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/Repository.java @@ -15,19 +15,13 @@ import com.google.common.base.Predicate; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableSet; -import org.json.JSONException; -import org.json.JSONObject; import javax.inject.Inject; import javax.inject.Singleton; -import java.net.URL; import java.util.Objects; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.INCLUDE_DELETED; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; -import static org.eclipse.flux.watcher.core.FluxMessageType.*; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Predicates.notNull; @@ -39,7 +33,6 @@ @Singleton public class Repository { private final Set projects; - private final FluxMessageBus messageBus; private final RepositoryEventBus repositoryEventBus; private final ProjectFactory projectFactory; @@ -56,40 +49,12 @@ public class Repository { * if {@code messageBus}, {@code projectFactory} or {@code repositoryEventBus} parameter is {@code null}. */ @Inject - Repository(FluxMessageBus messageBus, ProjectFactory projectFactory, RepositoryEventBus repositoryEventBus) { + Repository(ProjectFactory projectFactory, RepositoryEventBus repositoryEventBus) { this.repositoryEventBus = checkNotNull(repositoryEventBus); - this.messageBus = checkNotNull(messageBus); this.projectFactory = checkNotNull(projectFactory); this.projects = new CopyOnWriteArraySet<>(); } - /** - * Connects this {@link Repository} to a Flux remote. - * - * @param remoteURL - * the remote {@link java.net.URL}. - * @param credentials - * the {@link com.codenvy.flux.watcher.core.Credentials} used to connect. - * @return the opened {@link com.codenvy.flux.watcher.core.FluxConnection}. - * @throws java.lang.NullPointerException - * if {@code remoteURL} or {@code credentials} parameter is {@code null}. - */ - public FluxConnection addRemote(URL remoteURL, Credentials credentials) { - return messageBus.connect(checkNotNull(remoteURL), checkNotNull(credentials)); - } - - /** - * Disconnects this {@link Repository} from a Flux remote. - * - * @param remoteURL - * the server {@link java.net.URL}. - * @throws java.lang.NullPointerException - * if {@code remoteURL} parameter is {@code null}. - */ - public void removeRemote(URL remoteURL) { - messageBus.disconnect(checkNotNull(remoteURL)); - } - /** * Add a project to the repository. * @@ -112,18 +77,6 @@ public Project addProject(String projectId, String projectPath) { project = projectFactory.newProject(projectId, projectPath); project.setSynchronized(true); projects.add(project); - - /*try { - - JSONObject content = new JSONObject().put(PROJECT, projectId); - messageBus.sendMessages(new FluxMessage(PROJECT_CONNECTED, content)); - - content = new JSONObject().put(PROJECT, projectId).put(INCLUDE_DELETED, true); - messageBus.sendMessages(new FluxMessage(GET_PROJECT_REQUEST, content)); - - } catch (JSONException e) { - throw new RuntimeException(e); - }*/ } return project; } @@ -140,15 +93,6 @@ public Project removeProject(String projectId) { if (project != null) { projects.remove(project); project.setSynchronized(false); - - /*try { - - final JSONObject content = new JSONObject().put(PROJECT, projectId); - messageBus.sendMessages(new FluxMessage(PROJECT_DISCONNECTED, content)); - - } catch (JSONException e) { - throw new RuntimeException(e); - }*/ } return project; } @@ -193,9 +137,4 @@ public boolean apply(Project project) { public RepositoryEventBus repositoryEventBus() { return repositoryEventBus; } - - public FluxMessageBus getMessageBus(){ - return messageBus; - } - } diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryModule.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryModule.java index 8748944..0991aae 100644 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryModule.java +++ b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/RepositoryModule.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.flux.watcher.core; -import org.eclipse.flux.watcher.core.internal.*; import com.google.inject.AbstractModule; import com.google.inject.multibindings.Multibinder; @@ -23,19 +22,8 @@ public class RepositoryModule extends AbstractModule { @Override protected void configure() { bind(Repository.class); - bind(FluxMessageBus.class); bind(RepositoryEventBus.class); - // message handler bindings - final Multibinder messageHandlers = Multibinder.newSetBinder(binder(), FluxMessageHandler.class); - //messageHandlers.addBinding().to(GetResourceRequestHandler.class); - //messageHandlers.addBinding().to(GetResourceResponseHandler.class); - //messageHandlers.addBinding().to(GetProjectRequestHandler.class); - //messageHandlers.addBinding().to(GetProjectResponseHandler.class); - //messageHandlers.addBinding().to(ResourceCreatedHandler.class); - //messageHandlers.addBinding().to(ResourceDeletedHandler.class); - //messageHandlers.addBinding().to(ResourceChangedHandler.class); - // repository listener bindings final Multibinder repositoryListeners = Multibinder.newSetBinder(binder(), RepositoryListener.class); //repositoryListeners.addBinding().to(ProjectResourceCreatedListener.class); diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/.gitignore b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/.gitignore deleted file mode 100644 index c1b5ee1..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/.gitignore +++ /dev/null @@ -1,54 +0,0 @@ -# Created by .ignore support plugin (hsz.mobi) -### Eclipse template - -.metadata -bin/ -tmp/ -*.tmp -*.bak -*.swp -*~.nib -local.properties -.settings/ -.loadpath -.recommenders - -# Eclipse Core -.project - -# External tool builders -.externalToolBuilders/ - -# Locally stored "Eclipse launch configurations" -*.launch - -# PyDev specific (Python IDE for Eclipse) -*.pydevproject - -# CDT-specific (C/C++ Development Tooling) -.cproject - -# JDT-specific (Eclipse Java Development Tools) -.classpath - -# Java annotation processor (APT) -.factorypath - -# PDT-specific (PHP Development Tools) -.buildpath - -# sbteclipse plugin -.target - -# Tern plugin -.tern-project - -# TeXlipse plugin -.texlipse - -# STS (Spring Tool Suite) -.springBeans - -# Code Recommenders -.recommenders/ - diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java deleted file mode 100644 index 029db71..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectRequestHandler.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core.internal; - -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; -import org.eclipse.flux.watcher.core.Resource; -import org.eclipse.flux.watcher.core.spi.Project; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import javax.inject.Singleton; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CALLBACK_ID; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.FILES; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PATH; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.REQUEST_SENDER_ID; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_PROJECT_REQUEST; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_PROJECT_RESPONSE; - -/** - * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#GET_PROJECT_REQUEST}. - * - * @author Kevin Pollet - */ -@FluxMessageTypes(GET_PROJECT_REQUEST) -public final class GetProjectRequestHandler implements FluxMessageHandler { - @Override - public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.getContent(); - final int callbackId = request.getInt(CALLBACK_ID); - final String requestSenderId = request.getString(REQUEST_SENDER_ID); - final String projectName = request.getString(PROJECT); - - final Project project = repository.getProject(projectName); - if (project != null) { - final JSONArray files = new JSONArray(); - for (Resource oneResource : project.getResources()) { - files.put(new JSONObject() - .put(PATH, oneResource.path()) - .put(TIMESTAMP, oneResource.timestamp()) - .put(HASH, oneResource.hash()) - .put(TYPE, oneResource.type().name().toLowerCase())); - } - - final JSONObject content = new JSONObject() - .put(CALLBACK_ID, callbackId) - .put(REQUEST_SENDER_ID, requestSenderId) - .put(PROJECT, projectName) - .put(FILES, files); - - message.getSource() - .sendMessage(new FluxMessage(GET_PROJECT_RESPONSE, content)); - } - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java deleted file mode 100644 index a0fdef0..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetProjectResponseHandler.java +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core.internal; - -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; -import org.eclipse.flux.watcher.core.Resource; -import org.eclipse.flux.watcher.core.spi.Project; - -import org.json.JSONArray; -import org.json.JSONObject; - -import javax.inject.Singleton; -import java.util.Objects; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.DELETED; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.FILES; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PATH; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_PROJECT_RESPONSE; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_REQUEST; -import static org.eclipse.flux.watcher.core.Resource.ResourceType; -import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; -import static org.eclipse.flux.watcher.core.Resource.ResourceType.FOLDER; -import static org.eclipse.flux.watcher.core.Resource.ResourceType.UNKNOWN; - -/** - * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#GET_PROJECT_RESPONSE}. - * - * @author Kevin Pollet - */ -@FluxMessageTypes(GET_PROJECT_RESPONSE) -public final class GetProjectResponseHandler implements FluxMessageHandler { - @Override - public void onMessage(FluxMessage message, Repository repository) throws Exception { - final JSONObject request = message.getContent(); - final String projectName = request.getString(PROJECT); - final JSONArray files = request.getJSONArray(FILES); - final JSONArray deleted = request.optJSONArray(DELETED); - - final Project project = repository.getProject(projectName); - if (project != null) { - // new files - for (int i = 0; i < files.length(); i++) { - final JSONObject resource = files.getJSONObject(i); - final String resourcePath = resource.getString(PATH); - final long resourceTimestamp = resource.getLong(TIMESTAMP); - final ResourceType resourceType = ResourceType.valueOf(resource.optString(TYPE, UNKNOWN.name()).toUpperCase()); - final String resourceHash = resource.optString(HASH, "0"); - - final Resource localResource = project.getResource(resourcePath); - if (resourceType == FILE) { - if (localResource == null - || localResource.timestamp() < resourceTimestamp - && !Objects.equals(resourceHash, localResource.hash())) { - - final JSONObject content = new JSONObject() - .put(PROJECT, projectName) - .put(RESOURCE, resourcePath) - .put(TIMESTAMP, resourceTimestamp) - .put(HASH, resourceHash); - - message.getSource() - .sendMessage(new FluxMessage(GET_RESOURCE_REQUEST, content)); - } - - } else if (resourceType == FOLDER && localResource == null) { - project.createResource(Resource.newFolder(resourcePath, resourceTimestamp)); - } - } - - // deleted files - if (deleted != null) { - for (int i = 0; i < deleted.length(); i++) { - final JSONObject resource = deleted.getJSONObject(i); - final String resourcePath = resource.getString(PATH); - final long resourceTimestamp = resource.getLong(TIMESTAMP); - - final Resource localResource = project.getResource(resourcePath); - if (localResource != null && localResource.timestamp() < resourceTimestamp) { - project.deleteResource(Resource.newUnknown(resourcePath, resourceTimestamp)); - } - } - } - } - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java deleted file mode 100644 index c09adcd..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceRequestHandler.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core.internal; - -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; -import org.eclipse.flux.watcher.core.Resource; -import org.eclipse.flux.watcher.core.spi.Project; - -import org.json.JSONException; -import org.json.JSONObject; - -import javax.inject.Singleton; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CALLBACK_ID; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CONTENT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.REQUEST_SENDER_ID; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_REQUEST; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_RESPONSE; -import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; - -/** - * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#GET_RESOURCE_REQUEST}. - * - * @author Kevin Pollet - */ -@FluxMessageTypes(GET_RESOURCE_REQUEST) -public final class GetResourceRequestHandler implements FluxMessageHandler { - @Override - public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.getContent(); - final int callbackId = request.getInt(CALLBACK_ID); - final String requestSenderId = request.getString(REQUEST_SENDER_ID); - final String projectName = request.getString(PROJECT); - final String resourcePath = request.getString(RESOURCE); - - final Project project = repository.getProject(projectName); - if (project != null) { - final Resource resource = project.getResource(resourcePath); - - // compare the time stamp and allow a nearly difference for now TODO find out why CodenvyVFS -> Eclipse has different timestamp - long requestTimeStamp = request.has(TIMESTAMP) ? request.getLong(TIMESTAMP) : 0; - long resourceTimeStamp = resource.timestamp(); - if (!request.has(TIMESTAMP) || Math.abs(requestTimeStamp - resourceTimeStamp) < 10000) { - final JSONObject content = new JSONObject() - .put(CALLBACK_ID, callbackId) - .put(REQUEST_SENDER_ID, requestSenderId) - .put(PROJECT, projectName) - .put(RESOURCE, resourcePath) - .put(TIMESTAMP, resourceTimeStamp) - .put(HASH, resource.hash()) - .put(TYPE, resource.type().name().toLowerCase()); - - if (resource.type() == FILE) { - content.put(CONTENT, new String(resource.content())); - } - - message.getSource() - .sendMessage(new FluxMessage(GET_RESOURCE_RESPONSE, content)); - } - } - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java deleted file mode 100644 index 9e4e0c6..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/GetResourceResponseHandler.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core.internal; - -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; -import org.eclipse.flux.watcher.core.Resource; -import org.eclipse.flux.watcher.core.spi.Project; - -import org.json.JSONException; -import org.json.JSONObject; - -import javax.inject.Singleton; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.CONTENT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_RESPONSE; -import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_STORED; -import static org.eclipse.flux.watcher.core.Resource.ResourceType; -import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; - -/** - * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#GET_RESOURCE_RESPONSE}. - * - * @author Kevin Pollet - */ -@FluxMessageTypes(GET_RESOURCE_RESPONSE) -public final class GetResourceResponseHandler implements FluxMessageHandler { - @Override - public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.getContent(); - final String projectName = request.getString(PROJECT); - final String resourcePath = request.getString(RESOURCE); - final long resourceTimestamp = request.getLong(TIMESTAMP); - final String resourceHash = request.getString(HASH); - final String resourceContent = request.getString(CONTENT); - - final Project project = repository.getProject(projectName); - if (project != null) { - final ResourceType resourceType = ResourceType.valueOf(request.getString(TYPE).toUpperCase()); - - if (resourceType == FILE) { - boolean isResourceStored = false; - final Resource localResource = project.getResource(resourcePath); - final Resource resource = Resource.newFile(resourcePath, resourceTimestamp, resourceContent.getBytes()); - - if (localResource == null) { - project.createResource(resource); - isResourceStored = true; - - } else if (!localResource.hash().equals(resourceHash) && localResource.timestamp() < resourceTimestamp) { - project.updateResource(resource); - isResourceStored = true; - } - - if (isResourceStored) { - final JSONObject content = new JSONObject() - .put(PROJECT, projectName) - .put(RESOURCE, resourcePath) - .put(TIMESTAMP, resourceTimestamp) - .put(HASH, resourceHash) - .put(TYPE, resourceType.name().toLowerCase()); - - message.getSource() - .sendMessage(new FluxMessage(RESOURCE_STORED, content)); - } - } - } - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java deleted file mode 100644 index 925326b..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceCreatedListener.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core.internal; - -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageBus; -import org.eclipse.flux.watcher.core.RepositoryEvent; -import org.eclipse.flux.watcher.core.RepositoryEventTypes; -import org.eclipse.flux.watcher.core.RepositoryListener; - -import org.json.JSONException; -import org.json.JSONObject; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; -import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_CREATED; -import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_STORED; -import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_CREATED; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Listener sending a message to flux connections when a project resource is created in the repository. - * - * @author Kevin Pollet - */ -@Singleton -//@RepositoryEventTypes(PROJECT_RESOURCE_CREATED) -public final class ProjectResourceCreatedListener implements RepositoryListener { - private final FluxMessageBus messageBus; - - /** - * Constructs an instance of {@code ProjectResourceCreatedListener}. - * - * @param messageBus - * the {@link com.codenvy.flux.watcher.core.FluxMessageBus}. - * @throws java.lang.NullPointerException - * if {@code messageBus} parameter is {@code null}. - */ - @Inject - ProjectResourceCreatedListener(FluxMessageBus messageBus) { - this.messageBus = checkNotNull(messageBus); - } - - @Override - public void onEvent(RepositoryEvent event) throws JSONException { - JSONObject content = new JSONObject(); - content.put(PROJECT, event.project().id()); - content.put(RESOURCE, event.resource().path()); - content.put(TIMESTAMP, event.resource().timestamp()); - content.put(HASH, event.resource().hash()); - content.put(TYPE, event.resource().type().name().toLowerCase()); - - messageBus.sendMessages(new FluxMessage(RESOURCE_CREATED, content), new FluxMessage(RESOURCE_STORED, content)); - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java deleted file mode 100644 index 784f0a2..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceDeletedListener.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core.internal; - -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageBus; -import org.eclipse.flux.watcher.core.RepositoryEvent; -import org.eclipse.flux.watcher.core.RepositoryEventTypes; -import org.eclipse.flux.watcher.core.RepositoryListener; - -import org.json.JSONException; -import org.json.JSONObject; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; -import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_DELETED; -import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_DELETED; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Listener sending a message to flux connections when a project resource is deleted in the repository. - * - * @author Kevin Pollet - */ -@Singleton -//@RepositoryEventTypes(PROJECT_RESOURCE_DELETED) -public final class ProjectResourceDeletedListener implements RepositoryListener { - private final FluxMessageBus messageBus; - - /** - * Constructs an instance of {@code ProjectResourceDeletedListener}. - * - * @param messageBus - * the {@link com.codenvy.flux.watcher.core.FluxMessageBus}. - * @throws NullPointerException - * if {@code messageBus} parameter is {@code null}. - */ - @Inject - ProjectResourceDeletedListener(FluxMessageBus messageBus) { - this.messageBus = checkNotNull(messageBus); - } - - @Override - public void onEvent(RepositoryEvent event) throws JSONException { - JSONObject content = new JSONObject(); - content.put(PROJECT, event.project().id()); - content.put(RESOURCE, event.resource().path()); - content.put(TIMESTAMP, event.resource().timestamp()); - - messageBus.sendMessages(new FluxMessage(RESOURCE_DELETED, content)); - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java deleted file mode 100644 index d1d9402..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ProjectResourceModifiedListener.java +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core.internal; - -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageBus; -import org.eclipse.flux.watcher.core.RepositoryEvent; -import org.eclipse.flux.watcher.core.RepositoryEventTypes; -import org.eclipse.flux.watcher.core.RepositoryListener; - -import org.json.JSONException; -import org.json.JSONObject; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; -import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_CHANGED; -import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_STORED; -import static org.eclipse.flux.watcher.core.RepositoryEventType.PROJECT_RESOURCE_MODIFIED; -import static org.eclipse.flux.watcher.core.Resource.ResourceType.FILE; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Listener sending a message to flux connections when a project resource is modified in the repository. - * - * @author Kevin Pollet - */ -@Singleton -//@RepositoryEventTypes(PROJECT_RESOURCE_MODIFIED) -public final class ProjectResourceModifiedListener implements RepositoryListener { - private final FluxMessageBus messageBus; - - /** - * Constructs an instance of {@code ProjectResourceModifiedListener}. - * - * @param messageBus - * the {@link com.codenvy.flux.watcher.core.FluxMessageBus}. - * @throws NullPointerException - * if {@code messageBus} parameter is {@code null}. - */ - @Inject - ProjectResourceModifiedListener(FluxMessageBus messageBus) { - this.messageBus = checkNotNull(messageBus); - } - - @Override - public void onEvent(RepositoryEvent event) throws JSONException { - if (event.resource().type() != FILE) { - return; - } - JSONObject content = new JSONObject(); - content.put(PROJECT, event.project().id()); - content.put(RESOURCE, event.resource().path()); - content.put(TIMESTAMP, event.resource().timestamp()); - content.put(HASH, event.resource().hash()); - - messageBus.sendMessages(new FluxMessage(RESOURCE_CHANGED, content), new FluxMessage(RESOURCE_STORED, content)); - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java deleted file mode 100644 index 849f901..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceChangedHandler.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core.internal; - -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; -import org.eclipse.flux.watcher.core.Resource; -import org.eclipse.flux.watcher.core.spi.Project; - -import org.json.JSONException; -import org.json.JSONObject; - -import javax.inject.Singleton; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_REQUEST; -import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_CHANGED; - -/** - * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#RESOURCE_CHANGED}. - * - * @author Kevin Pollet - */ -@FluxMessageTypes(RESOURCE_CHANGED) -public final class ResourceChangedHandler implements FluxMessageHandler { - @Override - public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.getContent(); - final String projectName = request.getString(PROJECT); - final String resourcePath = request.getString(RESOURCE); - final long resourceTimestamp = request.getLong(TIMESTAMP); - final String resourceHash = request.getString(HASH); - - final Project project = repository.getProject(projectName); - if (project != null) { - final Resource localResource = project.getResource(resourcePath); - - if (localResource != null - && !localResource.hash().equals(resourceHash) - && localResource.timestamp() < resourceTimestamp) { - - final JSONObject content = new JSONObject() - .put(PROJECT, projectName) - .put(RESOURCE, resourcePath) - .put(TIMESTAMP, resourceTimestamp) - .put(HASH, resourceHash); - - message.getSource() - .sendMessage(new FluxMessage(GET_RESOURCE_REQUEST, content)); - } - } - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java deleted file mode 100644 index 41255a2..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceCreatedHandler.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core.internal; - -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; -import org.eclipse.flux.watcher.core.Resource; -import org.eclipse.flux.watcher.core.spi.Project; - -import org.json.JSONException; -import org.json.JSONObject; - -import javax.inject.Singleton; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.HASH; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TYPE; -import static org.eclipse.flux.watcher.core.FluxMessageType.GET_RESOURCE_REQUEST; -import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_CREATED; -import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_STORED; -import static org.eclipse.flux.watcher.core.Resource.ResourceType; -import static org.eclipse.flux.watcher.core.Resource.ResourceType.FOLDER; - -/** - * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#RESOURCE_CREATED}. - * - * @author Kevin Pollet - */ -@FluxMessageTypes(RESOURCE_CREATED) -public final class ResourceCreatedHandler implements FluxMessageHandler { - @Override - public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.getContent(); - final String projectName = request.getString(PROJECT); - final String resourcePath = request.getString(RESOURCE); - final long resourceTimestamp = request.getLong(TIMESTAMP); - final String resourceHash = request.getString(HASH); - - final Project project = repository.getProject(projectName); - if (project != null && project.getResource(resourcePath) == null) { - final ResourceType resourceType = ResourceType.valueOf(request.getString(TYPE).toUpperCase()); - if (resourceType == FOLDER) { - final Resource folder = Resource.newFolder(resourcePath, resourceTimestamp); - project.createResource(folder); - } - final JSONObject content = new JSONObject() - .put(PROJECT, projectName) - .put(RESOURCE, resourcePath) - .put(TIMESTAMP, resourceTimestamp) - .put(HASH, resourceHash) - .put(TYPE, resourceType.name().toLowerCase()); - - message.getSource().sendMessage(new FluxMessage(resourceType == FOLDER ? RESOURCE_STORED : GET_RESOURCE_REQUEST, content)); - } - } -} diff --git a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java b/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java deleted file mode 100644 index 684f1ac..0000000 --- a/org.eclipse.flux.watcher/src/main/java/org/eclipse/flux/watcher/core/internal/ResourceDeletedHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core.internal; - -import org.eclipse.flux.watcher.core.FluxMessage; -import org.eclipse.flux.watcher.core.FluxMessageHandler; -import org.eclipse.flux.watcher.core.FluxMessageTypes; -import org.eclipse.flux.watcher.core.Repository; -import org.eclipse.flux.watcher.core.Resource; -import org.eclipse.flux.watcher.core.spi.Project; - -import org.json.JSONException; -import org.json.JSONObject; - -import javax.inject.Singleton; - -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.PROJECT; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.RESOURCE; -import static org.eclipse.flux.watcher.core.FluxMessage.Fields.TIMESTAMP; -import static org.eclipse.flux.watcher.core.FluxMessageType.RESOURCE_DELETED; - -/** - * Handler replying to a {@link com.codenvy.flux.watcher.core.FluxMessageType#RESOURCE_DELETED}. - * - * @author Kevin Pollet - */ -@FluxMessageTypes(RESOURCE_DELETED) -public final class ResourceDeletedHandler implements FluxMessageHandler { - @Override - public void onMessage(FluxMessage message, Repository repository) throws JSONException { - final JSONObject request = message.getContent(); - final String projectName = request.getString(PROJECT); - final String resourcePath = request.getString(RESOURCE); - final long resourceTimestamp = request.getLong(TIMESTAMP); - - final Project project = repository.getProject(projectName); - if(project == null || !project.hasResource(resourcePath)) - return; - Resource localResource = project.getResource(resourcePath); - if(localResource.timestamp() < resourceTimestamp) - project.deleteResource(Resource.newUnknown(resourcePath, resourceTimestamp)); - } -} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/FluxMessageTypeTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/FluxMessageTypeTest.java deleted file mode 100644 index de59775..0000000 --- a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/FluxMessageTypeTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 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.flux.watcher.core; - - -import org.junit.Assert; -import org.junit.Test; - -import static org.eclipse.flux.watcher.core.FluxMessageType.CONNECT_TO_CHANNEL; - -/** - * {@link com.codenvy.flux.watcher.core.FluxMessageType} tests. - * - * @author Kevin Pollet - */ -public final class FluxMessageTypeTest { - @Test(expected = NullPointerException.class) - public void testFromTypeWithNullType() { - FluxMessageType.fromType(null); - } - - @Test(expected = IllegalArgumentException.class) - public void testFromTypeWithNonExistentType() { - FluxMessageType.fromType("foo"); - } - - @Test - public void testFromType() { - final FluxMessageType fluxMessageType = FluxMessageType.fromType(CONNECT_TO_CHANNEL.value()); - - Assert.assertEquals(CONNECT_TO_CHANNEL, fluxMessageType); - } -} diff --git a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryTest.java b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryTest.java index d014e8c..770edf2 100644 --- a/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryTest.java +++ b/org.eclipse.flux.watcher/src/test/java/org/eclipse/flux/watcher/core/RepositoryTest.java @@ -17,13 +17,8 @@ import org.junit.Before; import org.junit.Test; -import java.net.MalformedURLException; -import java.net.URL; - import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** @@ -36,7 +31,6 @@ public final class RepositoryTest { private final static String PROJECT_PATH = "/project-id"; private Repository repository; - private FluxMessageBus fluxMessageBusMock; @Before public void beforeTest() { @@ -46,58 +40,6 @@ public void beforeTest() { final ProjectFactory projectFactoryMock = mock(ProjectFactory.class); when(projectFactoryMock.newProject(anyString(), anyString())).thenReturn(projectMock); - - fluxMessageBusMock = mock(FluxMessageBus.class); - - repository = new Repository(fluxMessageBusMock, projectFactoryMock, mock(RepositoryEventBus.class)); - } - - @Test(expected = NullPointerException.class) - public void testNewWithNullMessageBus() { - new Repository(null, mock(ProjectFactory.class), mock(RepositoryEventBus.class)); - } - - @Test(expected = NullPointerException.class) - public void testNewWithNullProjectFactory() { - new Repository(mock(FluxMessageBus.class), null, mock(RepositoryEventBus.class)); - } - - @Test(expected = NullPointerException.class) - public void testNewWithNullRepositoryEventBus() { - new Repository(mock(FluxMessageBus.class), mock(ProjectFactory.class), null); - } - - @Test(expected = NullPointerException.class) - public void testAddRemoteWithNullRemoteURL() { - repository.addRemote(null, Credentials.DEFAULT_USER_CREDENTIALS); - } - - @Test(expected = NullPointerException.class) - public void testAddRemoteWithNullCredentials() throws MalformedURLException { - repository.addRemote(new URL("http://localhost:8080"), null); - } - - @Test - public void testAddRemote() throws MalformedURLException { - final URL remoteURL = new URL("http://localhost:8080"); - - repository.addRemote(remoteURL, Credentials.DEFAULT_USER_CREDENTIALS); - - verify(fluxMessageBusMock, times(1)).connect(remoteURL, Credentials.DEFAULT_USER_CREDENTIALS); - } - - @Test(expected = NullPointerException.class) - public void testRemoveRemoteWithNullRemoteURL() { - repository.removeRemote(null); - } - - @Test - public void testRemoveRemote() throws MalformedURLException { - final URL remoteURL = new URL("http://localhost:8080"); - - repository.removeRemote(remoteURL); - - verify(fluxMessageBusMock, times(1)).disconnect(remoteURL); } @Test(expected = NullPointerException.class) From 9a0df0341139f0da74287717b8416ff925b89236 Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Tue, 23 Aug 2016 06:14:18 +0300 Subject: [PATCH 32/34] Improved code && used static fields for building messages Signed-off-by: Fjodor Vershinin --- .../eclipse/flux/client/IMessageHandler.java | 2 + .../eclipse/flux/client/MessageConstants.java | 6 ++- .../eclipse/flux/core/RepositoryAdapter.java | 41 ++++++++++--------- .../handlers/LiveResourceChangedHandler.java | 2 +- .../handlers/LiveResourceStartedHandler.java | 2 +- .../LiveResourceStartedResponseHandler.java | 2 +- .../core/handlers/MetadataRequestHandler.java | 9 ++-- .../core/handlers/ProjectResponseHandler.java | 2 +- .../handlers/ProjectsResponseHandler.java | 14 +++---- .../core/handlers/ResourceRequestHandler.java | 15 +++++-- 10 files changed, 54 insertions(+), 41 deletions(-) diff --git a/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java b/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java index 14b2917..fdcc157 100644 --- a/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java +++ b/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/IMessageHandler.java @@ -21,6 +21,8 @@ public interface IMessageHandler { public static final String GET_PROJECT_REQUEST = "getProjectRequest"; public static final String GET_PROJECT_RESPONSE = "getProjectResponse"; + public static final String GET_PROJECTS_REQUEST = "getProjectsRequest"; + public static final String GET_PROJECTS_RESPONSE = "getProjectsResponse"; public static final String GET_LIVE_RESOURCE_REQUEST = "getLiveResourcesRequest"; public static final String GET_METADATA_REQUEST = "getMetadataRequest"; public static final String GET_METADATA_RESPONSE = "getMetadataResponse"; diff --git a/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/MessageConstants.java b/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/MessageConstants.java index 4b7bd94..ab1cea9 100644 --- a/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/MessageConstants.java +++ b/org.eclipse.flux.client.java/src/main/java/org/eclipse/flux/client/MessageConstants.java @@ -65,7 +65,6 @@ public abstract class MessageConstants { public static final String HASH = "hash"; public static final String INCLUDE_DELETED = "includeDeleted"; public static final String PATH = "path"; - public static final String PROJECT = "project"; public static final String RESOURCE = "resource"; public static final String TIMESTAMP = "timestamp"; public static final String TYPE = "type"; @@ -77,5 +76,8 @@ public abstract class MessageConstants { public static final String ADDED_CHARACTERS = "addedCharacters"; public static final String PROJECT_REG_EX = "projectRegEx"; public static final String RESOURCE_REG_EX = "resourceRegEx"; - + public static final String METADATA = "metadata"; + public static final String PROJECTS = "projects"; + public static final String NAME = "name"; + public static final String MARKER = "marker"; } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index d7d5a0e..e69db94 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -34,6 +34,7 @@ import org.eclipse.flux.core.util.Utils; import org.eclipse.flux.client.IMessageHandler; import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.client.MessageConstants; import org.eclipse.flux.watcher.core.Repository; import org.eclipse.flux.watcher.core.RepositoryEvent; import org.eclipse.flux.watcher.core.RepositoryEventBus; @@ -85,32 +86,32 @@ public void onEvent(RepositoryEvent event) throws Exception { switch (event.type()) { case PROJECT_RESOURCE_CREATED: JSONObject createdStoredMessage = new JSONObject(); - createdStoredMessage.put("username", RepositoryAdapter.this.username); - createdStoredMessage.put("project", project.id()); - createdStoredMessage.put("resource", resource.path()); - createdStoredMessage.put("timestamp", resource.timestamp()); - createdStoredMessage.put("hash", resource.hash()); - createdStoredMessage.put("type", resource.type().name().toLowerCase()); - RepositoryAdapter.this.messageConnector.send("resourceCreated", createdStoredMessage); - RepositoryAdapter.this.messageConnector.send("resourceStored", createdStoredMessage); + createdStoredMessage.put(MessageConstants.USERNAME, RepositoryAdapter.this.username); + createdStoredMessage.put(MessageConstants.PROJECT_NAME, project.id()); + createdStoredMessage.put(MessageConstants.RESOURCE, resource.path()); + createdStoredMessage.put(MessageConstants.TIMESTAMP, resource.timestamp()); + createdStoredMessage.put(MessageConstants.HASH, resource.hash()); + createdStoredMessage.put(MessageConstants.TYPE, resource.type().name().toLowerCase()); + RepositoryAdapter.this.messageConnector.send(IMessageHandler.RESOURCE_CREATED, createdStoredMessage); + RepositoryAdapter.this.messageConnector.send(IMessageHandler.RESOURCE_STORED, createdStoredMessage); break; case PROJECT_RESOURCE_MODIFIED: JSONObject modifiedStoredMessage = new JSONObject(); - modifiedStoredMessage.put("username", RepositoryAdapter.this.username); - modifiedStoredMessage.put("project", project.id()); - modifiedStoredMessage.put("resource", resource.path()); - modifiedStoredMessage.put("timestamp", resource.timestamp()); - modifiedStoredMessage.put("hash", resource.hash()); - RepositoryAdapter.this.messageConnector.send("resourceChanged", modifiedStoredMessage); - RepositoryAdapter.this.messageConnector.send("resourceStored", modifiedStoredMessage); + modifiedStoredMessage.put(MessageConstants.USERNAME, RepositoryAdapter.this.username); + modifiedStoredMessage.put(MessageConstants.PROJECT_NAME, project.id()); + modifiedStoredMessage.put(MessageConstants.RESOURCE, resource.path()); + modifiedStoredMessage.put(MessageConstants.TIMESTAMP, resource.timestamp()); + modifiedStoredMessage.put(MessageConstants.HASH, resource.hash()); + RepositoryAdapter.this.messageConnector.send(IMessageHandler.RESOURCE_CHANGED, modifiedStoredMessage); + RepositoryAdapter.this.messageConnector.send(IMessageHandler.RESOURCE_STORED, modifiedStoredMessage); break; case PROJECT_RESOURCE_DELETED: JSONObject message = new JSONObject(); - message.put("username", RepositoryAdapter.this.username); - message.put("project", project.id()); - message.put("resource", resource.path()); - message.put("timestamp", resource.timestamp()); - RepositoryAdapter.this.messageConnector.send("resourceDeleted", message); + message.put(MessageConstants.USERNAME, RepositoryAdapter.this.username); + message.put(MessageConstants.PROJECT_NAME, project.id()); + message.put(MessageConstants.RESOURCE, resource.path()); + message.put(MessageConstants.TIMESTAMP, resource.timestamp()); + RepositoryAdapter.this.messageConnector.send(IMessageHandler.RESOURCE_DELETED, message); break; default: break; diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java index 074ff62..634d1e0 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceChangedHandler.java @@ -17,7 +17,7 @@ public LiveResourceChangedHandler(Collection liveEditConnect @Override protected void onMessage(String type, JSONObject message) throws Exception { String username = message.getString(MessageConstants.USERNAME); - String projectName = message.getString(MessageConstants.PROJECT); + String projectName = message.getString(MessageConstants.PROJECT_NAME); String resourcePath = message.getString(MessageConstants.RESOURCE); int offset = message.getInt(MessageConstants.OFFSET); int removedCharCount = message.getInt(MessageConstants.REMOVED_CHAR_COUNT); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java index 36486c8..88defb5 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedHandler.java @@ -19,7 +19,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { String requestSenderID = message.getString(MessageConstants.REQUEST_SENDER_ID); int callbackID = message.getInt(MessageConstants.CALLBACK_ID); String username = message.getString(MessageConstants.USERNAME); - String projectName = message.getString(MessageConstants.PROJECT); + String projectName = message.getString(MessageConstants.PROJECT_NAME); String resourcePath = message.getString(MessageConstants.RESOURCE); String hash = message.getString(MessageConstants.HASH); long timestamp = message.getLong(MessageConstants.TIMESTAMP); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java index 9de53ea..66305e8 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/LiveResourceStartedResponseHandler.java @@ -19,7 +19,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { String requestSenderID = message.getString(MessageConstants.REQUEST_SENDER_ID); int callbackID = message.getInt(MessageConstants.CALLBACK_ID); String username = message.getString(MessageConstants.USERNAME); - String projectName = message.getString(MessageConstants.PROJECT); + String projectName = message.getString(MessageConstants.PROJECT_NAME); String resourcePath = message.getString(MessageConstants.RESOURCE); String savePointHash = message.getString(MessageConstants.SAVE_POINT_HASH); long savePointTimestamp = message.getLong(MessageConstants.SAVE_POINT_TIMESTAMP); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java index 5e48b3d..cc88850 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java @@ -1,6 +1,7 @@ package org.eclipse.flux.core.handlers; import org.eclipse.core.resources.IResource; +import org.eclipse.flux.client.MessageConstants; import org.eclipse.flux.core.IRepositoryCallback; import org.eclipse.flux.core.util.JSONUtils; import org.eclipse.flux.core.util.Utils; @@ -16,15 +17,15 @@ public MetadataRequestHandler(IRepositoryCallback repositoryCallback) { @Override protected void onMessage(String type, JSONObject message) throws Exception { - String projectName = message.getString("project"); - String resourcePath = message.getString("resource"); + String projectName = message.getString(MessageConstants.PROJECT_NAME); + String resourcePath = message.getString(MessageConstants.RESOURCE); Project project = repositoryCallback.getWatcherProject(projectName); if(project != null){ Resource resource = project.getResource(resourcePath); if(resource != null){ IResource file = Utils.getResourceByPath(projectName, resourcePath); - message.put("type", "marker"); - message.put("metadata", JSONUtils.toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE))); + message.put(MessageConstants.TYPE, "marker"); + message.put(MessageConstants.METADATA, JSONUtils.toJSON(file.findMarkers(null, true, IResource.DEPTH_INFINITE))); repositoryCallback.sendMessage(GET_METADATA_RESPONSE, message); } } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java index 31728d4..f0e6cb2 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java @@ -33,7 +33,7 @@ protected void onMessage(String type, JSONObject message) throws Exception { if(localResource == null || IsResourcesNotEquals(localResource, hash, timestamp)){ JSONObject content = new JSONObject(); content.put(MessageConstants.CALLBACK_ID, callbackID); - content.put(MessageConstants.PROJECT, project.id()); + content.put(MessageConstants.PROJECT_NAME, project.id()); content.put(MessageConstants.RESOURCE, path); content.put(MessageConstants.TIMESTAMP, timestamp); content.put(MessageConstants.HASH, hash); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java index f91bdb6..ab7380a 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java @@ -9,7 +9,7 @@ public class ProjectsResponseHandler extends AbstractMsgHandler { public ProjectsResponseHandler(IRepositoryCallback repositoryCallback) { - super(repositoryCallback, "getProjectsRequest"); + super(repositoryCallback, GET_PROJECTS_REQUEST); } @Override @@ -21,16 +21,16 @@ protected void onMessage(String type, JSONObject message) throws Exception { JSONArray projects = new JSONArray(); for (Project fluxProject : repositoryCallback.getSynchronizedProjects()) { JSONObject project = new JSONObject(); - project.put("name", fluxProject.id()); + project.put(MessageConstants.NAME, fluxProject.id()); projects.put(project); } JSONObject content = new JSONObject(); - content.put("callback_id", callbackID); - content.put("requestSenderID", requestSenderId); - content.put("username", username); - content.put("projects", projects); + content.put(MessageConstants.CALLBACK_ID, callbackID); + content.put(MessageConstants.REQUEST_SENDER_ID, requestSenderId); + content.put(MessageConstants.USERNAME, username); + content.put(MessageConstants.PROJECTS, projects); - repositoryCallback.sendMessage("getProjectsResponse", content); + repositoryCallback.sendMessage(GET_PROJECTS_RESPONSE, content); } } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java index fbd16ff..e2a4147 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java @@ -5,6 +5,7 @@ import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.eclipse.flux.watcher.core.spi.Project; +import org.json.JSONException; import org.json.JSONObject; public class ResourceRequestHandler extends AbstractMsgHandler { @@ -18,16 +19,22 @@ protected void onMessage(String type, JSONObject message) throws Exception { if (project == null) return; Resource resource = project.getResource(message.getString(MessageConstants.RESOURCE)); - if (resource == null || message.has("timestamp") && message.getLong("timestamp") != resource.timestamp()) + if (resource == null || compareTimestamp(message, resource)) return; message.put(MessageConstants.TIMESTAMP, resource.timestamp()); message.put(MessageConstants.HASH, resource.hash()); message.put(MessageConstants.TYPE, resource.type().name().toLowerCase()); - if (resource.type() == ResourceType.FILE) { - if(message.has("hash") && !message.getString("hash").equals(resource.hash())) - return; + if (resource.type() == ResourceType.FILE && !compareHash(message, resource)) { message.put(MessageConstants.CONTENT, new String(resource.content())); } repositoryCallback.sendMessage(GET_RESOURCE_RESPONSE, message); } + + private boolean compareHash(JSONObject message, Resource resource) throws JSONException { + return message.has(MessageConstants.HASH) && !message.getString(MessageConstants.HASH).equals(resource.hash()); + } + + private boolean compareTimestamp(JSONObject message, Resource resource) throws JSONException { + return message.has(MessageConstants.TIMESTAMP) && message.getLong(MessageConstants.TIMESTAMP) != resource.timestamp(); + } } From 1b01a239550a1a111b87e2c7f19b3bbbefe366bb Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Tue, 23 Aug 2016 08:42:57 +0300 Subject: [PATCH 33/34] Separated the logic of file system sync from RepositoryAdapter Signed-off-by: Fjodor Vershinin --- .../src/org/eclipse/flux/core/Activator.java | 6 +- .../eclipse/flux/core/RepositoryAdapter.java | 201 ++---------------- .../core/handlers/AbstractMsgHandler.java | 6 +- .../core/handlers/MetadataRequestHandler.java | 4 +- .../core/handlers/ProjectRequestHandler.java | 4 +- .../core/handlers/ProjectResponseHandler.java | 4 +- .../handlers/ProjectsResponseHandler.java | 4 +- .../core/handlers/ResourceChangedHandler.java | 9 +- .../core/handlers/ResourceCreatedHandler.java | 4 +- .../core/handlers/ResourceDeletedHandler.java | 4 +- .../core/handlers/ResourceRequestHandler.java | 4 +- .../handlers/ResourceResponseHandler.java | 12 +- .../ISystemSync.java} | 8 +- 13 files changed, 58 insertions(+), 212 deletions(-) rename org.eclipse.flux.core/src/org/eclipse/flux/core/{IRepositoryCallback.java => sync/ISystemSync.java} (60%) diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java index f728b7f..51dbe6e 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/Activator.java @@ -37,7 +37,6 @@ import org.eclipse.flux.client.config.SocketIOFluxConfig; import org.eclipse.flux.core.internal.CloudSyncMetadataListener; import org.eclipse.flux.core.util.ExceptionUtil; -import org.eclipse.flux.watcher.core.Repository; import org.eclipse.flux.watcher.core.RepositoryModule; import org.eclipse.flux.watcher.fs.JDKProjectModule; import org.osgi.framework.BundleContext; @@ -71,8 +70,6 @@ public class Activator extends Plugin { private IRepositoryListener repositoryListener; private IResourceChangeListener workspaceListener; - private Repository fluxRepository; - private final IChannelListener SERVICE_STARTER = new IChannelListener() { @Override public void connected(String userChannel) { @@ -117,7 +114,6 @@ public void start(BundleContext context) throws Exception { final String userChannel = lazyStart ? MessageConstants.SUPER_USER : channel; Injector injector = Guice.createInjector(new RepositoryModule(), new JDKProjectModule()); - fluxRepository = injector.getInstance(Repository.class); //Connecting to channel done asynchronously. To avoid blocking plugin state initialization. FluxClient.DEFAULT_INSTANCE.getExecutor().execute(new Runnable() { @Override @@ -174,7 +170,7 @@ public void stop(BundleContext context) throws Exception { } private void initCoreService(String userChannel) throws CoreException { - repository = new RepositoryAdapter(messageConnector, fluxRepository, userChannel); + repository = new RepositoryAdapter(messageConnector, userChannel); liveEditCoordinator = new LiveEditCoordinator(messageConnector); IWorkspace workspace = ResourcesPlugin.getWorkspace(); diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index e69db94..6d46d95 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -10,126 +10,45 @@ *******************************************************************************/ package org.eclipse.flux.core; -import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ConcurrentLinkedDeque; -import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.flux.core.handlers.MetadataRequestHandler; -import org.eclipse.flux.core.handlers.ProjectRequestHandler; -import org.eclipse.flux.core.handlers.ProjectResponseHandler; -import org.eclipse.flux.core.handlers.ProjectsResponseHandler; -import org.eclipse.flux.core.handlers.ResourceChangedHandler; -import org.eclipse.flux.core.handlers.ResourceCreatedHandler; -import org.eclipse.flux.core.handlers.ResourceDeletedHandler; -import org.eclipse.flux.core.handlers.ResourceRequestHandler; -import org.eclipse.flux.core.handlers.ResourceResponseHandler; -import org.eclipse.flux.core.util.JSONUtils; -import org.eclipse.flux.core.util.Utils; -import org.eclipse.flux.client.IMessageHandler; import org.eclipse.flux.client.MessageConnector; -import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.core.sync.FluxSystemSync; +import org.eclipse.flux.core.util.Utils; import org.eclipse.flux.watcher.core.RepositoryEvent; -import org.eclipse.flux.watcher.core.RepositoryEventBus; import org.eclipse.flux.watcher.core.RepositoryListener; -import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; -import org.json.JSONArray; -import org.json.JSONObject; /** * @author Martin Lippert */ -public class RepositoryAdapter implements IRepositoryCallback{ - private static int GET_PROJECT_CALLBACK = "Repository - getProjectCallback".hashCode(); - private static int GET_RESOURCE_CALLBACK = "Repository - getResourceCallback".hashCode(); - - private String username; +public class RepositoryAdapter implements RepositoryListener{ + private FluxSystemSync systemSync; private Collection repositoryListeners; - private RepositoryEventBus repositoryEventBus; - private Repository repository; - private MessageConnector messageConnector; - private Collection messageHandlers; - - public RepositoryAdapter(MessageConnector messageConnector, Repository repository, String user) { - this.repository = repository; - this.repositoryEventBus = repository.repositoryEventBus(); - this.messageConnector = messageConnector; - this.username = user; - this.messageHandlers = new ArrayList<>(); + public RepositoryAdapter(MessageConnector messageConnector, String user) { + this.systemSync = new FluxSystemSync(messageConnector, user, this); this.repositoryListeners = new ConcurrentLinkedDeque<>(); - - addMessageHandler(new MetadataRequestHandler(this)); - addMessageHandler(new ProjectsResponseHandler(this)); - addMessageHandler(new ProjectRequestHandler(this)); - addMessageHandler(new ProjectResponseHandler(this, GET_PROJECT_CALLBACK)); - addMessageHandler(new ResourceRequestHandler(this)); - addMessageHandler(new ResourceResponseHandler(this, GET_RESOURCE_CALLBACK)); - addMessageHandler(new ResourceCreatedHandler(this, GET_RESOURCE_CALLBACK)); - addMessageHandler(new ResourceChangedHandler(this, GET_RESOURCE_CALLBACK)); - addMessageHandler(new ResourceDeletedHandler(this)); - - this.repositoryEventBus.addRepositoryListener(new RepositoryListener() { - @Override - public void onEvent(RepositoryEvent event) throws Exception { - Project project = event.project(); - Resource resource = event.resource(); - switch (event.type()) { - case PROJECT_RESOURCE_CREATED: - JSONObject createdStoredMessage = new JSONObject(); - createdStoredMessage.put(MessageConstants.USERNAME, RepositoryAdapter.this.username); - createdStoredMessage.put(MessageConstants.PROJECT_NAME, project.id()); - createdStoredMessage.put(MessageConstants.RESOURCE, resource.path()); - createdStoredMessage.put(MessageConstants.TIMESTAMP, resource.timestamp()); - createdStoredMessage.put(MessageConstants.HASH, resource.hash()); - createdStoredMessage.put(MessageConstants.TYPE, resource.type().name().toLowerCase()); - RepositoryAdapter.this.messageConnector.send(IMessageHandler.RESOURCE_CREATED, createdStoredMessage); - RepositoryAdapter.this.messageConnector.send(IMessageHandler.RESOURCE_STORED, createdStoredMessage); - break; - case PROJECT_RESOURCE_MODIFIED: - JSONObject modifiedStoredMessage = new JSONObject(); - modifiedStoredMessage.put(MessageConstants.USERNAME, RepositoryAdapter.this.username); - modifiedStoredMessage.put(MessageConstants.PROJECT_NAME, project.id()); - modifiedStoredMessage.put(MessageConstants.RESOURCE, resource.path()); - modifiedStoredMessage.put(MessageConstants.TIMESTAMP, resource.timestamp()); - modifiedStoredMessage.put(MessageConstants.HASH, resource.hash()); - RepositoryAdapter.this.messageConnector.send(IMessageHandler.RESOURCE_CHANGED, modifiedStoredMessage); - RepositoryAdapter.this.messageConnector.send(IMessageHandler.RESOURCE_STORED, modifiedStoredMessage); - break; - case PROJECT_RESOURCE_DELETED: - JSONObject message = new JSONObject(); - message.put(MessageConstants.USERNAME, RepositoryAdapter.this.username); - message.put(MessageConstants.PROJECT_NAME, project.id()); - message.put(MessageConstants.RESOURCE, resource.path()); - message.put(MessageConstants.TIMESTAMP, resource.timestamp()); - RepositoryAdapter.this.messageConnector.send(IMessageHandler.RESOURCE_DELETED, message); - break; - default: - break; - } - } - }); } public String getUsername() { - return this.username; + return systemSync.getUsername(); } public ConnectedProject getProject(IProject project) { - return new ConnectedProject(repository.getProject(project.getName())); + return getProject(project.getName()); } public ConnectedProject getProject(String projectName) { - return new ConnectedProject(repository.getProject(projectName)); + return new ConnectedProject(systemSync.getWatcherProject(projectName)); } public boolean isConnected(IProject project) { @@ -137,31 +56,21 @@ public boolean isConnected(IProject project) { } public boolean isConnected(String projectName) { - Project project = this.repository.getProject(projectName); - return this.repository.getSynchronizedProjects().contains(project); + return systemSync.isProjectConnected(projectName); } public void addProject(IProject project) { - this.repository.addProject(project.getName(), project.getLocationURI().getPath()); - notifyProjectConnected(project); - sendProjectConnectedMessage(project.getName()); - syncConnectedProject(project.getName()); + this.systemSync.addProject(project.getName(), project.getLocationURI().getPath()); + notifyProjectConnected(project); } public void removeProject(IProject project) { - this.repository.removeProject(project.getName()); - notifyProjectDisonnected(project); - JSONObject message = new JSONObject(); - try { - message.put("username", this.username); - message.put("project", project.getName()); - messageConnector.send("projectDisconnected", message); - } catch (Exception e) { - e.printStackTrace(); - } + this.systemSync.removeProject(project.getName()); + notifyProjectDisonnected(project); } + public ConnectedProject[] getConnectedProjects() { - Set projects = repository.getSynchronizedProjects(); + Set projects = systemSync.getSynchronizedProjects(); Set connectedProjects = new HashSet<>(); for(Project project : projects){ connectedProjects.add(new ConnectedProject(project)); @@ -173,27 +82,7 @@ public void metadataChanged(IResourceDelta delta) { IProject project = delta.getResource().getProject(); IMarkerDelta[] markerDeltas = delta.getMarkerDeltas(); if (project != null && isConnected(project) && markerDeltas != null && markerDeltas.length > 0) { - sendMetadataUpdate(delta.getResource()); - } - } - - public void sendMetadataUpdate(IResource resource) { - try { - String project = resource.getProject().getName(); - String resourcePath = resource.getProjectRelativePath().toString(); - - JSONObject message = new JSONObject(); - message.put("username", this.username); - message.put("project", project); - message.put("resource", resourcePath); - message.put("type", "marker"); - - IMarker[] markers = resource.findMarkers(null, true, IResource.DEPTH_INFINITE); - JSONArray content = JSONUtils.toJSON(markers); - message.put("metadata", content); - messageConnector.send(IMessageHandler.METADATA_CHANGED, message); - } catch (Exception e) { - + systemSync.sendMetadataUpdate(delta.getResource()); } } @@ -205,30 +94,6 @@ public void removeRepositoryListener(IRepositoryListener listener) { this.repositoryListeners.remove(listener); } - protected void syncConnectedProject(String projectName) { - try { - JSONObject message = new JSONObject(); - message.put("username", this.username); - message.put("project", projectName); - message.put("includeDeleted", true); - message.put("callback_id", GET_PROJECT_CALLBACK); - messageConnector.send("getProjectRequest", message); - } catch (Exception e) { - e.printStackTrace(); - } - } - - protected void sendProjectConnectedMessage(String projectName) { - try { - JSONObject message = new JSONObject(); - message.put("username", this.username); - message.put("project", projectName); - messageConnector.send("projectConnected", message); - } catch (Exception e) { - e.printStackTrace(); - } - } - protected void notifyProjectConnected(IProject project) { for (IRepositoryListener listener : this.repositoryListeners) { listener.projectConnected(project); @@ -248,36 +113,14 @@ protected void notifyResourceChanged(IResource resource) { } public void dispose() { - for(IMessageHandler messageHandler : messageHandlers){ - messageConnector.removeMessageHandler(messageHandler); - } - } - - private void addMessageHandler(IMessageHandler messageHandler){ - this.messageConnector.addMessageHandler(messageHandler); - this.messageHandlers.add(messageHandler); + systemSync.dispose(); } - - @Override - public void notifyResourceChanged(Resource resource, Project project) { - notifyResourceChanged(Utils.getResourceByPath(project.id(), resource.path())); - - } @Override - public void sendMessage(String messageType, JSONObject content) throws Exception { - messageConnector.send(messageType, content); + public void onEvent(RepositoryEvent event) throws Exception { + String projectName = event.project().id(); + String path = event.resource().path(); + notifyResourceChanged(Utils.getResourceByPath(projectName, path)); } - @Override - public Project getWatcherProject(String projectName) { - return repository.getProject(projectName); - } - - @Override - public Set getSynchronizedProjects() { - return repository.getSynchronizedProjects(); - } - - } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractMsgHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractMsgHandler.java index 6eb6f99..8be2abb 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractMsgHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/AbstractMsgHandler.java @@ -2,15 +2,15 @@ import org.eclipse.flux.client.MessageConstants; import org.eclipse.flux.client.MessageHandler; -import org.eclipse.flux.core.IRepositoryCallback; +import org.eclipse.flux.core.sync.ISystemSync; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.json.JSONObject; public abstract class AbstractMsgHandler extends MessageHandler { - protected IRepositoryCallback repositoryCallback; + protected ISystemSync repositoryCallback; - public AbstractMsgHandler(IRepositoryCallback repositoryCallback, String type) { + public AbstractMsgHandler(ISystemSync repositoryCallback, String type) { super(type); this.repositoryCallback = repositoryCallback; } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java index cc88850..a74f318 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/MetadataRequestHandler.java @@ -2,7 +2,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.core.IRepositoryCallback; +import org.eclipse.flux.core.sync.ISystemSync; import org.eclipse.flux.core.util.JSONUtils; import org.eclipse.flux.core.util.Utils; import org.eclipse.flux.watcher.core.Resource; @@ -11,7 +11,7 @@ public class MetadataRequestHandler extends AbstractMsgHandler { - public MetadataRequestHandler(IRepositoryCallback repositoryCallback) { + public MetadataRequestHandler(ISystemSync repositoryCallback) { super(repositoryCallback, GET_METADATA_REQUEST); } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java index faec7f2..e6f9965 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectRequestHandler.java @@ -1,7 +1,7 @@ package org.eclipse.flux.core.handlers; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.core.IRepositoryCallback; +import org.eclipse.flux.core.sync.ISystemSync; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; @@ -9,7 +9,7 @@ public class ProjectRequestHandler extends AbstractMsgHandler { - public ProjectRequestHandler(IRepositoryCallback repositoryCallback) { + public ProjectRequestHandler(ISystemSync repositoryCallback) { super(repositoryCallback, GET_PROJECT_REQUEST); } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java index f0e6cb2..50eb900 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectResponseHandler.java @@ -1,7 +1,7 @@ package org.eclipse.flux.core.handlers; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.core.IRepositoryCallback; +import org.eclipse.flux.core.sync.ISystemSync; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; @@ -10,7 +10,7 @@ public class ProjectResponseHandler extends AbstractMsgHandler { private int callbackID; - public ProjectResponseHandler(IRepositoryCallback repositoryCallback, int callbackID) { + public ProjectResponseHandler(ISystemSync repositoryCallback, int callbackID) { super(repositoryCallback, GET_PROJECT_RESPONSE); this.callbackID = callbackID; } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java index ab7380a..0b66c63 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ProjectsResponseHandler.java @@ -1,14 +1,14 @@ package org.eclipse.flux.core.handlers; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.core.IRepositoryCallback; +import org.eclipse.flux.core.sync.ISystemSync; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONArray; import org.json.JSONObject; public class ProjectsResponseHandler extends AbstractMsgHandler { - public ProjectsResponseHandler(IRepositoryCallback repositoryCallback) { + public ProjectsResponseHandler(ISystemSync repositoryCallback) { super(repositoryCallback, GET_PROJECTS_REQUEST); } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java index fb38ec6..450d4b2 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceChangedHandler.java @@ -1,7 +1,9 @@ package org.eclipse.flux.core.handlers; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.core.IRepositoryCallback; +import org.eclipse.flux.core.sync.ISystemSync; +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventType; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.eclipse.flux.watcher.core.spi.Project; @@ -10,7 +12,7 @@ public class ResourceChangedHandler extends AbstractMsgHandler { private int callbackId; - public ResourceChangedHandler(IRepositoryCallback repositoryCallback, int callbackID) { + public ResourceChangedHandler(ISystemSync repositoryCallback, int callbackID) { super(repositoryCallback, RESOURCE_CHANGED); this.callbackId = callbackID; } @@ -37,7 +39,8 @@ protected void onMessage(String type, JSONObject message) throws Exception { content.put(MessageConstants.TIMESTAMP, resourceTimestamp); content.put(MessageConstants.HASH, resourceHash); repositoryCallback.sendMessage(GET_RESOURCE_REQUEST, content); - repositoryCallback.notifyResourceChanged(localResource, project); + RepositoryEvent event = new RepositoryEvent(RepositoryEventType.PROJECT_RESOURCE_MODIFIED, localResource, project); + repositoryCallback.onEvent(event); } } } \ No newline at end of file diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java index e8921cf..3b5c8c3 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceCreatedHandler.java @@ -1,7 +1,7 @@ package org.eclipse.flux.core.handlers; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.core.IRepositoryCallback; +import org.eclipse.flux.core.sync.ISystemSync; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; @@ -9,7 +9,7 @@ public class ResourceCreatedHandler extends AbstractMsgHandler { private int callbackID; - public ResourceCreatedHandler(IRepositoryCallback repositoryCallback, int callbackID) { + public ResourceCreatedHandler(ISystemSync repositoryCallback, int callbackID) { super(repositoryCallback, RESOURCE_CREATED); this.callbackID = callbackID; } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java index 5da7f84..d6a150e 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceDeletedHandler.java @@ -1,14 +1,14 @@ package org.eclipse.flux.core.handlers; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.core.IRepositoryCallback; +import org.eclipse.flux.core.sync.ISystemSync; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; public class ResourceDeletedHandler extends AbstractMsgHandler { - public ResourceDeletedHandler(IRepositoryCallback repositoryCallback) { + public ResourceDeletedHandler(ISystemSync repositoryCallback) { super(repositoryCallback, RESOURCE_DELETED); } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java index e2a4147..ac866d9 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceRequestHandler.java @@ -1,7 +1,7 @@ package org.eclipse.flux.core.handlers; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.core.IRepositoryCallback; +import org.eclipse.flux.core.sync.ISystemSync; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.eclipse.flux.watcher.core.spi.Project; @@ -9,7 +9,7 @@ import org.json.JSONObject; public class ResourceRequestHandler extends AbstractMsgHandler { - public ResourceRequestHandler(IRepositoryCallback repositoryCallback) { + public ResourceRequestHandler(ISystemSync repositoryCallback) { super(repositoryCallback, GET_RESOURCE_REQUEST); } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java index 05e0e60..d5bc7c6 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/handlers/ResourceResponseHandler.java @@ -2,8 +2,10 @@ import org.eclipse.core.resources.IResource; import org.eclipse.flux.client.MessageConstants; -import org.eclipse.flux.core.IRepositoryCallback; +import org.eclipse.flux.core.sync.ISystemSync; import org.eclipse.flux.core.util.Utils; +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventType; import org.eclipse.flux.watcher.core.Resource; import org.eclipse.flux.watcher.core.Resource.ResourceType; import org.eclipse.flux.watcher.core.spi.Project; @@ -12,7 +14,7 @@ public class ResourceResponseHandler extends AbstractMsgHandler { private int callbackID; - public ResourceResponseHandler(IRepositoryCallback repositoryCallback, int callbackID) { + public ResourceResponseHandler(ISystemSync repositoryCallback, int callbackID) { super(repositoryCallback, GET_RESOURCE_RESPONSE); this.callbackID = callbackID; } @@ -54,8 +56,10 @@ protected void onMessage(String type, JSONObject message) throws Exception { content.put(MessageConstants.HASH, resourceHash); content.put(MessageConstants.TYPE, "file"); repositoryCallback.sendMessage(RESOURCE_STORED, content); - if(localResource != null) - repositoryCallback.notifyResourceChanged(localResource, project); + if(localResource != null){ + RepositoryEvent event = new RepositoryEvent(RepositoryEventType.PROJECT_RESOURCE_MODIFIED, localResource, project); + repositoryCallback.onEvent(event); + } } } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/sync/ISystemSync.java similarity index 60% rename from org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java rename to org.eclipse.flux.core/src/org/eclipse/flux/core/sync/ISystemSync.java index cc3b5e3..f32bc58 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/IRepositoryCallback.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/sync/ISystemSync.java @@ -1,14 +1,14 @@ -package org.eclipse.flux.core; +package org.eclipse.flux.core.sync; import java.util.Set; -import org.eclipse.flux.watcher.core.Resource; +import org.eclipse.flux.watcher.core.RepositoryListener; import org.eclipse.flux.watcher.core.spi.Project; import org.json.JSONObject; -public interface IRepositoryCallback { - void notifyResourceChanged(Resource resource, Project project); +public interface ISystemSync extends RepositoryListener { void sendMessage(String messageType, JSONObject content) throws Exception; Project getWatcherProject(String projectName); Set getSynchronizedProjects(); + String getUsername(); } \ No newline at end of file From a029c7337621c9f7945922a80e1f62bbc4fc604e Mon Sep 17 00:00:00 2001 From: Fjodor Vershinin Date: Wed, 24 Aug 2016 08:51:25 +0300 Subject: [PATCH 34/34] Added to git: FluxSystemSync.java and resource listeners Signed-off-by: Fjodor Vershinin --- .../eclipse/flux/core/RepositoryAdapter.java | 15 +- .../listeners/ResourceCreatedListener.java | 31 ++++ .../listeners/ResourceDeletedListener.java | 30 +++ .../listeners/ResourceModifiedListener.java | 31 ++++ .../flux/core/sync/FluxSystemSync.java | 173 ++++++++++++++++++ 5 files changed, 267 insertions(+), 13 deletions(-) create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceCreatedListener.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceDeletedListener.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceModifiedListener.java create mode 100644 org.eclipse.flux.core/src/org/eclipse/flux/core/sync/FluxSystemSync.java diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java index 6d46d95..70fdc06 100644 --- a/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/RepositoryAdapter.java @@ -21,21 +21,18 @@ import org.eclipse.core.resources.IResourceDelta; import org.eclipse.flux.client.MessageConnector; import org.eclipse.flux.core.sync.FluxSystemSync; -import org.eclipse.flux.core.util.Utils; -import org.eclipse.flux.watcher.core.RepositoryEvent; -import org.eclipse.flux.watcher.core.RepositoryListener; import org.eclipse.flux.watcher.core.spi.Project; /** * @author Martin Lippert */ -public class RepositoryAdapter implements RepositoryListener{ +public class RepositoryAdapter{ private FluxSystemSync systemSync; private Collection repositoryListeners; public RepositoryAdapter(MessageConnector messageConnector, String user) { - this.systemSync = new FluxSystemSync(messageConnector, user, this); + this.systemSync = new FluxSystemSync(messageConnector, user); this.repositoryListeners = new ConcurrentLinkedDeque<>(); } @@ -115,12 +112,4 @@ protected void notifyResourceChanged(IResource resource) { public void dispose() { systemSync.dispose(); } - - @Override - public void onEvent(RepositoryEvent event) throws Exception { - String projectName = event.project().id(); - String path = event.resource().path(); - notifyResourceChanged(Utils.getResourceByPath(projectName, path)); - } - } diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceCreatedListener.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceCreatedListener.java new file mode 100644 index 0000000..1fbf5ab --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceCreatedListener.java @@ -0,0 +1,31 @@ +package org.eclipse.flux.core.listeners; + +import org.eclipse.flux.client.IMessageHandler; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.core.sync.ISystemSync; +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventType; +import org.eclipse.flux.watcher.core.RepositoryEventTypes; +import org.eclipse.flux.watcher.core.RepositoryListener; +import org.json.JSONObject; + +@RepositoryEventTypes(RepositoryEventType.PROJECT_RESOURCE_CREATED) +public class ResourceCreatedListener implements RepositoryListener { + private ISystemSync repositoryCallback; + + public ResourceCreatedListener(ISystemSync repositoryCallback){ + this.repositoryCallback = repositoryCallback; + } + @Override + public void onEvent(RepositoryEvent event) throws Exception { + JSONObject message = new JSONObject(); + message.put(MessageConstants.USERNAME, repositoryCallback.getUsername()); + message.put(MessageConstants.PROJECT_NAME, event.project().id()); + message.put(MessageConstants.RESOURCE, event.resource().path()); + message.put(MessageConstants.TIMESTAMP, event.resource().timestamp()); + message.put(MessageConstants.HASH, event.resource().hash()); + message.put(MessageConstants.TYPE, event.resource().type().name().toLowerCase()); + repositoryCallback.sendMessage(IMessageHandler.RESOURCE_CREATED, message); + repositoryCallback.sendMessage(IMessageHandler.RESOURCE_STORED, message); + } +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceDeletedListener.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceDeletedListener.java new file mode 100644 index 0000000..d479220 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceDeletedListener.java @@ -0,0 +1,30 @@ +package org.eclipse.flux.core.listeners; + +import org.eclipse.flux.client.IMessageHandler; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.core.sync.ISystemSync; +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventType; +import org.eclipse.flux.watcher.core.RepositoryEventTypes; +import org.eclipse.flux.watcher.core.RepositoryListener; +import org.json.JSONObject; + +@RepositoryEventTypes(RepositoryEventType.PROJECT_RESOURCE_DELETED) +public class ResourceDeletedListener implements RepositoryListener { + private ISystemSync repositoryCallback; + + public ResourceDeletedListener(ISystemSync repositoryCallback){ + this.repositoryCallback = repositoryCallback; + } + + @Override + public void onEvent(RepositoryEvent event) throws Exception { + JSONObject message = new JSONObject(); + message.put(MessageConstants.USERNAME, repositoryCallback.getUsername()); + message.put(MessageConstants.PROJECT_NAME, event.project().id()); + message.put(MessageConstants.RESOURCE, event.resource().path()); + message.put(MessageConstants.TIMESTAMP, event.resource().timestamp()); + repositoryCallback.sendMessage(IMessageHandler.RESOURCE_DELETED, message); + } + +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceModifiedListener.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceModifiedListener.java new file mode 100644 index 0000000..b29bbbd --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/listeners/ResourceModifiedListener.java @@ -0,0 +1,31 @@ +package org.eclipse.flux.core.listeners; + +import org.eclipse.flux.client.IMessageHandler; +import org.eclipse.flux.client.MessageConstants; +import org.eclipse.flux.core.sync.ISystemSync; +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventType; +import org.eclipse.flux.watcher.core.RepositoryEventTypes; +import org.eclipse.flux.watcher.core.RepositoryListener; +import org.json.JSONObject; + +@RepositoryEventTypes(RepositoryEventType.PROJECT_RESOURCE_MODIFIED) +public class ResourceModifiedListener implements RepositoryListener { + private ISystemSync repositoryCallback; + + public ResourceModifiedListener(ISystemSync repositoryCallback){ + this.repositoryCallback = repositoryCallback; + } + + @Override + public void onEvent(RepositoryEvent event) throws Exception { + JSONObject message = new JSONObject(); + message.put(MessageConstants.USERNAME, repositoryCallback.getUsername()); + message.put(MessageConstants.PROJECT_NAME, event.project().id()); + message.put(MessageConstants.RESOURCE, event.resource().path()); + message.put(MessageConstants.TIMESTAMP, event.resource().timestamp()); + message.put(MessageConstants.HASH, event.resource().hash()); + repositoryCallback.sendMessage(IMessageHandler.RESOURCE_CHANGED, message); + repositoryCallback.sendMessage(IMessageHandler.RESOURCE_STORED, message); + } +} diff --git a/org.eclipse.flux.core/src/org/eclipse/flux/core/sync/FluxSystemSync.java b/org.eclipse.flux.core/src/org/eclipse/flux/core/sync/FluxSystemSync.java new file mode 100644 index 0000000..0f0cab0 --- /dev/null +++ b/org.eclipse.flux.core/src/org/eclipse/flux/core/sync/FluxSystemSync.java @@ -0,0 +1,173 @@ +package org.eclipse.flux.core.sync; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Objects; +import java.util.Set; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.flux.client.IMessageHandler; +import org.eclipse.flux.client.MessageConnector; +import org.eclipse.flux.core.handlers.MetadataRequestHandler; +import org.eclipse.flux.core.handlers.ProjectRequestHandler; +import org.eclipse.flux.core.handlers.ProjectResponseHandler; +import org.eclipse.flux.core.handlers.ProjectsResponseHandler; +import org.eclipse.flux.core.handlers.ResourceChangedHandler; +import org.eclipse.flux.core.handlers.ResourceCreatedHandler; +import org.eclipse.flux.core.handlers.ResourceDeletedHandler; +import org.eclipse.flux.core.handlers.ResourceRequestHandler; +import org.eclipse.flux.core.handlers.ResourceResponseHandler; +import org.eclipse.flux.core.listeners.ResourceCreatedListener; +import org.eclipse.flux.core.listeners.ResourceDeletedListener; +import org.eclipse.flux.core.listeners.ResourceModifiedListener; +import org.eclipse.flux.core.util.JSONUtils; +import org.eclipse.flux.watcher.core.Repository; +import org.eclipse.flux.watcher.core.RepositoryEvent; +import org.eclipse.flux.watcher.core.RepositoryEventBus; +import org.eclipse.flux.watcher.core.RepositoryModule; +import org.eclipse.flux.watcher.core.spi.Project; +import org.eclipse.flux.watcher.fs.JDKProjectModule; +import org.json.JSONArray; +import org.json.JSONObject; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +public class FluxSystemSync implements ISystemSync { + private static int GET_PROJECT_CALLBACK = "Repository - getProjectCallback".hashCode(); + private static int GET_RESOURCE_CALLBACK = "Repository - getResourceCallback".hashCode(); + + private String username; + private Repository repository; + private RepositoryEventBus repositoryEventBus; + private MessageConnector messageConnector; + private Collection messageHandlers; + + public FluxSystemSync(MessageConnector messageConnector, String user) { + this.messageConnector = messageConnector; + this.username = user; + this.messageHandlers = new ArrayList<>(); + Injector injector = Guice.createInjector(new RepositoryModule(), new JDKProjectModule()); + this.repository = injector.getInstance(Repository.class); + this.repositoryEventBus = this.repository.repositoryEventBus(); + + this.repositoryEventBus.addRepositoryListener(new ResourceCreatedListener(this)); + this.repositoryEventBus.addRepositoryListener(new ResourceModifiedListener(this)); + this.repositoryEventBus.addRepositoryListener(new ResourceDeletedListener(this)); + + addMessageHandler(new MetadataRequestHandler(this)); + addMessageHandler(new ProjectsResponseHandler(this)); + addMessageHandler(new ProjectRequestHandler(this)); + addMessageHandler(new ProjectResponseHandler(this, GET_PROJECT_CALLBACK)); + addMessageHandler(new ResourceRequestHandler(this)); + addMessageHandler(new ResourceResponseHandler(this, GET_RESOURCE_CALLBACK)); + addMessageHandler(new ResourceCreatedHandler(this, GET_RESOURCE_CALLBACK)); + addMessageHandler(new ResourceChangedHandler(this, GET_RESOURCE_CALLBACK)); + addMessageHandler(new ResourceDeletedHandler(this)); + } + + + public Set getSynchronizedProjects() { + return this.repository.getSynchronizedProjects(); + } + + public void addProject(String name, String path) { + this.repository.addProject(name, path); + sendProjectConnectedMessage(name); + syncConnectedProject(name); + } + + public void removeProject(String name) { + this.repository.removeProject(name); + try { + JSONObject message = new JSONObject(); + message.put("username", this.username); + message.put("project", name); + messageConnector.send("projectDisconnected", message); + } catch (Exception e) { + e.printStackTrace(); + } + } + + + public void sendMetadataUpdate(IResource resource) { + try { + String project = resource.getProject().getName(); + String resourcePath = resource.getProjectRelativePath().toString(); + + JSONObject message = new JSONObject(); + message.put("username", this.username); + message.put("project", project); + message.put("resource", resourcePath); + message.put("type", "marker"); + + IMarker[] markers = resource.findMarkers(null, true, IResource.DEPTH_INFINITE); + JSONArray content = JSONUtils.toJSON(markers); + message.put("metadata", content); + messageConnector.send(IMessageHandler.METADATA_CHANGED, message); + } catch (Exception e) { + e.printStackTrace(); + } + } + + + + public boolean isProjectConnected(String projectName) { + return Objects.nonNull(this.getWatcherProject(projectName)); + } + + public String getUsername() { + return this.username; + } + + private void syncConnectedProject(String projectName){ + try{ + JSONObject message=new JSONObject(); + message.put("username",this.username); + message.put("project",projectName); + message.put("includeDeleted",true); + message.put("callback_id", GET_PROJECT_CALLBACK); + messageConnector.send("getProjectRequest",message); + }catch(Exception e){ + e.printStackTrace(); + } + } + + private void sendProjectConnectedMessage(String projectName){ + try{ + JSONObject message=new JSONObject(); + message.put("username",this.username); + message.put("project",projectName); + messageConnector.send("projectConnected",message); + }catch(Exception e){ + e.printStackTrace(); + } + } + + public void dispose() { + for(IMessageHandler messageHandler : messageHandlers){ + messageConnector.removeMessageHandler(messageHandler); + } + } + + private void addMessageHandler(IMessageHandler messageHandler){ + this.messageConnector.addMessageHandler(messageHandler); + this.messageHandlers.add(messageHandler); + } + + @Override + public void onEvent(RepositoryEvent event) throws Exception { + + } + + @Override + public void sendMessage(String messageType, JSONObject content) throws Exception { + this.messageConnector.send(messageType, content); + } + + @Override + public Project getWatcherProject(String projectName) { + return this.repository.getProject(projectName); + } +} \ No newline at end of file