001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2008 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2016 ForgeRock AS. 016 */ 017package org.opends.server.controls; 018import org.forgerock.i18n.LocalizableMessage; 019 020 021 022import java.util.ArrayList; 023import java.io.IOException; 024import java.util.List; 025 026import org.forgerock.opendj.io.*; 027import org.forgerock.opendj.ldap.schema.AttributeType; 028import org.opends.server.types.*; 029import org.forgerock.opendj.ldap.ResultCode; 030import org.forgerock.opendj.ldap.ByteString; 031import org.forgerock.i18n.slf4j.LocalizedLogger; 032import static org.opends.messages.ProtocolMessages.*; 033import static org.opends.server.util.ServerConstants.*; 034import static org.opends.server.util.StaticUtils.*; 035 036 037 038/** 039 * This class implements the matched values control as defined in RFC 3876. It 040 * may be included in a search request to indicate that only attribute values 041 * matching one or more filters contained in the matched values control should 042 * be returned to the client. 043 */ 044public class MatchedValuesControl 045 extends Control 046{ 047 /** ControlDecoder implementation to decode this control from a ByteString. */ 048 private static final class Decoder 049 implements ControlDecoder<MatchedValuesControl> 050 { 051 @Override 052 public MatchedValuesControl decode(boolean isCritical, ByteString value) 053 throws DirectoryException 054 { 055 ArrayList<MatchedValuesFilter> filters; 056 if (value == null) 057 { 058 LocalizableMessage message = ERR_MATCHEDVALUES_NO_CONTROL_VALUE.get(); 059 throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message); 060 } 061 062 ASN1Reader reader = ASN1.getReader(value); 063 try 064 { 065 reader.readStartSequence(); 066 if (!reader.hasNextElement()) 067 { 068 LocalizableMessage message = ERR_MATCHEDVALUES_NO_FILTERS.get(); 069 throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message); 070 } 071 072 filters = new ArrayList<>(); 073 while(reader.hasNextElement()) 074 { 075 filters.add(MatchedValuesFilter.decode(reader)); 076 } 077 reader.readEndSequence(); 078 } 079 catch (DirectoryException e) 080 { 081 throw e; 082 } 083 catch (Exception e) 084 { 085 logger.traceException(e); 086 087 LocalizableMessage message = ERR_MATCHEDVALUES_CANNOT_DECODE_VALUE_AS_SEQUENCE.get( 088 getExceptionMessage(e)); 089 throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message); 090 } 091 092 return new MatchedValuesControl(isCritical,filters); 093 } 094 095 096 @Override 097 public String getOID() 098 { 099 return OID_MATCHED_VALUES; 100 } 101 102 } 103 104 /** The Control Decoder that can be used to decode this control. */ 105 public static final ControlDecoder<MatchedValuesControl> DECODER = 106 new Decoder(); 107 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 108 109 110 111 112 /** The set of matched values filters for this control. */ 113 private final List<MatchedValuesFilter> filters; 114 115 116 117 /** 118 * Creates a new matched values control using the default OID and the provided 119 * criticality and set of filters. 120 * 121 * @param isCritical Indicates whether this control should be considered 122 * critical to the operation processing. 123 * @param filters The set of filters to use to determine which values to 124 * return. 125 */ 126 public MatchedValuesControl(boolean isCritical, 127 List<MatchedValuesFilter> filters) 128 { 129 super(OID_MATCHED_VALUES, isCritical); 130 131 132 this.filters = filters; 133 } 134 135 @Override 136 public void writeValue(ASN1Writer writer) throws IOException { 137 writer.writeStartSequence(ASN1.UNIVERSAL_OCTET_STRING_TYPE); 138 139 writer.writeStartSequence(); 140 for (MatchedValuesFilter f : filters) 141 { 142 f.encode(writer); 143 } 144 writer.writeEndSequence(); 145 146 writer.writeEndSequence(); 147 } 148 149 150 /** 151 * Retrieves the set of filters associated with this matched values control. 152 * 153 * @return The set of filters associated with this matched values control. 154 */ 155 public List<MatchedValuesFilter> getFilters() 156 { 157 return filters; 158 } 159 160 161 162 /** 163 * Indicates whether any of the filters associated with this matched values 164 * control matches the provided attribute type/value. 165 * 166 * @param type The attribute type with which the value is associated. 167 * @param value The attribute value for which to make the determination. 168 * 169 * @return <CODE>true</CODE> if at least one of the filters associated with 170 * this matched values control does match the provided attribute 171 * value, or <CODE>false</CODE> if none of the filters match. 172 */ 173 public boolean valueMatches(AttributeType type, ByteString value) 174 { 175 for (MatchedValuesFilter f : filters) 176 { 177 try 178 { 179 if (f.valueMatches(type, value)) 180 { 181 return true; 182 } 183 } 184 catch (Exception e) 185 { 186 logger.traceException(e); 187 } 188 } 189 190 return false; 191 } 192 193 @Override 194 public void toString(StringBuilder buffer) 195 { 196 if (filters.size() == 1) 197 { 198 buffer.append("MatchedValuesControl(filter=\""); 199 filters.get(0).toString(buffer); 200 buffer.append("\")"); 201 } 202 else 203 { 204 buffer.append("MatchedValuesControl(filters=\"("); 205 206 for (MatchedValuesFilter f : filters) 207 { 208 f.toString(buffer); 209 } 210 211 buffer.append(")\")"); 212 } 213 } 214} 215