@Override public EvaluationContext evaluate(Object document, Object rootDocument, Configuration configuration, boolean forUpdate) { if (logger.isDebugEnabled()) { logger.debug("Evaluating path: {}", toString()); } EvaluationContextImpl ctx = new EvaluationContextImpl(this, rootDocument, configuration, forUpdate); try { PathRef op = ctx.forUpdate() ? PathRef.createRoot(rootDocument) : PathRef.NO_OP; root.evaluate("", op, document, ctx); } catch (EvaluationAbortException abort) {} return ctx; }
@Override public void evaluate(String currentPath, PathRef ref, Object model, EvaluationContextImpl ctx) { if (ctx.jsonProvider().isMap(model)) { if (accept(model, ctx.rootDocument(), ctx.configuration(), ctx)) { PathRef op = ctx.forUpdate() ? ref : PathRef.NO_OP; if (isLeaf()) { ctx.addResult(currentPath, op, model); } else { next().evaluate(currentPath, op, model, ctx); } } } else if (ctx.jsonProvider().isArray(model)){ int idx = 0; Iterable<?> objects = ctx.jsonProvider().toIterable(model); for (Object idxModel : objects) { if (accept(idxModel, ctx.rootDocument(), ctx.configuration(), ctx)) { handleArrayIndex(idx, currentPath, model, ctx); } idx++; } } else { if (isUpstreamDefinite()) { throw new InvalidPathException(format("Filter: %s can not be applied to primitives. Current context is: %s", toString(), model)); } } }
public boolean accept(final Object obj, final Object root, final Configuration configuration, EvaluationContextImpl evaluationContext) { Predicate.PredicateContext ctx = new PredicateContextImpl(obj, root, configuration, evaluationContext.documentEvalCache()); for (Predicate predicate : predicates) { try { if (!predicate.apply(ctx)) { return false; } } catch (InvalidPathException e) { return false; } } return true; }
@Override public boolean matches(Object model) { return predicatePathToken.accept(model, ctx.rootDocument(), ctx.configuration(), ctx); } }
protected void handleArrayIndex(int index, String currentPath, Object model, EvaluationContextImpl ctx) { String evalPath = Utils.concat(currentPath, "[", String.valueOf(index), "]"); PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, index) : PathRef.NO_OP; int effectiveIndex = index < 0 ? ctx.jsonProvider().length(model) + index : index; try { Object evalHit = ctx.jsonProvider().getArrayIndex(model, effectiveIndex); if (isLeaf()) { if (ctx.configuration().getComputeRoot()) { checkAndFillArrayElements(ctx, ctx.getParent(), evalHit, effectiveIndex); ctx.addResult(evalPath, pathRef, evalHit); } else { Object old = ctx.getParent(); Object curr = null; if (ctx.configuration().getComputeRoot()) { curr = (ctx.configuration().jsonProvider().length(old) > effectiveIndex ? ctx.configuration().jsonProvider().getArrayIndex(old, effectiveIndex) : null); if (null == curr) { curr = ctx.configuration().jsonProvider().createMap(); checkAndFillArrayElements(ctx, old, curr, effectiveIndex); ctx.setParent(curr); if (ctx.configuration().getComputeRoot()) { if (old != curr) { if (ctx.configuration().jsonProvider().isMap(curr) && ctx.configuration().jsonProvider().length(curr) == 0) { ctx.configuration().jsonProvider().removeProperty(old, new Integer(effectiveIndex));
@Override public boolean matches(Object model) { return ctx.jsonProvider().isArray(model); } }
if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){ propertyVal = null; } else { if(ctx.options().contains(Option.SUPPRESS_EXCEPTIONS) || !ctx.options().contains(Option.REQUIRE_PROPERTIES)){ return; } else { !ctx.options().contains(Option.REQUIRE_PROPERTIES) || ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)){ PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, property) : PathRef.NO_OP; if (isLeaf()) { ctx.addResult(evalPath, pathRef, propertyVal); Object merged = ctx.jsonProvider().createMap(); for (String property : properties) { Object propertyVal; propertyVal = readObjectProperty(property, model, ctx); if(propertyVal == JsonProvider.UNDEFINED){ if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)) { propertyVal = null; } else { if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){ propertyVal = null; } else if (ctx.options().contains(Option.REQUIRE_PROPERTIES)) { throw new PathNotFoundException("Missing property in path " + evalPath);
@Override public void evaluate(String currentPath, PathRef pathRef, Object model, EvaluationContextImpl ctx) { if (isLeaf()) { PathRef op = ctx.forUpdate() ? pathRef : PathRef.NO_OP; if (ctx.configuration().getComputeRoot()) { // KR ok to overwrite root here ctx.setRoot(model); ctx.setParent(model); } ctx.addResult(rootToken, op, model); } else { if (ctx.configuration().getComputeRoot()) { Object root; if (null != ctx.getRoot()) { root = ctx.getRoot(); } else { root = ctx.configuration().jsonProvider().copy(model); } ctx.setRoot(root); ctx.setParent(root); } next().evaluate(rootToken, pathRef, model, ctx); } }
@Override public void evaluate(String currentPath, PathRef parent, Object model, EvaluationContextImpl ctx) { if (ctx.jsonProvider().isMap(model)) { for (String property : ctx.jsonProvider().getPropertyKeys(model)) { handleObjectProperty(currentPath, model, ctx, Collections.singletonList(property)); } } else if (ctx.jsonProvider().isArray(model)) { for (int idx = 0; idx < ctx.jsonProvider().length(model); idx++) { try { handleArrayIndex(idx, currentPath, model, ctx); } catch (PathNotFoundException p){ if(ctx.options().contains(Option.REQUIRE_PROPERTIES)){ throw p; } } } } }
protected void handleArrayIndex(int index, String currentPath, Object model, EvaluationContextImpl ctx) { String evalPath = Utils.concat(currentPath, "[", String.valueOf(index), "]"); PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, index) : PathRef.NO_OP; int effectiveIndex = index < 0 ? ctx.jsonProvider().length(model) + index : index; try { Object evalHit = ctx.jsonProvider().getArrayIndex(model, effectiveIndex); if (isLeaf()) { ctx.addResult(evalPath, pathRef, evalHit); } else { next().evaluate(evalPath, pathRef, evalHit, ctx); } } catch (IndexOutOfBoundsException e) { } }
@Override public void evaluate(String currentPath, PathRef parent, Object model, EvaluationContextImpl ctx) { // Can't assert it in ctor because isLeaf() could be changed later on. assert onlyOneIsTrueNonThrow(singlePropertyCase(), multiPropertyMergeCase(), multiPropertyIterationCase()); if (!ctx.jsonProvider().isMap(model)) { if (! isUpstreamDefinite()) { return; } else { String m = model == null ? "null" : model.getClass().getName(); throw new PathNotFoundException(String.format( "Expected to find an object with property %s in path %s but found '%s'. " + "This is not a json object according to the JsonProvider: '%s'.", getPathFragment(), currentPath, m, ctx.configuration().jsonProvider().getClass().getName())); } } if (singlePropertyCase() || multiPropertyMergeCase()) { handleObjectProperty(currentPath, model, ctx, properties); return; } assert multiPropertyIterationCase(); final List<String> currentlyHandledProperty = new ArrayList<String>(1); currentlyHandledProperty.add(null); for (final String property : properties) { currentlyHandledProperty.set(0, property); handleObjectProperty(currentPath, model, ctx, currentlyHandledProperty); } }
@Override public EvaluationContextImpl evaluate(Object rootObj, Object document, Object rootDocument, Configuration configuration) { if (logger.isDebugEnabled()) { logger.debug("Evaluating path: {}", toString()); } EvaluationContextImpl ctx = new EvaluationContextImpl(this, rootDocument, configuration, true); if (null != rootObj) { ctx.setRoot(rootObj); } try { PathRef op = ctx.forUpdate() ? PathRef.createRoot(rootDocument) : PathRef.NO_OP; root.evaluate("", op, document, ctx); } catch (EvaluationAbortException abort) { } return ctx; }
public void invoke(PathFunction pathFunction, String currentPath, PathRef parent, Object model, EvaluationContextImpl ctx) { ctx.addResult(currentPath, parent, pathFunction.invoke(currentPath, parent, model, ctx, null)); }
private void checkAndFillArrayElements(EvaluationContextImpl ctx, Object parent, Object evalHit, int effectiveIndex) { Object copy = ctx.jsonProvider().copy(evalHit); int len = ctx.jsonProvider().length(parent); // fill dummy array elements if (len < effectiveIndex) { for (int i = len; i < effectiveIndex; i++) { ctx.jsonProvider().setArrayIndex(parent, i, copy); } } ctx.jsonProvider().setArrayIndex(ctx.getParent(), effectiveIndex, evalHit); }
@SuppressWarnings("unchecked") @Override public <T> T getValue() { return getValue(true); }
public void addResult(String path, PathRef operation, Object model) { if(forUpdate) { updateOperations.add(operation); } configuration.jsonProvider().setArrayIndex(valueResult, resultIndex, model); configuration.jsonProvider().setArrayIndex(pathResult, resultIndex, path); resultIndex++; if(!configuration().getEvaluationListeners().isEmpty()){ int idx = resultIndex - 1; for (EvaluationListener listener : configuration().getEvaluationListeners()) { EvaluationListener.EvaluationContinuation continuation = listener.resultFound(new FoundResultImpl(idx, path, model)); if(EvaluationListener.EvaluationContinuation.ABORT == continuation){ throw ABORT_EVALUATION; } } } }
if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){ propertyVal = null; } else { if(ctx.options().contains(Option.SUPPRESS_EXCEPTIONS) || !ctx.options().contains(Option.REQUIRE_PROPERTIES)){ return; } else { !ctx.options().contains(Option.REQUIRE_PROPERTIES) || ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)){ PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, property) : PathRef.NO_OP; if (isLeaf()) { if (ctx.configuration().getComputeRoot()) { if (null == ctx.configuration().jsonProvider().getProperty(ctx.getParent(), property)) { ctx.configuration().jsonProvider().setProperty(ctx.getParent(), property, propertyVal); ctx.addResult(evalPath, pathRef, propertyVal); } else { Object prev = ctx.getParent(); Object curr = null; if (ctx.configuration().getComputeRoot()) { curr = ctx.configuration().jsonProvider().getProperty(prev, property); if (null == curr) { if (ctx.configuration().jsonProvider().isMap(propertyVal)) { curr = ctx.configuration().jsonProvider().createMap(); } else if (ctx.configuration().jsonProvider().isArray(propertyVal)) {
private static Object readObjectProperty(String property, Object model, EvaluationContextImpl ctx) { return ctx.jsonProvider().getMapValue(model, property); }
if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){ propertyVal = null; } else { if(ctx.options().contains(Option.SUPPRESS_EXCEPTIONS) || !ctx.options().contains(Option.REQUIRE_PROPERTIES)){ return; } else { !ctx.options().contains(Option.REQUIRE_PROPERTIES) || ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)){ PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, property) : PathRef.NO_OP; if (isLeaf()) { ctx.addResult(evalPath, pathRef, propertyVal); Object merged = ctx.jsonProvider().createMap(); for (String property : properties) { Object propertyVal; propertyVal = readObjectProperty(property, model, ctx); if(propertyVal == JsonProvider.UNDEFINED){ if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)) { propertyVal = null; } else { if(ctx.options().contains(Option.DEFAULT_PATH_LEAF_TO_NULL)){ propertyVal = null; } else if (ctx.options().contains(Option.REQUIRE_PROPERTIES)) { throw new PathNotFoundException("Missing property in path " + evalPath);