/** * Copyright (C) 2008 - 2014 52°North Initiative for Geospatial Open Source * Software GmbH * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * If the program is linked with libraries which are licensed under one of * the following licenses, the combination of the program with the linked * library is not considered a "derivative work" of the program: * * - Apache License, version 2.0 * - Apache Software License, version 1.0 * - GNU Lesser General Public License, version 3 * - Mozilla Public License, versions 1.0, 1.1 and 2.0 * - Common Development and Distribution License (CDDL), version 1.0 * * Therefore the distribution of the program linked with libraries licensed * under the aforementioned licenses, is permitted by the copyright holders * if the distribution is compliant with both the GNU General Public * icense version 2 and the aforementioned licenses. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ package org.n52.ses.eml.v002.filterlogic.esper.customFunctions; import java.util.List; import java.util.Map; /** * Provides methods to check properties */ public class PropertyMethods { /** * check if a property exists * * @param event the event that should contain the property * @param propertyName the property name * * @return true, if the event contains the property */ @SuppressWarnings("rawtypes") public static boolean propertyExists(Object event, Object propertyName) { //prepare types String propName = propertyName.toString(); //first object is always a MapEvent Map eventMap = (Map) event; //check for nested properties if (propName.contains(".")) { //nested properties return containsNestedProperty(propName, eventMap); } //not nested return containsProperty(propName, eventMap); } @SuppressWarnings("rawtypes") private static boolean containsNestedProperty(String propName, Map map) { //check if first part is contained in map int dotIndex = propName.indexOf("."); String firstPart = propName.substring(0, dotIndex); if (!map.containsKey(firstPart)) { //if not, return false return false; } //if yes, do... //...check if value for the first part is not null Object prop = map.get(firstPart); if (prop == null) { //return false if it is null return false; } //...check if the value is a map or list type, if (!(prop instanceof Map) && !(prop instanceof List)) { //if not, return false as the first part of the nested property must point to a map or list return false; } //...check if the remaining part is nested String lastPart = propName.substring(dotIndex + 1); if (lastPart.contains(".")) { //if yes do a recursive call of containsNestedProperty either with a map or a list, //return result or recursive call if (prop instanceof Map) { return containsNestedProperty(lastPart, (Map) prop); } //prop must be instance of List here, otherwise we would have a return false before return containsNestedProperty(lastPart, (List) prop); } //if not, return result of containsProperty if (prop instanceof Map) { return containsProperty(lastPart, (Map) prop); } //prop must be instance of List here, otherwise we would have a return false before return containsProperty(lastPart, (List) prop); } @SuppressWarnings("rawtypes") private static boolean containsNestedProperty(String propName, List list) { //get first part of the nested property name int dotIndex = propName.indexOf("."); String firstPart = propName.substring(0, dotIndex); //check if first part is an int int index = -1; try { index = Integer.parseInt(firstPart); } catch (NumberFormatException e) { //not an int return false; } //check if the index is contained in list if (index < 0 || index >= list.size()) { //if not, return false return false; } //if yes, do... //...check if value for the index is not null Object prop = list.get(index); if (prop == null) { //return false if it is null return false; } //...check if the value is a map or list type, if (!(prop instanceof Map) && !(prop instanceof List)) { //if not, return false as the first part of the nested property must point to a map or list return false; } //...check if the remaining part is nested String lastPart = propName.substring(dotIndex + 1); if (lastPart.contains(".")) { //if yes do a recursive call of containsNestedProperty either with a map or a list, //return result or recursive call if (prop instanceof Map) { return containsNestedProperty(lastPart, (Map) prop); } //prop must be instance of List here, otherwise we would have a return false before return containsNestedProperty(lastPart, (List) prop); } //if not, return result of containsProperty if (prop instanceof Map) { return containsProperty(lastPart, (Map) prop); } //prop must be instance of List here, otherwise we would have a return false before return containsProperty(lastPart, (List) prop); } @SuppressWarnings("rawtypes") private static boolean containsProperty(String propName, List list) { //propName has to be an int int index = -1; try { index = Integer.parseInt(propName); } catch (NumberFormatException e) { //not an int return false; } //check if the list contains the property if (index >= 0 && index < list.size()){ //number available, check if value != null if (list.get(index) == null) { //no value return false; } } else { //index not found or too large return false; } //all tests passed return true; } @SuppressWarnings("rawtypes") private static boolean containsProperty(String propName, Map map) { if (map.containsKey(propName)) { if (map.get(propName) == null) { //no value available return false; } } else { //property not in map return false; } //all tests passed return true; } }