001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.activemq.console.filter; 018 019 import java.util.ArrayList; 020 import java.util.HashMap; 021 import java.util.Iterator; 022 import java.util.List; 023 import java.util.Map; 024 import java.util.regex.Pattern; 025 026 public abstract class RegExQueryFilter extends AbstractQueryFilter { 027 public static final String REGEX_PREFIX = "REGEX:QUERY:"; 028 029 /** 030 * Creates a regular expression query that is able to match an object using 031 * key-value pattern regex filtering 032 * 033 * @param next 034 */ 035 protected RegExQueryFilter(QueryFilter next) { 036 super(next); 037 } 038 039 /** 040 * Separates the regular expressions queries from the usual queries. A query 041 * is a regex query, if it is key-value pair with the format <key>=<value>, 042 * and value is a pattern that satisfies the isRegularExpression method. 043 * 044 * @param queries - list of queries 045 * @return filtered objects that matches the regex query 046 * @throws Exception 047 */ 048 public List query(List queries) throws Exception { 049 Map regex = new HashMap(); 050 List newQueries = new ArrayList(); 051 052 // Lets parse for regular expression queries 053 for (Iterator i = queries.iterator(); i.hasNext();) { 054 // Get key-value pair 055 String token = (String)i.next(); 056 String key = ""; 057 String val = ""; 058 int pos = token.indexOf("="); 059 if (pos >= 0) { 060 val = token.substring(pos + 1); 061 key = token.substring(0, pos); 062 } 063 064 // Add the regex query to list and make it a non-factor in the 065 // succeeding queries 066 if (isRegularExpression(val)) { 067 regex.put(key, compileQuery(val)); 068 069 // Add the normal query to the query list 070 } else { 071 newQueries.add(token); 072 } 073 } 074 075 // Filter the result using the regular expressions specified 076 return filterCollectionUsingRegEx(regex, next.query(newQueries)); 077 } 078 079 /** 080 * Checks if a given string is a regular expression query. Currently, a 081 * pattern is a regex query, if it starts with the 082 * RegExQueryFilter.REGEX_PREFIX. 083 * 084 * @param query 085 * @return 086 */ 087 protected boolean isRegularExpression(String query) { 088 return query.startsWith(REGEX_PREFIX); 089 } 090 091 /** 092 * Compiles the regex query to a pattern. 093 * 094 * @param query - query string to compile 095 * @return regex pattern 096 */ 097 protected Pattern compileQuery(String query) { 098 return Pattern.compile(query.substring(REGEX_PREFIX.length())); 099 } 100 101 /** 102 * Filter the specified colleciton using the regex patterns extracted. 103 * 104 * @param regex - regex map 105 * @param data - list of objects to filter 106 * @return filtered list of objects that matches the regex map 107 * @throws Exception 108 */ 109 protected List filterCollectionUsingRegEx(Map regex, List data) throws Exception { 110 // No regular expressions filtering needed 111 if (regex == null || regex.isEmpty()) { 112 return data; 113 } 114 115 List filteredElems = new ArrayList(); 116 117 // Get each data object to filter 118 for (Iterator i = data.iterator(); i.hasNext();) { 119 Object dataElem = i.next(); 120 // If properties of data matches all the regex pattern, add it 121 if (matches(dataElem, regex)) { 122 filteredElems.add(dataElem); 123 } 124 } 125 126 return filteredElems; 127 } 128 129 /** 130 * Determines how the object is to be matched to the regex map. 131 * 132 * @param data - object to match 133 * @param regex - regex map 134 * @return true, if the object matches the regex map, false otherwise 135 * @throws Exception 136 */ 137 protected abstract boolean matches(Object data, Map regex) throws Exception; 138 }