/* * 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.harmony.jndi.provider.ldap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.InvalidSearchFilterException; import javax.naming.directory.SearchResult; import org.apache.harmony.jndi.internal.nls.Messages; import org.apache.harmony.jndi.internal.parser.AttributeTypeAndValuePair; import org.apache.harmony.jndi.provider.ldap.Filter.SubstringFilter; import org.apache.harmony.jndi.provider.ldap.asn1.ASN1ChoiceWrap.ChosenValue; import org.apache.harmony.jndi.provider.ldap.parser.FilterParser; import org.apache.harmony.jndi.provider.ldap.parser.ParseException; public class LdapSchemaFilter { private Filter commonFilter; public LdapSchemaFilter(String filterValue, Object[] filterArgs) throws InvalidSearchFilterException { try { FilterParser commonFilterParser = new FilterParser(filterValue); commonFilterParser.setArgs(filterArgs); commonFilter = commonFilterParser.parse(); } catch (ParseException e) { // ldap.29=Invalid search filter throw new InvalidSearchFilterException(Messages .getString("ldap.29")); //$NON-NLS-1$ } } public HashSet<SearchResult> filter( HashSet<SearchResult> results) throws NamingException { return doFilter(results, commonFilter); } private HashSet<SearchResult> doFilter( HashSet<SearchResult> currentResults, Filter filter) throws NamingException { List<Filter> filters; HashSet<SearchResult> filteredResults = null; HashSet<SearchResult> tempResults; Iterator<SearchResult> iterator; AttributeTypeAndValuePair pair; String attributeType; Object attributeValue; SearchResult searchResult; Attribute attr; NamingEnumeration<?> valuesEnum; Object value; boolean hasMatch; switch (filter.getType()) { case Filter.AND_FILTER: filteredResults = currentResults; filters = filter.getChildren(); for (int i = 0; i < filters.size(); i++) { filteredResults = doFilter(filteredResults, filters.get(i)); } break; case Filter.OR_FILTER: filters = filter.getChildren(); filteredResults = new HashSet<SearchResult>(); for (int i = 0; i < filters.size(); i++) { tempResults = doFilter(currentResults, filters.get(i)); filteredResults.addAll(tempResults); } break; case Filter.NOT_FILTER: filteredResults = new HashSet<SearchResult>(); Filter tempFilter = (Filter) filter.getValue(); tempResults = doFilter(currentResults, tempFilter); iterator = currentResults.iterator(); while (iterator.hasNext()) { searchResult = iterator.next(); if (!tempResults.contains(searchResult)) { filteredResults.add(searchResult); } } break; case Filter.EQUALITY_MATCH_FILTER: case Filter.APPROX_MATCH_FILTER: filteredResults = new HashSet<SearchResult>(); pair = (AttributeTypeAndValuePair) filter.getValue(); attributeType = pair.getType(); attributeValue = pair.getValue(); iterator = currentResults.iterator(); while (iterator.hasNext()) { searchResult = iterator.next(); attr = searchResult.getAttributes().get(attributeType); if (attr != null) { hasMatch = false; valuesEnum = attr.getAll(); while (valuesEnum.hasMore()) { value = valuesEnum.next(); if (attributeValue.toString().equalsIgnoreCase( value.toString())) { hasMatch = true; } } if (hasMatch) { filteredResults.add(searchResult); } } } break; case Filter.SUBSTRINGS_FILTER: filteredResults = new HashSet<SearchResult>(); SubstringFilter substringFilter = (SubstringFilter) filter .getValue(); attributeType = substringFilter.getType(); List<ChosenValue> list = substringFilter.getSubstrings(); String attributePatternValue = ""; //$NON-NLS-1$ for (int i = 0; i < list.size(); i++) { attributePatternValue += list.get(i).getValue().toString(); } attributePatternValue = attributePatternValue.replaceAll("\\*", //$NON-NLS-1$ ".*"); //$NON-NLS-1$ Pattern pattern = Pattern.compile(attributePatternValue, Pattern.CASE_INSENSITIVE); iterator = currentResults.iterator(); while (iterator.hasNext()) { searchResult = iterator.next(); attr = searchResult.getAttributes().get(attributeType); if (attr != null) { hasMatch = false; valuesEnum = attr.getAll(); while (valuesEnum.hasMore()) { value = valuesEnum.next(); if (pattern.matcher(value.toString()).matches()) { hasMatch = true; } } if (hasMatch) { filteredResults.add(searchResult); } } } break; case Filter.GREATER_OR_EQUAL_FILTER: filteredResults = new HashSet<SearchResult>(); pair = (AttributeTypeAndValuePair) filter.getValue(); attributeType = pair.getType(); attributeValue = pair.getValue(); iterator = currentResults.iterator(); while (iterator.hasNext()) { searchResult = iterator.next(); attr = searchResult.getAttributes().get(attributeType); if (attr != null) { hasMatch = false; valuesEnum = attr.getAll(); while (valuesEnum.hasMore()) { value = valuesEnum.next(); if ((value.toString().compareTo(attributeValue .toString())) >= 0) { hasMatch = true; } } if (hasMatch) { filteredResults.add(searchResult); } } } break; case Filter.LESS_OR_EQUAL_FILTER: filteredResults = new HashSet<SearchResult>(); pair = (AttributeTypeAndValuePair) filter.getValue(); attributeType = pair.getType(); attributeValue = pair.getValue(); iterator = currentResults.iterator(); while (iterator.hasNext()) { searchResult = iterator.next(); attr = searchResult.getAttributes().get(attributeType); if (attr != null) { hasMatch = false; valuesEnum = attr.getAll(); while (valuesEnum.hasMore()) { value = valuesEnum.next(); if ((value.toString().compareTo(attributeValue .toString())) <= 0) { hasMatch = true; } } if (hasMatch) { filteredResults.add(searchResult); } } } break; case Filter.PRESENT_FILTER: filteredResults = new HashSet<SearchResult>(); attributeType = filter.getValue().toString(); iterator = currentResults.iterator(); while (iterator.hasNext()) { searchResult = iterator.next(); attr = searchResult.getAttributes().get(attributeType); if (attr != null) { filteredResults.add(searchResult); } } break; case Filter.EXTENSIBLE_MATCH_FILTER: // TODO break; default: // Never reach here. } return filteredResults; } }