public static <T extends Enum<T>> boolean hasOperationStat(Object rootNode, Class<T> statisticType, String statName) { Query q = queryBuilder().descendants() .filter(context(identifier(subclassOf(OperationStatistic.class)))) .filter(context(attributes(Matchers.allOf( hasAttribute("name", statName), hasAttribute("this", new Matcher<OperationStatistic<T>>() { @Override protected boolean matchesSafely(OperationStatistic<T> object) { return object.type().equals(statisticType); } }) )))) .build(); Set<TreeNode> result = q.execute(Collections.singleton(ContextManager.nodeFor(rootNode))); if (result.size() > 1) { throw new RuntimeException("a zero or a single stat was expected; found " + result.size()); } return !result.isEmpty(); } }
/** * Return the unique node selected by running this query against this * {@code ContextManager}'s root context. * <p> * If this query does not return a single unique result then an * {@code IllegalStateException} will be thrown. More details on the query * execution context can be found in {@link #query(Query)}. * * @see #query(Query) * @see QueryBuilder#ensureUnique() * @param query the query to execute * @return the node selected by the query * @throws IllegalStateException if the query does not select a unique node */ public TreeNode queryForSingleton(Query query) throws IllegalStateException { return query(queryBuilder().chain(query).ensureUnique().build()).iterator().next(); }
/** * Creates a new query builder instance. * <p> * A newly constructed query builder represents the identity query. It simply * returns the input node set as the output node set. * * @return a new query builder */ public static QueryBuilder queryBuilder() { return new QueryBuilder(); }
/** * Add the given nodes to the current node set * * @return merged node set */ EhcacheQuery add(final EhcacheQuery chain) { return new EhcacheQuery(queryBuilder().chain(query).chain(new Query() { @Override public Set<TreeNode> execute(Set<TreeNode> input) { Set<TreeNode> result = new HashSet<TreeNode>(); result.addAll(input); result.addAll(chain.execute(input)); return result; } }).build()); }
/** * Creates a query selecting caches. * * @return cache query */ static EhcacheQuery cache() { return new EhcacheQuery(queryBuilder().build()).children(Cache.class); }
@Override public <T extends Enum<T>> Set<Operation<T>> operations(Class<T> outcome, String name, String... tags) { Set<OperationStatistic<T>> sources = findOperationStatistic(manager, queryBuilder().descendants().build(), outcome, name, new HashSet<String>(Arrays.asList(tags))); if (sources.isEmpty()) { return Collections.emptySet(); } else { Set<Operation<T>> operations = new HashSet(); for (OperationStatistic<T> source : sources) { CompoundOperationImpl<T> operation = (CompoundOperationImpl<T>) customOperations.get(source); if (operation == null) { operation = new CompoundOperationImpl<T>(source, source.type(), 1, SECONDS, executor, 0, 1, SECONDS); CompoundOperationImpl<T> racer = (CompoundOperationImpl<T>) customOperations.putIfAbsent(source, operation); if (racer != null) { operation = racer; } } operations.add(operation); } return operations; } }
/** * Creates a query selecting all children. * * @return children query */ public static Query children() { return queryBuilder().children().build(); }
/** * Selects the union of the current node sets child nodes. * * @return this query builder */ public QueryBuilder children() { return chain(Children.INSTANCE); }
/** * Add the given nodes to the current node set * * @return merged node set */ EhcacheQuery add(final EhcacheQuery chain) { return new EhcacheQuery(queryBuilder().chain(query).chain(new Query() { @Override public Set<TreeNode> execute(Set<TreeNode> input) { Set<TreeNode> result = new HashSet<TreeNode>(); result.addAll(input); result.addAll(chain.execute(input)); return result; } }).build()); }
/** * Creates a query selecting all descendants. * * @return descendants query */ static EhcacheQuery descendants() { return new EhcacheQuery(queryBuilder().build()).descendants(); }
/** * Creates a query selecting all descendants. * * @return descendants query */ public static Query descendants() { return queryBuilder().descendants().build(); }
/** * Add the given nodes to the current node set * * @return merged node set */ EhcacheQuery add(final EhcacheQuery chain) { return new EhcacheQuery(queryBuilder().chain(query).chain(new Query() { @Override public Set<TreeNode> execute(Set<TreeNode> input) { Set<TreeNode> result = new HashSet<TreeNode>(); result.addAll(input); result.addAll(chain.execute(input)); return result; } }).build()); }
/** * Selects the merged descendant set of the current node set. * <p> * More precisely this recursively merges the children of each member of the * node-set in to the output node set until the set ceases to grow. * * @return this query builder */ public QueryBuilder descendants() { return chain(Descendants.INSTANCE); }
/** * Search for a statistic on the descendant of the context that matches the tag and statistic name. * * @param context the context of the query * @param tag the tag we are looking for * @param statName statistic name * @param <T> type of the statistic that will be returned * @return the wanted statistic or null if no such statistic is found * @throws RuntimeException when more than one matching statistic is found */ public static <T> Optional<T> findStatisticOnDescendants(Object context, String tag, String statName) { @SuppressWarnings("unchecked") Set<TreeNode> statResult = queryBuilder() .descendants() .filter(context(attributes(Matchers.allOf( hasAttribute("name", statName), hasTag(tag))))) .build().execute(Collections.singleton(ContextManager.nodeFor(context))); if (statResult.size() > 1) { throw new RuntimeException("One stat expected for " + statName + " but found " + statResult.size()); } if (statResult.size() == 1) { @SuppressWarnings("unchecked") T result = (T) statResult.iterator().next().getContext().attributes().get("this"); return Optional.ofNullable(result); } // No such stat in this context return Optional.empty(); }
/** * Return the unique node selected by running this query against this * {@code ContextManager}'s root context. * <p> * If this query does not return a single unique result then an * {@code IllegalStateException} will be thrown. More details on the query * execution context can be found in {@link #query(Query)}. * * @param query the query to execute * @return the node selected by the query * @throws IllegalStateException if the query does not select a unique node * @see #query(Query) * @see QueryBuilder#ensureUnique() */ public TreeNode queryForSingleton(Query query) throws IllegalStateException { return query(queryBuilder().chain(query).ensureUnique().build()).iterator().next(); }
/** * Creates a query selecting all children. * * @return children query */ static EhcacheQuery children() { return new EhcacheQuery(queryBuilder().build()).children(); }
@Override public <T extends Enum<T>> Set<Operation<T>> operations(Class<T> outcome, String name, String... tags) { Set<OperationStatistic<T>> sources = findOperationStatistic(manager, queryBuilder().descendants().build(), outcome, name, new HashSet<String>(Arrays.asList(tags))); if (sources.isEmpty()) { return Collections.emptySet(); } else { Set<Operation<T>> operations = new HashSet(); for (OperationStatistic<T> source : sources) { CompoundOperationImpl<T> operation = (CompoundOperationImpl<T>) customOperations.get(source); if (operation == null) { operation = new CompoundOperationImpl<T>(source, source.type(), 1, SECONDS, executor, 0, 1, SECONDS); CompoundOperationImpl<T> racer = (CompoundOperationImpl<T>) customOperations.putIfAbsent(source, operation); if (racer != null) { operation = racer; } } operations.add(operation); } return operations; } }
/** * Asserts that the current node set is a singleton. * <p> * If the current node set is not of size 1 then the query will terminate with * an {@code IllegalStateException}. * * @return this query builder */ public QueryBuilder ensureUnique() { return chain(EnsureUnique.INSTANCE); }
/** * Creates a new query builder instance. * <p> * A newly constructed query builder represents the identity query. It simply * returns the input node set as the output node set. * * @return a new query builder */ public static QueryBuilder queryBuilder() { return new QueryBuilder(); }
/** * Find an operation statistic attached (as a children) to this context that matches the statistic name and type * * @param context the context of the query * @param type type of the operation statistic * @param statName statistic name * @param <T> type of the operation statistic content * @return the operation statistic searched for * @throws RuntimeException if 0 or more than 1 result is found */ public static <T extends Enum<T>> OperationStatistic<T> findOperationStatisticOnChildren(Object context, Class<T> type, String statName) { @SuppressWarnings("unchecked") Query query = queryBuilder() .children() .filter(context(attributes(Matchers.allOf(hasAttribute("name", statName), hasAttribute("type", type))))) .build(); Set<TreeNode> result = query.execute(Collections.singleton(ContextManager.nodeFor(context))); if (result.size() > 1) { throw new RuntimeException("result must be unique"); } if (result.isEmpty()) { throw new RuntimeException("result must not be null"); } @SuppressWarnings("unchecked") OperationStatistic<T> statistic = (OperationStatistic<T>) result.iterator().next().getContext().attributes().get("this"); return statistic; }