001 /* 002 * Copyright 2009-2015 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005 /* 006 * Copyright (C) 2015 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021 package com.unboundid.ldap.sdk.unboundidds.controls; 022 023 024 025 import com.unboundid.asn1.ASN1Element; 026 import com.unboundid.asn1.ASN1OctetString; 027 import com.unboundid.ldap.sdk.Control; 028 import com.unboundid.ldap.sdk.LDAPException; 029 import com.unboundid.ldap.sdk.ResultCode; 030 import com.unboundid.util.NotMutable; 031 import com.unboundid.util.ThreadSafety; 032 import com.unboundid.util.ThreadSafetyLevel; 033 034 import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*; 035 import static com.unboundid.util.Debug.*; 036 import static com.unboundid.util.StaticUtils.*; 037 038 039 040 /** 041 * <BLOCKQUOTE> 042 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID 043 * LDAP SDK for Java. It is not available for use in applications that 044 * include only the Standard Edition of the LDAP SDK, and is not supported for 045 * use in conjunction with non-UnboundID products. 046 * </BLOCKQUOTE> 047 * This class provides an implementation of an LDAP control which can be 048 * included in a search request to indicate that search result entries should be 049 * returned along with related entries based on a given set of criteria, much 050 * like an SQL join in a relational database. 051 * <BR><BR> 052 * <H2>Example</H2> 053 * Consider the case in which user entries include an account number, but 054 * additional information about those accounts are available in separate 055 * entries. If you wish to retrieve both the user and account entries for a 056 * user given only a user ID, then you may accomplish that using the join 057 * request control as follows: 058 * <PRE> 059 * SearchRequest searchRequest = new SearchRequest( 060 * "ou=People,dc=example,dc=com", SearchScope.SUB, 061 * Filter.createEqualityFilter("uid", userID)); 062 * searchRequest.addControl(new JoinRequestControl(new JoinRequestValue( 063 * JoinRule.createEqualityJoin("accountNumber", "accountNumber", false), 064 * JoinBaseDN.createUseCustomBaseDN("ou=Accounts,dc=example,dc=com"), 065 * SearchScope.SUB, DereferencePolicy.NEVER, null, 066 * Filter.createEqualityFilter("objectClass", "accountEntry"), 067 * new String[0], false, null))); 068 * SearchResult searchResult = connection.search(searchRequest); 069 * 070 * for (SearchResultEntry userEntry : searchResult.getSearchEntries()) 071 * { 072 * JoinResultControl c = JoinResultControl.get(userEntry); 073 * for (JoinedEntry accountEntry : c.getJoinResults()) 074 * { 075 * // User userEntry was joined with account accountEntry 076 * } 077 * } 078 * </PRE> 079 */ 080 @NotMutable() 081 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 082 public final class JoinRequestControl 083 extends Control 084 { 085 /** 086 * The OID (1.3.6.1.4.1.30221.2.5.9) for the join request control. 087 */ 088 public static final String JOIN_REQUEST_OID = "1.3.6.1.4.1.30221.2.5.9"; 089 090 091 092 /** 093 * The serial version UID for this serializable class. 094 */ 095 private static final long serialVersionUID = -1321645105838145996L; 096 097 098 099 // The join request value for this control. 100 private final JoinRequestValue joinRequestValue; 101 102 103 104 /** 105 * Creates a new join request control with the provided join request value. 106 * 107 * @param joinRequestValue The join request value to use for this control. 108 */ 109 public JoinRequestControl(final JoinRequestValue joinRequestValue) 110 { 111 super(JOIN_REQUEST_OID, true, 112 new ASN1OctetString(joinRequestValue.encode().encode())); 113 114 this.joinRequestValue = joinRequestValue; 115 } 116 117 118 119 /** 120 * Creates a new join request control which is decoded from the provided 121 * generic control. 122 * 123 * @param control The generic control to be decoded as a join request 124 * control. 125 * 126 * @throws LDAPException If the provided control cannot be decoded as a 127 * virtual attributes only request control. 128 */ 129 public JoinRequestControl(final Control control) 130 throws LDAPException 131 { 132 super(control); 133 134 final ASN1OctetString value = control.getValue(); 135 if (value == null) 136 { 137 throw new LDAPException(ResultCode.DECODING_ERROR, 138 ERR_JOIN_REQUEST_CONTROL_NO_VALUE.get()); 139 } 140 141 final ASN1Element valueElement; 142 try 143 { 144 valueElement = ASN1Element.decode(value.getValue()); 145 } 146 catch (Exception e) 147 { 148 debugException(e); 149 150 throw new LDAPException(ResultCode.DECODING_ERROR, 151 ERR_JOIN_REQUEST_VALUE_CANNOT_DECODE.get(getExceptionMessage(e)), e); 152 } 153 154 joinRequestValue = JoinRequestValue.decode(valueElement); 155 } 156 157 158 159 /** 160 * Retrieves the join request value for this join request control. 161 * 162 * @return The join request value for this join request control. 163 */ 164 public JoinRequestValue getJoinRequestValue() 165 { 166 return joinRequestValue; 167 } 168 169 170 171 /** 172 * {@inheritDoc} 173 */ 174 @Override() 175 public String getControlName() 176 { 177 return INFO_CONTROL_NAME_JOIN_REQUEST.get(); 178 } 179 180 181 182 /** 183 * {@inheritDoc} 184 */ 185 @Override() 186 public void toString(final StringBuilder buffer) 187 { 188 buffer.append("JoinRequestControl(value="); 189 joinRequestValue.toString(buffer); 190 buffer.append(')'); 191 } 192 }