Initial commit 🎉

fbshipit-source-id: b6fc29740c6875d2e78953b8a7123890a67930f2
Co-authored-by: Sebastian McKenzie <sebmck@fb.com>
Co-authored-by: John Knox <jknox@fb.com>
Co-authored-by: Emil Sjölander <emilsj@fb.com>
Co-authored-by: Pritesh Nandgaonkar <prit91@fb.com>
This commit is contained in:
Daniel Büchele
2018-04-13 08:38:06 -07:00
committed by Daniel Buchele
commit fbbf8cf16b
659 changed files with 87130 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.sonar.core;
public abstract class ErrorReportingRunnable implements Runnable {
private final SonarConnection mConnection;
public ErrorReportingRunnable(SonarConnection connection) {
mConnection = connection;
}
@Override
public final void run() {
try {
runOrThrow();
} catch (Exception e) {
if (mConnection != null) {
mConnection.reportError(e);
}
} finally {
doFinally();
}
}
protected void doFinally() {}
protected abstract void runOrThrow() throws Exception;
}

View File

@@ -0,0 +1,164 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.sonar.core;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class SonarArray {
final JSONArray mJson;
SonarArray(JSONArray json) {
mJson = (json != null ? json : new JSONArray());
}
SonarArray(String json) {
try {
mJson = new JSONArray(json);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
public SonarDynamic getDynamic(int index) {
return new SonarDynamic(mJson.opt(index));
}
public String getString(int index) {
return mJson.optString(index);
}
public int getInt(int index) {
return mJson.optInt(index);
}
public long getLong(int index) {
return mJson.optLong(index);
}
public float getFloat(int index) {
return (float) mJson.optDouble(index);
}
public double getDouble(int index) {
return mJson.optDouble(index);
}
public boolean getBoolean(int index) {
return mJson.optBoolean(index);
}
public SonarObject getObject(int index) {
final Object o = mJson.opt(index);
return new SonarObject((JSONObject) o);
}
public SonarArray getArray(int index) {
final Object o = mJson.opt(index);
return new SonarArray((JSONArray) o);
}
public int length() {
return mJson.length();
}
public List<String> toStringList() {
final int length = length();
final List<String> list = new ArrayList<>(length);
for (int i = 0; i < length; i++) {
list.add(getString(i));
}
return list;
}
public String toJsonString() {
return toString();
}
@Override
public String toString() {
return mJson.toString();
}
@Override
public boolean equals(Object o) {
return mJson.toString().equals(o.toString());
}
@Override
public int hashCode() {
return mJson.hashCode();
}
public static class Builder {
private final JSONArray mJson;
public Builder() {
mJson = new JSONArray();
}
public Builder put(String s) {
mJson.put(s);
return this;
}
public Builder put(Integer i) {
mJson.put(i);
return this;
}
public Builder put(Long l) {
mJson.put(l);
return this;
}
public Builder put(Float f) {
mJson.put(Float.isNaN(f) ? null : f);
return this;
}
public Builder put(Double d) {
mJson.put(Double.isNaN(d) ? null : d);
return this;
}
public Builder put(Boolean b) {
mJson.put(b);
return this;
}
public Builder put(SonarValue v) {
return put(v.toSonarObject());
}
public Builder put(SonarArray a) {
mJson.put(a == null ? null : a.mJson);
return this;
}
public Builder put(SonarArray.Builder b) {
return put(b.build());
}
public Builder put(SonarObject o) {
mJson.put(o == null ? null : o.mJson);
return this;
}
public Builder put(SonarObject.Builder b) {
return put(b.build());
}
public SonarArray build() {
return new SonarArray(mJson);
}
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.sonar.core;
public interface SonarClient {
void addPlugin(SonarPlugin plugin);
<T extends SonarPlugin> T getPlugin(String id);
void removePlugin(SonarPlugin plugin);
void start();
void stop();
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.sonar.core;
/**
* A connection between a SonarPlugin and the desktop Sonar application. Register request handlers
* to respond to calls made by the desktop application or directly send messages to the desktop
* application.
*/
public interface SonarConnection {
/**
* Call a remote method on the Sonar desktop application, passing an optional JSON object as a
* parameter.
*/
void send(String method, SonarObject params);
/**
* Call a remote method on the Sonar desktop application, passing an optional JSON array as a
* parameter.
*/
void send(String method, SonarArray params);
/** Report client error */
void reportError(Throwable throwable);
/**
* Register a receiver for a remote method call issued by the Sonar desktop application. The
* SonarReceiver is passed a responder to respond back to the desktop application.
*/
void receive(String method, SonarReceiver receiver);
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.sonar.core;
import javax.annotation.Nullable;
import org.json.JSONArray;
import org.json.JSONObject;
public class SonarDynamic {
private final Object mObject;
public SonarDynamic(Object object) {
mObject = object;
}
public @Nullable String asString() {
if (mObject == null) {
return null;
}
return mObject.toString();
}
public int asInt() {
if (mObject == null) {
return 0;
}
if (mObject instanceof Integer) {
return (Integer) mObject;
}
if (mObject instanceof Long) {
return ((Long) mObject).intValue();
}
if (mObject instanceof Float) {
return ((Float) mObject).intValue();
}
if (mObject instanceof Double) {
return ((Double) mObject).intValue();
}
return 0;
}
public long asLong() {
if (mObject == null) {
return 0;
}
if (mObject instanceof Integer) {
return (Integer) mObject;
}
if (mObject instanceof Long) {
return (Long) mObject;
}
if (mObject instanceof Float) {
return ((Float) mObject).longValue();
}
if (mObject instanceof Double) {
return ((Double) mObject).longValue();
}
return 0;
}
public float asFloat() {
if (mObject == null) {
return 0;
}
if (mObject instanceof Integer) {
return (Integer) mObject;
}
if (mObject instanceof Long) {
return (Long) mObject;
}
if (mObject instanceof Float) {
return (Float) mObject;
}
if (mObject instanceof Double) {
return ((Double) mObject).floatValue();
}
return 0;
}
public double asDouble() {
if (mObject == null) {
return 0;
}
if (mObject instanceof Integer) {
return (Integer) mObject;
}
if (mObject instanceof Long) {
return (Long) mObject;
}
if (mObject instanceof Float) {
return (Float) mObject;
}
if (mObject instanceof Double) {
return (Double) mObject;
}
return 0;
}
public boolean asBoolean() {
if (mObject == null) {
return false;
}
return (Boolean) mObject;
}
public SonarObject asObject() {
if (mObject instanceof JSONObject) {
return new SonarObject((JSONObject) mObject);
}
return (SonarObject) mObject;
}
public SonarArray asArray() {
if (mObject instanceof JSONArray) {
return new SonarArray((JSONArray) mObject);
}
return (SonarArray) mObject;
}
}

View File

@@ -0,0 +1,221 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.sonar.core;
import java.util.Arrays;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class SonarObject {
final JSONObject mJson;
public SonarObject(JSONObject json) {
mJson = (json != null ? json : new JSONObject());
}
public SonarObject(String json) {
try {
mJson = new JSONObject(json);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
public SonarDynamic getDynamic(String name) {
return new SonarDynamic(mJson.opt(name));
}
public String getString(String name) {
if (mJson.isNull(name)) {
return null;
}
return mJson.optString(name);
}
public int getInt(String name) {
return mJson.optInt(name);
}
public long getLong(String name) {
return mJson.optLong(name);
}
public float getFloat(String name) {
return (float) mJson.optDouble(name);
}
public double getDouble(String name) {
return mJson.optDouble(name);
}
public boolean getBoolean(String name) {
return mJson.optBoolean(name);
}
public SonarObject getObject(String name) {
final Object o = mJson.opt(name);
return new SonarObject((JSONObject) o);
}
public SonarArray getArray(String name) {
final Object o = mJson.opt(name);
return new SonarArray((JSONArray) o);
}
public boolean contains(String name) {
return mJson.has(name);
}
public String toJsonString() {
return toString();
}
@Override
public String toString() {
return mJson.toString();
}
@Override
public boolean equals(Object o) {
return mJson.toString().equals(o.toString());
}
@Override
public int hashCode() {
return mJson.hashCode();
}
public static class Builder {
private final JSONObject mJson;
public Builder() {
mJson = new JSONObject();
}
public Builder put(String name, Object obj) {
if (obj == null) {
return put(name, (String) null);
} else if (obj instanceof Integer) {
return put(name, (Integer) obj);
} else if (obj instanceof Long) {
return put(name, (Long) obj);
} else if (obj instanceof Float) {
return put(name, (Float) obj);
} else if (obj instanceof Double) {
return put(name, (Double) obj);
} else if (obj instanceof String) {
return put(name, (String) obj);
} else if (obj instanceof Boolean) {
return put(name, (Boolean) obj);
} else if (obj instanceof Object[]) {
return put(name, Arrays.deepToString((Object[]) obj));
} else if (obj instanceof SonarObject) {
return put(name, (SonarObject) obj);
} else if (obj instanceof SonarObject.Builder) {
return put(name, (SonarObject.Builder) obj);
} else if (obj instanceof SonarArray) {
return put(name, (SonarArray) obj);
} else if (obj instanceof SonarArray.Builder) {
return put(name, (SonarArray.Builder) obj);
} else if (obj instanceof SonarValue) {
return put(name, ((SonarValue) obj).toSonarObject());
} else {
return put(name, obj.toString());
}
}
public Builder put(String name, String s) {
try {
mJson.put(name, s);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return this;
}
public Builder put(String name, Integer i) {
try {
mJson.put(name, i);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return this;
}
public Builder put(String name, Long l) {
try {
mJson.put(name, l);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return this;
}
public Builder put(String name, Float f) {
try {
mJson.put(name, Float.isNaN(f) ? null : f);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return this;
}
public Builder put(String name, Double d) {
try {
mJson.put(name, Double.isNaN(d) ? null : d);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return this;
}
public Builder put(String name, Boolean b) {
try {
mJson.put(name, b);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return this;
}
public Builder put(String name, SonarValue v) {
return put(name, v.toSonarObject());
}
public Builder put(String name, SonarArray a) {
try {
mJson.put(name, a == null ? null : a.mJson);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return this;
}
public Builder put(String name, SonarArray.Builder b) {
return put(name, b.build());
}
public Builder put(String name, SonarObject o) {
try {
mJson.put(name, o == null ? null : o.mJson);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return this;
}
public Builder put(String name, SonarObject.Builder b) {
return put(name, b.build());
}
public SonarObject build() {
return new SonarObject(mJson);
}
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.sonar.core;
/**
* A SonarPlugin is an object which exposes an API to the Desktop Sonar application. When a
* connection is established the plugin is given a SonarConnection on which it can register request
* handlers and send messages. When the SonarConnection is invalid onDisconnect is called. onConnect
* may be called again on the same plugin object if Sonar re-connects, this will provide a new
* SonarConnection, do not attempt to re-use the previous connection.
*/
public interface SonarPlugin {
/**
* @return The id of this plugin. This is the namespace which Sonar desktop plugins will call
* methods on to route them to your plugin. This should match the id specified in your React
* plugin.
*/
String getId();
/**
* Called when a connection has been established. The connection passed to this method is valid
* until {@link SonarPlugin#onDisconnect()} is called.
*/
void onConnect(SonarConnection connection) throws Exception;
/**
* Called when the connection passed to {@link SonarPlugin#onConnect(SonarConnection)} is no
* longer valid. Do not try to use the connection in or after this method has been called.
*/
void onDisconnect() throws Exception;
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.sonar.core;
/**
* A receiver of a remote method call issued by the Sonar desktop application. If the given
* responder is present it means the Sonar desktop application is expecting a response.
*/
public interface SonarReceiver {
/**
* Reciver for a request sent from the Sonar desktop client.
*
* @param params Optional set of parameters sent with the request.
* @param responder Optional responder for request. Some requests don't warrant a response
* through. In this case the request should be made from the desktop using send() instead of
* call().
*/
void onReceive(SonarObject params, SonarResponder responder) throws Exception;
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.sonar.core;
/**
* SonarResponder is used to asyncronously response to a messaged recieved from the Sonar desktop
* app. The Sonar Responder will automatically wrap the response in an approriate object depending
* on if it is an error or not.
*/
public interface SonarResponder {
/** Deliver a successful response to the Sonar desktop app. */
void success(SonarObject response);
/** Deliver a successful response to the Sonar desktop app. */
void success(SonarArray response);
/** Deliver a successful response to the Sonar desktop app. */
void success();
/** Inform the Sonar desktop app of an error in handling the request. */
void error(SonarObject response);
}

View File

@@ -0,0 +1,12 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.sonar.core;
public interface SonarValue {
SonarObject toSonarObject();
}