| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| */ |
| package org.apache.pirk.utils; |
| |
| import java.text.ParseException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Map; |
| import java.util.regex.Pattern; |
| |
| import org.apache.hadoop.io.MapWritable; |
| import org.apache.hadoop.io.Text; |
| import org.apache.pirk.inputformat.hadoop.TextArrayWritable; |
| import org.apache.pirk.schema.data.DataSchema; |
| import org.apache.pirk.schema.data.partitioner.IPDataPartitioner; |
| import org.elasticsearch.hadoop.mr.WritableArrayWritable; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * Class used for URI query parsing |
| * <p> |
| * Query of the form @{code ?q=<queryField>:<queryTerm>} |
| * <p> |
| * TODO: Use Lucene's query parsing?... Make this lots lots better... |
| * |
| */ |
| public class QueryParserUtils |
| { |
| private static final Logger logger = LoggerFactory.getLogger(QueryParserUtils.class); |
| |
| /** |
| * Given a URI query string, checks to see if the given document satisfies the query |
| * <p> |
| * ...Very hacky... |
| * <p> |
| * NOTE: Assumes that MapWritable keys are Text objects and values are Text or TextArrayWritable objects |
| * <p> |
| * NOTE: Support for list fields (values) is provided for checkRecord with Map<String, Object> and checkRecord with MapWritable containing |
| * WritableArrayWritable types for array values (vs. json string list representation) |
| * <p> |
| * NOTE: @ symbol represents flag ignore case sensitivity used after field (e.g. user_agent@:*searchparam*) |
| * <p> |
| * NOTE: Assumes that all AND booleans come before any OR booleans - ADD @ case sensitivity support for range queries |
| * |
| */ |
| public static boolean checkRecord(String uriQuery, MapWritable doc, DataSchema dataSchema) |
| { |
| boolean satisfiesQuery = true; |
| |
| logger.debug("uriQuery = " + uriQuery); |
| uriQuery = uriQuery.substring(3); // strip the beginning query tag '?q=' |
| logger.debug("uriQuery = " + uriQuery); |
| |
| if (uriQuery.equals("*")) |
| { |
| return true; |
| } |
| |
| String[] queryTokens = uriQuery.split("\\+(?=AND)|\\+(?=OR)|\\+(?=[a-z])"); // booleans of the form +AND+, +OR+, don't split on +T0+ |
| int index = 0; |
| String item; |
| while (index < queryTokens.length) |
| { |
| boolean ignoreCase = false; |
| |
| item = queryTokens[index]; |
| logger.debug("item = " + item); |
| |
| String[] itemTokens = item.split(":", 2); // There are two components <field>:<query> |
| logger.debug("itemTokens[0] = " + itemTokens[0] + " itemTokens[1] = " + itemTokens[1]); |
| |
| // check for ignore case flag |
| if (itemTokens[0].endsWith("@")) |
| { |
| ignoreCase = true; |
| logger.debug("ignore case = true"); |
| itemTokens[0] = itemTokens[0].replaceAll("@", ""); // strip flag |
| logger.debug("itemTokens[0]:" + itemTokens[0]); |
| } |
| |
| Object value = doc.get(new Text(itemTokens[0])); |
| if (value != null) // if the field is not present, a null Writable is returned |
| { |
| |
| if (itemTokens[1].startsWith("[")) // Inclusive range query |
| { |
| if (value instanceof Text) |
| { |
| if (!checkRangeQuery(true, itemTokens[0], itemTokens[1], value.toString(), dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned false"); |
| satisfiesQuery = false; |
| } |
| } |
| else if (value instanceof TextArrayWritable) |
| { |
| String[] elements = ((TextArrayWritable) value).toStrings(); |
| boolean oneSatisfied = false; |
| for (String element : elements) |
| { |
| if (checkRangeQuery(true, itemTokens[0], itemTokens[1], element, dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned true"); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| satisfiesQuery = oneSatisfied; |
| } |
| } |
| else if (itemTokens[1].startsWith("{")) // Exclusive range query |
| { |
| if (value instanceof Text) |
| { |
| if (!checkRangeQuery(false, itemTokens[0], itemTokens[1], value.toString(), dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned false"); |
| satisfiesQuery = false; |
| } |
| } |
| else if (value instanceof TextArrayWritable) |
| { |
| String[] elements = ((TextArrayWritable) value).toStrings(); |
| boolean oneSatisfied = false; |
| for (String element : elements) |
| { |
| if (checkRangeQuery(false, itemTokens[0], itemTokens[1], element, dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned true"); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| satisfiesQuery = oneSatisfied; |
| } |
| } |
| else |
| // Not a range query |
| { |
| if (value instanceof Text) |
| { |
| String valueString = value.toString(); |
| if (ignoreCase) |
| { // Case insensitivity |
| logger.debug("not a range query; itemstoken1:" + itemTokens[1]); |
| itemTokens[1] = itemTokens[1].toLowerCase(); |
| valueString = valueString.toLowerCase(); |
| logger.debug("valuestring after:" + valueString); |
| } |
| |
| if (itemTokens[1].contains("*") || itemTokens[1].contains("?")) // Wildcard match |
| { |
| logger.debug("itemTokens[1] = " + itemTokens[1] + " contains wildcard"); |
| if (!Pattern.matches(wildcardToRegex(itemTokens[1]), valueString)) |
| { |
| logger.debug("stringValue = " + valueString + " did not satisfy itemTokens[1] = " + itemTokens[1]); |
| satisfiesQuery = false; |
| } |
| logger.debug("stringValue = " + valueString + " did satisfy itemTokens[1] = " + itemTokens[1]); |
| } |
| else if (!(valueString).equals(itemTokens[1])) // Single value match |
| { |
| logger.debug("We do not have a single value match: stringValue " + valueString + " != itemTokens[1] = " + itemTokens[1]); |
| satisfiesQuery = false; |
| } |
| } |
| else if (value instanceof TextArrayWritable) |
| { |
| String[] elements = ((TextArrayWritable) value).toStrings(); |
| logger.debug("elements.size() = " + elements.length); |
| |
| boolean oneSatisfied = false; |
| for (String element : elements) |
| { |
| if (ignoreCase) |
| { // Case insensitivity |
| itemTokens[1] = itemTokens[1].toLowerCase(); |
| logger.debug("waw: itemtoken1 after:" + itemTokens[1]); |
| element = element.toLowerCase(); |
| logger.debug("element after:" + element); |
| } |
| |
| logger.debug("element: " + element); |
| if (itemTokens[1].contains("*") || itemTokens[1].contains("?")) // Wildcard match |
| { |
| logger.debug("itemTokens[1] = " + itemTokens[1] + " contains wildcard"); |
| if (Pattern.matches(wildcardToRegex(itemTokens[1]), element)) |
| { |
| logger.debug("stringValue = " + element + " satisfied itemTokens[1] = " + itemTokens[1]); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| else if (element.equals(itemTokens[1])) // Single value match |
| { |
| logger.debug("We have a single value match: stringValue " + element + " = itemTokens[1] = " + itemTokens[1]); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| satisfiesQuery = oneSatisfied; |
| } |
| } |
| } |
| else |
| { |
| satisfiesQuery = false; // add fix - account for case if query field does not exist |
| } |
| |
| ++index; // Try to pick up the boolean operators |
| if (index < (queryTokens.length - 1)) |
| { |
| if (queryTokens[index].equals("AND")) // Do nothing and keep going |
| { |
| if (!satisfiesQuery) |
| { |
| break; |
| } |
| ++index; |
| item = queryTokens[index]; |
| } |
| else if (queryTokens[index].equals("OR")) // Assume all OR's occur after all AND's |
| { |
| if (satisfiesQuery) // if we passed the query and it is not the first term |
| { |
| break; |
| } |
| else |
| { |
| ++index; |
| item = queryTokens[index]; |
| satisfiesQuery = true; // reset so that we pick up matches for the next term |
| } |
| } |
| else if (!satisfiesQuery) |
| { |
| logger.debug("Does not satisfy the query and no boolean ops next..."); |
| break; |
| } |
| } |
| } |
| |
| return satisfiesQuery; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public static boolean checkRecord(String uriQuery, Map<String,Object> doc, DataSchema dataSchema) |
| { |
| boolean satisfiesQuery = true; |
| |
| logger.debug("uriQuery = " + uriQuery); |
| uriQuery = uriQuery.substring(3); // strip the beginning query tag '?q=' |
| logger.debug("uriQuery = " + uriQuery); |
| |
| if (uriQuery.equals("*")) |
| { |
| return true; |
| } |
| |
| String[] queryTokens = uriQuery.split("\\+(?=AND)|\\+(?=OR)|\\+(?=[a-z])"); // booleans of the form +AND+, +OR+, don't split on +T0+ |
| int index = 0; |
| String item; |
| while (index < queryTokens.length) |
| { |
| item = queryTokens[index]; |
| logger.debug("item = " + item); |
| |
| String[] itemTokens = item.split(":", 2); // There are two components <field>:<query> |
| logger.debug("itemTokens[0] = " + itemTokens[0] + " itemTokens[1] = " + itemTokens[1]); |
| |
| boolean ignoreCase = false; |
| |
| // check for ignore case flag |
| if (itemTokens[0].endsWith("@")) |
| { |
| ignoreCase = true; |
| itemTokens[0] = itemTokens[0].replaceAll("@", ""); // strip case flag |
| logger.debug("ignore case: itemTokens[0] = " + itemTokens[0] + " itemTokens[1] = " + itemTokens[1]); |
| } |
| |
| Object value = doc.get(itemTokens[0]); // handle array answers |
| if (value != null) // if the field is not present, a null Writable is returned |
| { |
| if (itemTokens[1].startsWith("[")) // Inclusive range query |
| { |
| if (value instanceof String) |
| { |
| if (ignoreCase) |
| { // case insensitivity |
| itemTokens[1] = itemTokens[1].toLowerCase(); |
| value = value.toString().toLowerCase(); |
| } |
| |
| if (!checkRangeQuery(true, itemTokens[0], itemTokens[1], (String) value, dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned false"); |
| satisfiesQuery = false; |
| } |
| } |
| else if (value instanceof ArrayList) |
| { |
| boolean oneSatisfied = false; |
| for (String element : (ArrayList<String>) value) |
| { |
| if (checkRangeQuery(true, itemTokens[0], itemTokens[1], element, dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned true"); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| satisfiesQuery = oneSatisfied; |
| } |
| } |
| else if (itemTokens[1].startsWith("{")) // Exclusive range query |
| { |
| if (value instanceof String) |
| { |
| if (!checkRangeQuery(false, itemTokens[0], itemTokens[1], (String) value, dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned false"); |
| satisfiesQuery = false; |
| } |
| } |
| else if (value instanceof ArrayList) |
| { |
| |
| boolean oneSatisfied = false; |
| for (String element : (ArrayList<String>) value) |
| { |
| if (ignoreCase) |
| { |
| itemTokens[1] = itemTokens[1].toLowerCase(); |
| element = element.toLowerCase(); |
| } |
| if (checkRangeQuery(false, itemTokens[0], itemTokens[1], element, dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned true"); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| satisfiesQuery = oneSatisfied; |
| } |
| } |
| else |
| // Not a range query |
| { |
| if (value instanceof String) |
| { |
| if (ignoreCase) |
| { |
| itemTokens[1] = itemTokens[1].toLowerCase(); |
| value = value.toString().toLowerCase(); |
| } |
| |
| if (itemTokens[1].contains("*") || itemTokens[1].contains("?")) // Wildcard match |
| { |
| logger.debug("itemTokens[1] = " + itemTokens[1] + " contains wildcard"); |
| if (!Pattern.matches(wildcardToRegex(itemTokens[1]), (String) value)) |
| { |
| logger.debug("stringValue = " + value + " did not satisfy itemTokens[1] = " + itemTokens[1]); |
| satisfiesQuery = false; |
| } |
| logger.debug("stringValue = " + value + " did satisfy itemTokens[1] = " + itemTokens[1]); |
| } |
| else if (!(value).equals(itemTokens[1])) // Single value match |
| { |
| logger.debug("We do not have a single value match: stringValue " + value + " != itemTokens[1] = " + itemTokens[1]); |
| satisfiesQuery = false; |
| } |
| } |
| else if (value instanceof ArrayList) |
| { |
| boolean oneSatisfied = false; |
| for (String element : (ArrayList<String>) value) |
| { |
| logger.debug("element = " + element); |
| if (ignoreCase) |
| { // case insensitivity |
| itemTokens[1] = itemTokens[1].toLowerCase(); |
| element = element.toLowerCase(); |
| } |
| |
| if (itemTokens[1].contains("*") || itemTokens[1].contains("?")) // Wildcard match |
| { |
| logger.debug("itemTokens[1] = " + itemTokens[1] + " contains wildcard"); |
| if (Pattern.matches(wildcardToRegex(itemTokens[1]), element)) |
| { |
| logger.debug("stringValue = " + element + " satisfied itemTokens[1] = " + itemTokens[1]); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| else if (element.equals(itemTokens[1])) // Single value match |
| { |
| logger.debug("We have a single value match: stringValue " + element + " = itemTokens[1] = " + itemTokens[1]); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| satisfiesQuery = oneSatisfied; |
| } |
| } |
| } |
| else |
| { // added fix: If the value is null (the requested field did not appear in the data) |
| satisfiesQuery = false; |
| } |
| ++index; // Try to pick up the boolean operators |
| if (index < (queryTokens.length - 1)) |
| { |
| if (queryTokens[index].equals("AND")) // Do nothing and keep going |
| { |
| if (!satisfiesQuery) |
| { |
| break; |
| } |
| ++index; |
| item = queryTokens[index]; |
| } |
| else if (queryTokens[index].equals("OR")) // Assume all OR's occur after all AND's |
| { |
| if (satisfiesQuery && (index != 1)) // if we passed the query and it is not the first term |
| { |
| break; |
| } |
| else |
| { |
| ++index; |
| item = queryTokens[index]; |
| satisfiesQuery = true; // reset so that we pick up matches for the next term |
| } |
| } |
| else if (!satisfiesQuery) |
| { |
| logger.debug("Does not satisfy the query and no boolean ops next..."); |
| break; |
| } |
| } |
| } |
| |
| return satisfiesQuery; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public static boolean checkRecordWritableArrayWritable(String uriQuery, MapWritable doc, DataSchema dataSchema) |
| { |
| boolean satisfiesQuery = true; |
| |
| logger.debug("uriQuery = " + uriQuery); |
| uriQuery = uriQuery.substring(3); // strip the beginning query tag '?q=' |
| logger.debug("uriQuery = " + uriQuery); |
| |
| if (uriQuery.equals("*")) |
| { |
| return true; |
| } |
| |
| String[] queryTokens = uriQuery.split("\\+(?=AND)|\\+(?=OR)|\\+(?=[a-z])"); // booleans of the form +AND+, +OR+, don't split on +T0+ |
| int index = 0; |
| String item; |
| while (index < queryTokens.length) |
| { |
| boolean ignoreCase = false; |
| |
| item = queryTokens[index]; |
| logger.debug("item = " + item); |
| |
| String[] itemTokens = item.split(":", 2); // There are two components <field>:<query> |
| logger.debug("itemTokens[0] = " + itemTokens[0] + " itemTokens[1] = " + itemTokens[1]); |
| |
| // check for ignore case flag |
| if (itemTokens[0].endsWith("@")) |
| { |
| ignoreCase = true; |
| logger.debug("ignore case = true"); |
| itemTokens[0] = itemTokens[0].replaceAll("@", ""); // strip flag |
| logger.debug("itemTokens[0]:" + itemTokens[0]); |
| } |
| |
| Object value = doc.get(new Text(itemTokens[0])); |
| if (value != null) // if the field is not present, a null Writable is returned |
| { |
| |
| if (itemTokens[1].startsWith("[")) // Inclusive range query |
| { |
| if (value instanceof Text) |
| { |
| if (!checkRangeQuery(true, itemTokens[0], itemTokens[1], value.toString(), dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned false"); |
| satisfiesQuery = false; |
| } |
| } |
| else if (value instanceof WritableArrayWritable) |
| { |
| String[] elements = ((WritableArrayWritable) value).toStrings(); |
| boolean oneSatisfied = false; |
| for (String element : elements) |
| { |
| if (checkRangeQuery(true, itemTokens[0], itemTokens[1], element, dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned true"); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| satisfiesQuery = oneSatisfied; |
| } |
| } |
| else if (itemTokens[1].startsWith("{")) // Exclusive range query |
| { |
| if (value instanceof Text) |
| { |
| if (!checkRangeQuery(false, itemTokens[0], itemTokens[1], value.toString(), dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned false"); |
| satisfiesQuery = false; |
| } |
| } |
| else if (value instanceof WritableArrayWritable) |
| { |
| String[] elements = ((WritableArrayWritable) value).toStrings(); |
| boolean oneSatisfied = false; |
| for (String element : elements) |
| { |
| if (checkRangeQuery(false, itemTokens[0], itemTokens[1], element, dataSchema)) |
| { |
| logger.debug("checkRangeQuery returned true"); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| satisfiesQuery = oneSatisfied; |
| } |
| } |
| else |
| // Not a range query |
| { |
| if (value instanceof Text) |
| { |
| String valueString = value.toString(); |
| if (ignoreCase) |
| { // Case insensitivity |
| logger.debug("not a range query; itemstoken1:" + itemTokens[1]); |
| itemTokens[1] = itemTokens[1].toLowerCase(); |
| valueString = valueString.toLowerCase(); |
| logger.debug("valuestring after:" + valueString); |
| } |
| |
| if (itemTokens[1].contains("*") || itemTokens[1].contains("?")) // Wildcard match |
| { |
| logger.debug("itemTokens[1] = " + itemTokens[1] + " contains wildcard"); |
| if (!Pattern.matches(wildcardToRegex(itemTokens[1]), valueString)) |
| { |
| logger.debug("stringValue = " + valueString + " did not satisfy itemTokens[1] = " + itemTokens[1]); |
| satisfiesQuery = false; |
| } |
| logger.debug("stringValue = " + valueString + " did satisfy itemTokens[1] = " + itemTokens[1]); |
| } |
| else if (!(valueString).equals(itemTokens[1])) // Single value match |
| { |
| logger.debug("We do not have a single value match: stringValue " + valueString + " != itemTokens[1] = " + itemTokens[1]); |
| satisfiesQuery = false; |
| } |
| } |
| else if (value instanceof WritableArrayWritable) |
| { |
| String[] elements = ((WritableArrayWritable) value).toStrings(); |
| logger.debug("elements.size() = " + elements.length); |
| |
| boolean oneSatisfied = false; |
| for (String element : elements) |
| { |
| if (ignoreCase) |
| { // Case insensitivity |
| itemTokens[1] = itemTokens[1].toLowerCase(); |
| logger.debug("waw: itemtoken1 after:" + itemTokens[1]); |
| element = element.toLowerCase(); |
| logger.debug("element after:" + element); |
| } |
| |
| logger.debug("element: " + element); |
| if (itemTokens[1].contains("*") || itemTokens[1].contains("?")) // Wildcard match |
| { |
| logger.debug("itemTokens[1] = " + itemTokens[1] + " contains wildcard"); |
| if (Pattern.matches(wildcardToRegex(itemTokens[1]), element)) |
| { |
| logger.debug("stringValue = " + element + " satisfied itemTokens[1] = " + itemTokens[1]); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| else if (element.equals(itemTokens[1])) // Single value match |
| { |
| logger.debug("We have a single value match: stringValue " + element + " = itemTokens[1] = " + itemTokens[1]); |
| oneSatisfied = true; |
| break; |
| } |
| } |
| satisfiesQuery = oneSatisfied; |
| } |
| } |
| } |
| else |
| { |
| satisfiesQuery = false; // add fix - account for case if query field does not exist |
| } |
| |
| ++index; // Try to pick up the boolean operators |
| if (index < (queryTokens.length - 1)) |
| { |
| if (queryTokens[index].equals("AND")) // Do nothing and keep going |
| { |
| if (!satisfiesQuery) |
| { |
| break; |
| } |
| ++index; |
| item = queryTokens[index]; |
| } |
| else if (queryTokens[index].equals("OR")) // Assume all OR's occur after all AND's |
| { |
| if (satisfiesQuery) // if we passed the query and it is not the first term |
| { |
| break; |
| } |
| else |
| { |
| ++index; |
| item = queryTokens[index]; |
| satisfiesQuery = true; // reset so that we pick up matches for the next term |
| } |
| } |
| else if (!satisfiesQuery) |
| { |
| logger.debug("Does not satisfy the query and no boolean ops next..."); |
| break; |
| } |
| } |
| } |
| |
| return satisfiesQuery; |
| } |
| |
| /** |
| * Method to handle ranges queries |
| * |
| */ |
| public static boolean checkRangeQuery(boolean inclusive, String field, String query, String value, DataSchema dataSchema) |
| { |
| boolean matches = true; |
| |
| logger.info("inclusive = " + inclusive + " field = " + field + " query = " + query + " value = " + value); |
| |
| // Strip the brackets or braces to obtain query form <lower>+TO+<upper> |
| if (inclusive) |
| { |
| query = query.replaceFirst("\\[", ""); |
| query = query.replaceFirst("\\]", ""); |
| } |
| else |
| { |
| query = query.replaceFirst("\\{", ""); |
| query = query.replaceFirst("\\}", ""); |
| } |
| logger.debug("query = " + query); |
| |
| // Special case for IPs |
| if (dataSchema.getPartitionerTypeName(field).equals(IPDataPartitioner.class.getName())) // Doesn't handle arrays of IPs in the value right now... |
| { |
| logger.debug("Have IP Field"); |
| |
| String[] ranges = query.split("\\+TO\\+"); |
| logger.info("ranges[0] = " + ranges[0] + " ranges[1] = " + ranges[1]); |
| |
| if ((!inclusive) && (value.equals(ranges[0]) || value.equals(ranges[1]))) |
| { |
| logger.debug("inclusive = false and either value.equals(ranges[0]) or value.equals(ranges[1])"); |
| matches = false; |
| } |
| else |
| { |
| String[] blocksLower = ranges[0].split("\\."); |
| String[] blocksUpper = ranges[1].split("\\."); |
| String[] ipValue = value.split("\\."); |
| int ipBlock = 0; |
| while (ipBlock < 4) |
| { |
| logger.info("ipBlock = " + ipBlock + " ipValue[ipBlock] = " + ipValue[ipBlock] + " blocksLower[ipBlock] = " + blocksLower[ipBlock] |
| + " blocksUpper[ipBlock] = " + blocksUpper[ipBlock]); |
| |
| if (blocksLower[ipBlock].equals(blocksUpper[ipBlock])) |
| { |
| logger.info("blocksLower[ipBlock].equals(blocksUpper[ipBlock])"); |
| if (!ipValue[ipBlock].equals(blocksLower[ipBlock])) |
| { |
| logger.info("!ipValue[ipBlock].equals(blocksLower[ipBlock]"); |
| matches = false; |
| } |
| } |
| else |
| { |
| if (!((Integer.parseInt(blocksLower[ipBlock]) <= Integer.parseInt(ipValue[ipBlock])) |
| && (Integer.parseInt(ipValue[ipBlock]) <= Integer.parseInt(blocksUpper[ipBlock])))) |
| { |
| logger.info("IP block not within given range"); |
| matches = false; |
| } |
| } |
| ++ipBlock; |
| } |
| } |
| } |
| else if (field.equals("date"))// Special case for ISO8601 dates & Epoch Dates |
| { |
| String[] ranges = query.split("\\+TO\\+"); |
| logger.info("query:" + query); |
| logger.info("value:" + value); |
| logger.info("ranges[0] = " + ranges[0] + " ranges[1] = " + ranges[1]); |
| |
| // code to parse epoch time: VacantArmy |
| if ((EpochDateParser.isEpochDateFormat(ranges[0]) || EpochDateParser.isEpochDateSearchFormat(ranges[0])) |
| && (EpochDateParser.isEpochDateFormat(ranges[1]) || EpochDateParser.isEpochDateSearchFormat(ranges[1]))) |
| { |
| double fromDate = 0; |
| double toDate = 0; |
| double valueDate = 0; |
| |
| long fromSeconds = 0; |
| long fromMilli = 0; |
| long toSeconds = 0; |
| long toMilli = 0; |
| |
| try |
| { |
| |
| fromDate = EpochDateParser.convertSearchDate(ranges[0]); |
| toDate = EpochDateParser.convertSearchDate(ranges[1]); |
| valueDate = Double.parseDouble(value); |
| |
| logger.debug("fromDate:" + fromDate); |
| logger.debug("toDate:" + toDate); |
| logger.debug("valueDate:" + valueDate); |
| |
| // split up seconds & milliseconds...keep? needed?? |
| String[] fromDateArr = ranges[0].split("\\."); |
| fromSeconds = Integer.parseInt(fromDateArr[0]); |
| fromMilli = Integer.parseInt(fromDateArr[1]); |
| |
| String[] toDateArr = ranges[1].split("\\."); |
| toSeconds = Integer.parseInt(toDateArr[0]); |
| toMilli = Integer.parseInt(toDateArr[1]); |
| } catch (Exception e) |
| { |
| logger.info(Arrays.toString(e.getStackTrace())); |
| } |
| |
| if ((!inclusive) && (fromDate == valueDate || toDate == valueDate)) |
| { |
| logger.debug("(inclusive == false) && (fromDate == valueDate || toDate == valueDate))"); |
| matches = false; |
| } |
| else |
| { |
| if (!((fromDate <= valueDate) && (valueDate <= toDate))) |
| { |
| logger.debug("valueDate = " + valueDate + " out of range: <" + fromDate + "," + toDate + ">"); |
| matches = false; |
| } |
| } |
| } |
| else |
| { // Special case for ISO8061 dates |
| long lower = 0; |
| long upper = 0; |
| long valueDate = 0; |
| try |
| { |
| lower = ISO8601DateParser.getLongDate(ranges[0]); |
| upper = ISO8601DateParser.getLongDate(ranges[1]); |
| valueDate = ISO8601DateParser.getLongDate(value); |
| } catch (ParseException e) |
| { |
| e.printStackTrace(); |
| } |
| if ((!inclusive) && (lower == valueDate || upper == valueDate)) |
| { |
| logger.debug("(inclusive == false) && (lower == valueDate || upper == valueDate))"); |
| matches = false; |
| } |
| else |
| { |
| if (!((lower <= valueDate) && (valueDate <= upper))) |
| { |
| logger.debug("valueDate = " + valueDate + " out of range: <" + lower + "," + upper + ">"); |
| matches = false; |
| } |
| } |
| logger.debug("valueDate = " + valueDate + " in range: <" + lower + "," + upper + ">"); |
| |
| } |
| } |
| else |
| // Int |
| { |
| |
| String[] ranges = query.split("\\+TO\\+"); |
| |
| // check for ints |
| // if (ranges[0].matches("\\d+") && ranges[1].matches("\\d+")){ //int range |
| int lower = Integer.parseInt(ranges[0]); |
| int upper = Integer.parseInt(ranges[1]); |
| int valueInt = Integer.parseInt(value); |
| logger.debug("valueInt = " + valueInt + " lower = " + lower + " upper = " + upper); |
| |
| if ((!inclusive) && (lower == valueInt || upper == valueInt)) |
| { |
| logger.debug("(inclusive == false) && (lower == valueInt || upper == valueInt))"); |
| matches = false; |
| } |
| else |
| { |
| if (!((lower <= valueInt) && (valueInt <= upper))) |
| { |
| logger.debug("valueInt = " + valueInt + " out of range: <" + lower + "," + upper + ">"); |
| matches = false; |
| } |
| } |
| logger.debug("valueInt = " + valueInt + " in range: <" + lower + "," + upper + ">"); |
| } |
| |
| return matches; |
| } |
| |
| /** |
| * Method to convert a URI wildcard query into a java regex |
| * |
| */ |
| public static String wildcardToRegex(String wildcard) |
| { |
| StringBuilder s = new StringBuilder(wildcard.length()); |
| for (int i = 0, is = wildcard.length(); i < is; i++) |
| { |
| char c = wildcard.charAt(i); |
| switch (c) |
| { |
| case '*': |
| s.append(".*"); |
| break; |
| case '?': |
| s.append("."); |
| break; |
| // escape special regexp-characters |
| case '(': |
| case ')': |
| case '[': |
| case ']': |
| case '$': |
| case '^': |
| case '.': |
| case '{': |
| case '}': |
| case '|': |
| case '\\': |
| s.append("\\"); |
| s.append(c); |
| break; |
| default: |
| s.append(c); |
| break; |
| } |
| } |
| logger.debug("regex = " + s.toString()); |
| |
| return (s.toString()); |
| } |
| } |