@Override
    public Volumes deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
        throws IOException, JsonProcessingException {

      List<Volume> volumes = new ArrayList<Volume>();
      ObjectCodec oc = jsonParser.getCodec();
      JsonNode node = oc.readTree(jsonParser);
      for (Iterator<Map.Entry<String, JsonNode>> it = node.fields(); it.hasNext(); ) {

        Map.Entry<String, JsonNode> field = it.next();
        if (!field.getValue().equals(NullNode.getInstance())) {
          String path = field.getKey();
          Volume volume = new Volume(path);
          volumes.add(volume);
        }
      }
      return new Volumes(volumes.toArray(new Volume[0]));
    }
  @Test
  public void test() throws JsonProcessingException, IOException {
    final Scope scope = new Scope();
    final ObjectMapper mapper = new ObjectMapper();

    scope.addFunction(
        "inc", 1, new JsonQueryFunction("inc", Arrays.asList("x"), JsonQuery.compile("x + 1")));
    scope.addFunction(
        "fib",
        1,
        new JsonQueryFunction(
            "fib",
            Arrays.asList("x"),
            JsonQuery.compile("if x == 0 then 0 elif x == 1 then 1 else fib(x-1) + fib(x-2) end")));
    scope.addFunction(
        "fib",
        0,
        new JsonQueryFunction("fib", Arrays.<String>asList(), JsonQuery.compile("fib(.)"), scope));

    assertEquals(
        Arrays.asList(mapper.readTree("2")),
        JsonQuery.compile("inc(1)").apply(scope, NullNode.getInstance()));
    assertEquals(
        Arrays.asList(mapper.readTree("1")),
        JsonQuery.compile("fib(1)").apply(scope, NullNode.getInstance()));
    assertEquals(
        Arrays.asList(mapper.readTree("1")),
        JsonQuery.compile("fib(2)").apply(scope, NullNode.getInstance()));
    assertEquals(
        Arrays.asList(mapper.readTree("2")),
        JsonQuery.compile("fib(3)").apply(scope, NullNode.getInstance()));
    assertEquals(
        Arrays.asList(mapper.readTree("3")),
        JsonQuery.compile("fib(4)").apply(scope, NullNode.getInstance()));
    assertEquals(
        Arrays.asList(mapper.readTree("5")),
        JsonQuery.compile("fib(5)").apply(scope, NullNode.getInstance()));
    assertEquals(
        Arrays.asList(mapper.readTree("8")),
        JsonQuery.compile("fib").apply(scope, IntNode.valueOf(6)));
  }
Exemple #3
0
  /**
   * Finds the {@link Method} from the supplied {@link Set} that best matches the rest of the
   * arguments supplied and returns it as a {@link MethodAndArgs} class.
   *
   * @param methods the {@link Method}s
   * @param paramNames the parameter names
   * @param paramNodes the parameters for matching types
   * @return the {@link MethodAndArgs}
   */
  @SuppressWarnings("deprecation")
  protected MethodAndArgs findBestMethodUsingParamNames(
      Set<Method> methods, Set<String> paramNames, ObjectNode paramNodes) {

    // determine param count
    int maxMatchingParams = -1;
    int maxMatchingParamTypes = -1;
    Method bestMethod = null;
    List<JsonRpcParam> bestAnnotations = null;

    for (Method method : methods) {

      // get parameter types
      List<Class<?>> parameterTypes = ReflectionUtil.getParameterTypes(method);

      // bail early if possible
      if (!allowExtraParams && paramNames.size() > parameterTypes.size()) {
        continue;
      } else if (!allowLessParams && paramNames.size() < parameterTypes.size()) {
        continue;
      }

      // list of params
      List<JsonRpcParam> annotations = new ArrayList<JsonRpcParam>();

      // try the deprecated parameter first
      List<List<JsonRpcParamName>> depMethodAnnotations =
          ReflectionUtil.getParameterAnnotations(method, JsonRpcParamName.class);
      if (!depMethodAnnotations.isEmpty()) {
        for (List<JsonRpcParamName> annots : depMethodAnnotations) {
          if (annots.size() > 0) {
            final JsonRpcParamName annotation = annots.get(0);
            annotations.add(
                (JsonRpcParam)
                    Proxy.newProxyInstance(
                        getClass().getClassLoader(),
                        new Class[] {JsonRpcParam.class},
                        new InvocationHandler() {
                          public Object invoke(Object proxy, Method method, Object[] args)
                              throws Throwable {
                            if (method.getName().equals("value")) {
                              return annotation.value();
                            }
                            throw new Exception("Unknown method: " + method.getName());
                          }
                        }));
          } else {
            annots.add(null);
          }
        }
      }

      // now try the non-deprecated parameters
      List<List<JsonRpcParam>> methodAnnotations =
          ReflectionUtil.getParameterAnnotations(method, JsonRpcParam.class);
      if (!methodAnnotations.isEmpty()) {
        for (List<JsonRpcParam> annots : methodAnnotations) {
          if (annots.size() > 0) {
            annotations.add(annots.get(0));
          } else {
            annots.add(null);
          }
        }
      }

      // count the matching params for this method
      int numMatchingParamTypes = 0;
      int numMatchingParams = 0;
      for (int i = 0; i < annotations.size(); i++) {

        // skip parameters that didn't have an annotation
        JsonRpcParam annotation = annotations.get(i);
        if (annotation == null) {
          continue;
        }

        // check for a match
        String paramName = annotation.value();
        boolean hasParamName = paramNames.contains(paramName);

        if (hasParamName && isMatchingType(paramNodes.get(paramName), parameterTypes.get(i))) {
          numMatchingParamTypes++;
          numMatchingParams++;

        } else if (hasParamName) {
          numMatchingParams++;
        }
      }

      // check for exact param matches
      // bail early if possible
      if (!allowExtraParams && numMatchingParams > parameterTypes.size()) {
        continue;
      } else if (!allowLessParams && numMatchingParams < parameterTypes.size()) {
        continue;
      }

      // better match
      if (numMatchingParams > maxMatchingParams
          || (numMatchingParams == maxMatchingParams
              && numMatchingParamTypes > maxMatchingParamTypes)) {
        bestMethod = method;
        maxMatchingParams = numMatchingParams;
        maxMatchingParamTypes = numMatchingParamTypes;
        bestAnnotations = annotations;
      }
    }

    // bail early
    if (bestMethod == null) {
      return null;
    }

    // create return
    MethodAndArgs ret = new MethodAndArgs();
    ret.method = bestMethod;

    // now fill arguments
    int numParameters = bestMethod.getParameterTypes().length;
    for (int i = 0; i < numParameters; i++) {
      JsonRpcParam param = bestAnnotations.get(i);
      if (param != null && paramNames.contains(param.value())) {
        ret.arguments.add(paramNodes.get(param.value()));
      } else {
        ret.arguments.add(NullNode.getInstance());
      }
    }

    // return the method
    return ret;
  }
Exemple #4
0
  /**
   * Finds the {@link Method} from the supplied {@link Set} that best matches the rest of the
   * arguments supplied and returns it as a {@link MethodAndArgs} class.
   *
   * @param methods the {@link Method}s
   * @param paramCount the number of expect parameters
   * @param paramNodes the parameters for matching types
   * @return the {@link MethodAndArgs}
   */
  protected MethodAndArgs findBestMethodUsingParamIndexes(
      Set<Method> methods, int paramCount, ArrayNode paramNodes) {

    // get param count
    int numParams = paramNodes != null && !paramNodes.isNull() ? paramNodes.size() : 0;

    // determine param count
    int bestParamNumDiff = Integer.MAX_VALUE;
    Set<Method> matchedMethods = new HashSet<Method>();

    // check every method
    for (Method method : methods) {

      // get parameter types
      Class<?>[] paramTypes = method.getParameterTypes();
      int paramNumDiff = paramTypes.length - paramCount;

      // we've already found a better match
      if (Math.abs(paramNumDiff) > Math.abs(bestParamNumDiff)) {
        continue;

        // we don't allow extra params
      } else if (!allowExtraParams && paramNumDiff < 0 || !allowLessParams && paramNumDiff > 0) {
        continue;

        // check the parameters
      } else {
        if (Math.abs(paramNumDiff) < Math.abs(bestParamNumDiff)) {
          matchedMethods.clear();
        }
        matchedMethods.add(method);
        bestParamNumDiff = paramNumDiff;
        continue;
      }
    }

    // bail early
    if (matchedMethods.isEmpty()) {
      return null;
    }

    // now narrow it down to the best method
    // based on argument types
    Method bestMethod = null;
    if (matchedMethods.size() == 1 || numParams == 0) {
      bestMethod = matchedMethods.iterator().next();

    } else {

      // check the matching methods for
      // matching parameter types
      int mostMatches = -1;
      for (Method method : matchedMethods) {
        List<Class<?>> parameterTypes = ReflectionUtil.getParameterTypes(method);
        int numMatches = 0;
        for (int i = 0; i < parameterTypes.size() && i < numParams; i++) {
          if (isMatchingType(paramNodes.get(i), parameterTypes.get(i))) {
            numMatches++;
          }
        }
        if (numMatches > mostMatches) {
          mostMatches = numMatches;
          bestMethod = method;
        }
      }
    }

    // create return
    MethodAndArgs ret = new MethodAndArgs();
    ret.method = bestMethod;

    // now fill arguments
    int numParameters = bestMethod.getParameterTypes().length;
    for (int i = 0; i < numParameters; i++) {
      if (i < numParams) {
        ret.arguments.add(paramNodes.get(i));
      } else {
        ret.arguments.add(NullNode.getInstance());
      }
    }

    // return the method
    return ret;
  }
/** @author henrik lundgren */
public final class ContinuousChangesFeed implements ChangesFeed, Runnable {

  private static final AtomicInteger THREAD_COUNT = new AtomicInteger();
  private static final Logger LOG = LoggerFactory.getLogger(ContinuousChangesFeed.class);
  private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
  private static final DocumentChange INTERRUPT_MARKER =
      new StdDocumentChange(NullNode.getInstance());
  private static final Set<Class<?>> INTERRUPTED_EXCEPTION_TYPES = new HashSet<Class<?>>();

  static {
    INTERRUPTED_EXCEPTION_TYPES.add(InterruptedException.class);
    INTERRUPTED_EXCEPTION_TYPES.add(InterruptedIOException.class);
  }

  private final BlockingQueue<DocumentChange> changes =
      new LinkedBlockingQueue<DocumentChange>(100);
  private final BufferedReader reader;
  private final Thread thread = new Thread(this);
  private volatile boolean shouldRun = true;
  private final HttpResponse httpResponse;

  public ContinuousChangesFeed(String dbName, HttpResponse httpResponse) {
    this.httpResponse = httpResponse;
    try {
      reader = new BufferedReader(new InputStreamReader(httpResponse.getContent(), "UTF-8"));
      thread.setName(
          String.format(
              "ektorp-%s-changes-listening-thread-%s", dbName, THREAD_COUNT.getAndIncrement()));
      thread.start();
    } catch (UnsupportedEncodingException e) {
      throw Exceptions.propagate(e);
    }
  }

  public DocumentChange next() throws InterruptedException {
    assertRunningState();
    DocumentChange c = changes.take();
    checkIfInterrupted(c);
    return c;
  }

  public DocumentChange poll() throws InterruptedException {
    assertRunningState();
    DocumentChange c = changes.poll();
    checkIfInterrupted(c);
    return c;
  }

  public DocumentChange next(long timeout, TimeUnit unit) throws InterruptedException {
    assertRunningState();
    DocumentChange c = changes.poll(timeout, unit);
    checkIfInterrupted(c);
    return c;
  }

  private void assertRunningState() {
    if (!isAlive()) {
      throw new IllegalStateException("Changes feed is not alive");
    }
  }

  private void checkIfInterrupted(DocumentChange c) throws InterruptedException {
    if (c == INTERRUPT_MARKER || (!shouldRun && changes.isEmpty())) {
      throw new InterruptedException();
    }
  }

  public void cancel() {
    LOG.debug("Feed cancelled");
    shouldRun = false;
    thread.interrupt();
  }

  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE")
  private void sendInterruptMarker() {
    LOG.debug("Sending interrupt marker in order to interrupt feed consumer");
    changes.offer(INTERRUPT_MARKER);
  }

  public boolean isAlive() {
    return thread.isAlive();
  }

  public int queueSize() {
    return changes.size();
  }

  public void run() {
    try {
      String line = reader.readLine();
      while (shouldRun && line != null) {
        if (line.length() > 0) {
          handleChange(line);
        } else {
          handleHeartbeat();
        }
        line = reader.readLine();
      }
      String reason = !shouldRun ? "Cancelled" : "EOF";
      LOG.info("Changes feed stopped. Reason: " + reason);
    } catch (Exception e) {
      handleException(e);
    } finally {
      sendInterruptMarker();
      httpResponse.abort();
      try {
        reader.close();
      } catch (IOException e) {
      }
    }
  }

  private void handleChange(String line)
      throws IOException, InterruptedException, JsonParseException, JsonMappingException {
    changes.put(new StdDocumentChange(OBJECT_MAPPER.readTree(line)));
  }

  private void handleHeartbeat() {
    LOG.debug("Got heartbeat from DB");
  }

  private void handleException(Exception e) {
    if (INTERRUPTED_EXCEPTION_TYPES.contains(e.getClass())) {
      LOG.info("Changes feed was interrupted");
    } else {
      LOG.error("Caught exception while listening to changes feed:", e);
    }
  }
}
Exemple #6
0
 public NullLiteral() {
   super(NullNode.getInstance());
 }
 /** Adds a variable to the current scope. */
 private void addVariable(String name) {
   JsonNode node = currentNode.path(name);
   if (node.isMissingNode()) {
     currentNode.put(name, NullNode.getInstance());
   }
 }
Exemple #8
0
 @JsonValue
 public NullNode value() {
   return NullNode.getInstance();
 }