/*
* Copyright 2015-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.intellij.ideabuck.ws;
import com.facebook.buck.intellij.ideabuck.config.BuckModule;
import com.facebook.buck.intellij.ideabuck.config.BuckWSServerPortUtils;
import com.facebook.buck.intellij.ideabuck.ws.buckevents.BuckEventsHandlerInterface;
import com.google.common.annotations.VisibleForTesting;
import com.intellij.execution.ExecutionException;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import java.io.IOException;
import java.net.URI;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jetty.websocket.client.WebSocketClient;
public class BuckClient {
private static final Logger LOG = Logger.getInstance(BuckClient.class);
private BuckSocket mBuckSocket;
private WebSocketClient mWSClient;
private AtomicBoolean mConnecting;
private Project mProject;
BuckClient(final BuckEventsHandlerInterface buckEventHandler, Project project) {
mWSClient = new WebSocketClient();
mProject = project;
mConnecting = new AtomicBoolean(false);
mBuckSocket =
new BuckSocket(
new BuckEventsHandlerInterface() {
@Override
public void onConnect() {
buckEventHandler.onConnect();
mConnecting.set(false);
}
@Override
public void onDisconnect() {
buckEventHandler.onDisconnect();
}
@Override
public void onMessage(String message) {
buckEventHandler.onMessage(message);
}
});
}
public void connect() {
if (isConnected() || mConnecting.get()) {
return;
}
mConnecting.set(true);
ApplicationManager.getApplication()
.executeOnPooledThread(
new Runnable() {
@Override
public void run() {
try {
int port = BuckWSServerPortUtils.getPort(mProject.getBasePath());
// Connect to WebServer
connectToWebServer("localhost", port);
} catch (NumberFormatException e) {
LOG.error(e);
} catch (ExecutionException e) {
LOG.error(e);
} catch (IOException e) {
LOG.error(e);
} catch (RuntimeException e) {
if (!mProject.isDisposed()) {
BuckModule buckModule = mProject.getComponent(BuckModule.class);
buckModule.attachIfDetached();
buckModule.getBuckEventsConsumer().consumeConsoleEvent(e.toString());
}
}
}
});
}
@VisibleForTesting
protected void setBuckSocket(BuckSocket buckSocket) {
mBuckSocket = buckSocket;
}
private void connectToWebServer(String host, int port) {
try {
mWSClient.start();
URI uri = new URI("ws://" + host + ":" + port + "/ws/build");
mWSClient.connect(mBuckSocket, uri);
} catch (Throwable t) {
LOG.error(t);
mConnecting.set(false);
}
}
public boolean isConnected() {
return mBuckSocket.isConnected();
}
public void disconnectWithRetry() {
disconnect(true);
}
public void disconnectWithoutRetry() {
disconnect(false);
}
private void disconnect(final boolean retry) {
ApplicationManager.getApplication()
.executeOnPooledThread(
new Runnable() {
@Override
public void run() {
try {
mWSClient.stop();
if (retry) {
connect();
} else {
mWSClient.destroy();
BuckClientManager.removeClient(mProject);
}
} catch (InterruptedException e) {
LOG.error("Could not disconnect from buck. " + e);
} catch (Throwable t) {
LOG.error("Could not disconnect from buck. " + t.getMessage());
}
}
});
}
}