Home | History | Annotate | Download | only in jsonrpc
      1 /*
      2  * Copyright (C) 2016 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package com.googlecode.android_scripting.jsonrpc;
     18 
     19 import java.lang.reflect.Constructor;
     20 import java.lang.reflect.Method;
     21 import java.util.Collection;
     22 import java.util.HashMap;
     23 import java.util.Map;
     24 
     25 import com.googlecode.android_scripting.facade.FacadeManager;
     26 import com.googlecode.android_scripting.Log;
     27 import com.googlecode.android_scripting.rpc.MethodDescriptor;
     28 
     29 public abstract class RpcReceiverManager {
     30 
     31     private final Map<Class<? extends RpcReceiver>, RpcReceiver> mReceivers;
     32 
     33     /**
     34      * A map of strings to known RPCs.
     35      */
     36     private final Map<String, MethodDescriptor> mKnownRpcs = new HashMap<String, MethodDescriptor>();
     37 
     38     public RpcReceiverManager(Collection<Class<? extends RpcReceiver>> classList) {
     39         mReceivers = new HashMap<Class<? extends RpcReceiver>, RpcReceiver>();
     40         for (Class<? extends RpcReceiver> receiverClass : classList) {
     41             mReceivers.put(receiverClass, null);
     42             Collection<MethodDescriptor> methodList = MethodDescriptor.collectFrom(receiverClass);
     43             for (MethodDescriptor m : methodList) {
     44                 if (mKnownRpcs.containsKey(m.getName())) {
     45                     // We already know an RPC of the same name. We don't catch this anywhere because
     46                     // this is a programming error.
     47                     throw new RuntimeException("An RPC with the name " + m.getName()
     48                             + " is already known.");
     49                 }
     50                 mKnownRpcs.put(m.getName(), m);
     51             }
     52         }
     53     }
     54 
     55     public Collection<Class<? extends RpcReceiver>> getRpcReceiverClasses() {
     56         return mReceivers.keySet();
     57     }
     58 
     59     private RpcReceiver get(Class<? extends RpcReceiver> clazz) {
     60         RpcReceiver object = mReceivers.get(clazz);
     61         if (object != null) {
     62             return object;
     63         }
     64 
     65         Constructor<? extends RpcReceiver> constructor;
     66         try {
     67             constructor = clazz.getConstructor(FacadeManager.class);
     68             object = constructor.newInstance(this);
     69             mReceivers.put(clazz, object);
     70         } catch (Exception e) {
     71             Log.e(e);
     72         }
     73 
     74         return object;
     75     }
     76 
     77     public <T extends RpcReceiver> T getReceiver(Class<T> clazz) {
     78         RpcReceiver receiver = get(clazz);
     79         return clazz.cast(receiver);
     80     }
     81 
     82     public MethodDescriptor getMethodDescriptor(String methodName) {
     83         return mKnownRpcs.get(methodName);
     84     }
     85 
     86     public Object invoke(Class<? extends RpcReceiver> clazz, Method method, Object[] args)
     87             throws Exception {
     88         RpcReceiver object = get(clazz);
     89         return method.invoke(object, args);
     90     }
     91 
     92     public void shutdown() {
     93         for (RpcReceiver receiver : mReceivers.values()) {
     94             try {
     95                 if (receiver != null) {
     96                     receiver.shutdown();
     97                 }
     98             } catch (Exception e) {
     99                 Log.e("Failed to shut down an RpcReceiver", e);
    100             }
    101         }
    102     }
    103 }
    104