Java tutorial
/* * #%L * wcm.io * %% * Copyright (C) 2014 wcm.io * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ package io.wcm.caravan.pipeline.extensions.hal.filter; import java.util.List; import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; import org.osgi.annotation.versioning.ProviderType; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.Option; import io.wcm.caravan.hal.resource.HalResource; import rx.functions.Func1; /** * Default filtering predicates for HAL resources. */ @ProviderType public final class HalResourceFilters { private static final Configuration JSON_PATH_CONF = Configuration.defaultConfiguration() .addOptions(Option.ALWAYS_RETURN_LIST, Option.SUPPRESS_EXCEPTIONS); /** JSON object mapper */ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); private HalResourceFilters() { // nothing to do } /** * Executes all predicates and combines the result by logical {@code and}. If there are negative predicate results, * remaining predicates will not get executed. * @param predicates Predicates to check * @return True if all predicates return true */ public static HalResourcePredicate all(HalResourcePredicate... predicates) { return new HalResourcePredicate() { @Override public boolean apply(HalPath halPath, HalResource hal) { for (HalResourcePredicate predicate : predicates) { if (!predicate.apply(halPath, hal)) { return false; } } return true; } @Override public String getId() { List<String> ids = Stream.of(predicates).map(matcher -> matcher.getId()) .collect(java.util.stream.Collectors.toList()); return "ALL(" + StringUtils.join(ids, '+') + ")"; } }; } /** * @param jsonPath JSON path to check * @return True if model has field(s) for given JSON path and all values are not null */ public static HalResourcePredicate hasPathNonNull(String jsonPath) { JsonPath compiledPath = JsonPath.compile(jsonPath); return new HalResourcePredicate() { @Override public String getId() { return "HAS(" + jsonPath + ")"; } @Override public boolean apply(HalPath halPath, HalResource hal) { ObjectNode json = hal.getModel(); ArrayNode matches = compiledPath.read(json, JSON_PATH_CONF); // check for empty result list if (matches == null || matches.size() == 0) { return false; } // check for null value for (JsonNode match : matches) { if (match == null || match.isNull()) { return false; } } return true; } }; } /** * @param fieldName JSON field name * @return True if field exists and is not null */ public static HalResourcePredicate hasNonNull(String fieldName) { return new HalResourcePredicate() { @Override public String getId() { return "HAS(" + fieldName + ")"; } @Override public boolean apply(HalPath halPath, HalResource hal) { return hal.getModel().hasNonNull(fieldName); } }; } /** * @param relation Relation name of the embedded resource * @return True if HAL resource has one or more embedded resources for the given relation name */ public static HalResourcePredicate hasEmbedded(String relation) { return new HalResourcePredicate() { @Override public String getId() { return "HAS-EMBEDDED(" + relation + ")"; } @Override public boolean apply(HalPath halPath, HalResource hal) { return hal.hasEmbedded(relation) && !hal.getEmbedded(relation).isEmpty(); } }; } /** * Converts the state of the HAL resource to an object of the given type and applies the provided function. * @param <S> Type of the HAL resource state * @param clazz Class type of the HAL resource state * @param function Function to apply on the object * @return Return value of the executed function */ public static <S> HalResourcePredicate object(Class<S> clazz, Func1<S, Boolean> function) { return new HalResourcePredicate() { @Override public String getId() { return "OBJECT(" + clazz.getSimpleName() + ")"; } @Override public boolean apply(HalPath halPath, HalResource hal) { S object = OBJECT_MAPPER.convertValue(hal.getModel(), clazz); return function.call(object); } }; } }