Package com.subgraph.orchid.config

Source Code of com.subgraph.orchid.config.TorConfigProxy

package com.subgraph.orchid.config;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.subgraph.orchid.TorConfig;
import com.subgraph.orchid.TorConfig.ConfigVar;
import com.subgraph.orchid.TorConfig.ConfigVarType;
import com.subgraph.orchid.data.HexDigest;
import com.subgraph.orchid.data.IPv4Address;

public class TorConfigProxy implements InvocationHandler {
 
  private final Map<String, Object> configValues;
  private final List<TorConfigBridgeLine> bridges;
  private final TorConfigParser parser;
 
  public TorConfigProxy() {
    this.configValues = new HashMap<String, Object>();
    this.bridges = new ArrayList<TorConfigBridgeLine>();
    this.configValues.put("Bridges", bridges);
    this.parser = new TorConfigParser();
  }
 
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if(method.getName().startsWith("set")) {
      invokeSetMethod(method, args);
      return null;
    } else if(method.getName().startsWith("get")) {
      if(args == null) {
        return invokeGetMethod(method);
      } else {
        return invokeGetMethodWithArgs(method, args);
      }
    } else if(method.getName().startsWith("add")) {
      invokeAddMethod(method, args);
      return null;
    } else {
      throw new IllegalArgumentException();
    }
  }
 
  void invokeSetMethod(Method method, Object[] args) {
    final String name = getVariableNameForMethod(method);
    final ConfigVar annotation = getAnnotationForVariable(name);
    if(annotation != null && annotation.type() == ConfigVarType.INTERVAL) {
      setIntervalValue(name, args);
    } else {
      configValues.put(name, args[0]);
    }
  }
 
  private void setIntervalValue(String varName, Object[] args) {
    if(!(args[0] instanceof Long && args[1] instanceof TimeUnit)) {
      throw new IllegalArgumentException();
    }
    final long time = (Long) args[0];
    final TimeUnit unit = (TimeUnit) args[1];
    final TorConfigInterval interval = new TorConfigInterval(time, unit);
    configValues.put(varName, interval);
  }

 
  private Object invokeGetMethodWithArgs(Method method, Object[] args) {
    final String varName = getVariableNameForMethod(method);
    if(getVariableType(varName) == ConfigVarType.HS_AUTH) {
      return invokeHSAuthGet(varName, args);
    } else {
      throw new IllegalArgumentException();
    }
  }
 
  private Object invokeGetMethod(Method method) {
    final String varName = getVariableNameForMethod(method);
    final Object value = getVariableValue(varName);
   
    if(value instanceof TorConfigInterval) {
      final TorConfigInterval interval = (TorConfigInterval) value;
      return interval.getMilliseconds();
    } else {
      return value;
    }
  }
 
  private Object invokeHSAuthGet(String varName, Object[] args) {
    if(!(args[0] instanceof String)) {
      throw new IllegalArgumentException();
    }
    final TorConfigHSAuth hsAuth = getHSAuth(varName);   
    return hsAuth.get((String) args[0]);
  }

  private void invokeAddMethod(Method method, Object[] args) {
    final String name = getVariableNameForMethod(method);
    final ConfigVarType type = getVariableType(name);
    switch(type) {
    case HS_AUTH:
      invokeHSAuthAdd(name, args);
      break;
     
    case BRIDGE_LINE:
      invokeBridgeAdd(args);
      break;
     
    default:
      throw new UnsupportedOperationException("addX configuration methods only supported for HS_AUTH or BRIDGE_LINE type");
    }
  }
 
  private void invokeBridgeAdd(Object[] args) {
    if(args.length >= 2 && (args[0] instanceof IPv4Address) && (args[1] instanceof Integer)) {
      if(args.length == 2) {
        bridges.add(new TorConfigBridgeLine((IPv4Address)args[0], (Integer)args[1], null));
        return;
      } else if(args.length == 3 && (args[2] instanceof HexDigest)) {
        bridges.add(new TorConfigBridgeLine((IPv4Address) args[0], (Integer) args[1], (HexDigest) args[2]));
        return;
      }
    }
    throw new IllegalArgumentException();
  }
 
  private void invokeHSAuthAdd(String name, Object[] args) {
    if(!(args.length == 2 && (args[0] instanceof String) && (args[1] instanceof String))) {
      throw new IllegalArgumentException();
    }
    final TorConfigHSAuth hsAuth = getHSAuth(name);
    hsAuth.add((String)args[0], (String)args[1]);
  }
 
  private TorConfigHSAuth getHSAuth(String keyName) {
    if(!configValues.containsKey(keyName)) {
      configValues.put(keyName, new TorConfigHSAuth());
    }
    return (TorConfigHSAuth) configValues.get(keyName);
  }

  private Object getVariableValue(String varName) {
    if(configValues.containsKey(varName)) {
      return configValues.get(varName);
    } else {
      return getDefaultVariableValue(varName);
    }
  }

  private Object getDefaultVariableValue(String varName) {
    final String defaultValue = getDefaultValueString(varName);
    final ConfigVarType type = getVariableType(varName);
    if(defaultValue == null || type == null) {
      return null;
    }
    return parser.parseValue(defaultValue, type);
  }
 
  private String getDefaultValueString(String varName) {
    final ConfigVar var = getAnnotationForVariable(varName);
    if(var == null) {
      return null;
    } else {
      return var.defaultValue();
    }
  }

  private ConfigVarType getVariableType(String varName) {
    if("Bridge".equals(varName)) {
      return ConfigVarType.BRIDGE_LINE;
    }
   
    final ConfigVar var = getAnnotationForVariable(varName);
    if(var == null) {
      return null;
    } else {
      return var.type();
    }
  }
 
  private String getVariableNameForMethod(Method method) {
    final String methodName = method.getName();
    if(methodName.startsWith("get") || methodName.startsWith("set") || methodName.startsWith("add")) {
      return methodName.substring(3);
    }
    throw new IllegalArgumentException();
  }
 
  private ConfigVar getAnnotationForVariable(String varName) {
    final String getName = "get"+ varName;
    for(Method m: TorConfig.class.getDeclaredMethods()) {
      if(getName.equals(m.getName())) {
        return m.getAnnotation(TorConfig.ConfigVar.class);
      }
    }
    return null;
  }
}
TOP

Related Classes of com.subgraph.orchid.config.TorConfigProxy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.