/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.stetho.inspector.runtime;
import android.content.Context;
import android.support.annotation.Nullable;
import com.facebook.stetho.common.LogUtil;
import com.facebook.stetho.inspector.console.RuntimeRepl;
import com.facebook.stetho.inspector.console.RuntimeReplFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Attempts to locate stetho-js-rhino in the classpath and use it if available. Otherwise falls
* back to a no-op version which informs folks that they can include stetho-js-rhino for more
* advanced functionality.
* <p />
* Eventually we should develop a kind of service locator somehow to make this more discoverable
* and generalized. For now with only one official implementation however it seems like overkill.
*/
public class RhinoDetectingRuntimeReplFactory implements RuntimeReplFactory {
private final Context mContext;
private boolean mSearchedForRhinoJs;
private RuntimeReplFactory mRhinoReplFactory;
private RuntimeException mRhinoJsUnexpectedError;
public RhinoDetectingRuntimeReplFactory(Context context) {
mContext = context;
}
@Override
public RuntimeRepl newInstance() {
if (!mSearchedForRhinoJs) {
mSearchedForRhinoJs = true;
try {
mRhinoReplFactory = findRhinoReplFactory(mContext);
} catch (RuntimeException e) {
mRhinoJsUnexpectedError = e;
}
}
if (mRhinoReplFactory != null) {
return mRhinoReplFactory.newInstance();
} else {
return new RuntimeRepl() {
@Override
public Object evaluate(String expression) throws Exception {
if (mRhinoJsUnexpectedError != null) {
return "stetho-js-rhino threw: " + mRhinoJsUnexpectedError.toString();
} else {
return "Not supported without stetho-js-rhino dependency";
}
}
};
}
}
@Nullable
private static RuntimeReplFactory findRhinoReplFactory(Context context) throws RuntimeException {
try {
Class<?> jsRuntimeReplFactory =
Class.forName("com.facebook.stetho.rhino.JsRuntimeReplFactoryBuilder");
Method defaultFactoryMethod =
jsRuntimeReplFactory.getDeclaredMethod("defaultFactory", Context.class);
return (RuntimeReplFactory) defaultFactoryMethod.invoke(null, context);
} catch (ClassNotFoundException e) {
LogUtil.i("Error finding stetho-js-rhino, cannot enable console evaluation!");
return null;
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}