/* * Copyright (C) 2017 The Android Open Source Project * * 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.googlecode.android_scripting.jsonrpc; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Collection; import java.util.HashMap; import java.util.Map; import com.googlecode.android_scripting.facade.FacadeManager; import com.googlecode.android_scripting.Log; import com.googlecode.android_scripting.rpc.MethodDescriptor; public abstract class RpcReceiverManager { private final Map, RpcReceiver> mReceivers; /** * A map of strings to known RPCs. */ private final Map mKnownRpcs = new HashMap(); public RpcReceiverManager(Collection> classList) { mReceivers = new HashMap, RpcReceiver>(); for (Class receiverClass : classList) { mReceivers.put(receiverClass, null); Collection methodList = MethodDescriptor.collectFrom(receiverClass); for (MethodDescriptor m : methodList) { if (mKnownRpcs.containsKey(m.getName())) { // We already know an RPC of the same name. We don't catch this anywhere because // this is a programming error. throw new RuntimeException("An RPC with the name " + m.getName() + " is already known."); } mKnownRpcs.put(m.getName(), m); } } } public Collection> getRpcReceiverClasses() { return mReceivers.keySet(); } private RpcReceiver get(Class clazz) { RpcReceiver object = mReceivers.get(clazz); if (object != null) { return object; } Constructor constructor; try { constructor = clazz.getConstructor(FacadeManager.class); object = constructor.newInstance(this); mReceivers.put(clazz, object); } catch (Exception e) { Log.e(e); } return object; } public T getReceiver(Class clazz) { RpcReceiver receiver = get(clazz); return clazz.cast(receiver); } public MethodDescriptor getMethodDescriptor(String methodName) { return mKnownRpcs.get(methodName); } public Object invoke(Class clazz, Method method, Object[] args) throws Exception { RpcReceiver object = get(clazz); return method.invoke(object, args); } public void shutdown() { for (RpcReceiver receiver : mReceivers.values()) { try { if (receiver != null) { receiver.shutdown(); } } catch (Exception e) { Log.e("Failed to shut down an RpcReceiver", e); } } } }