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 2012-2014 ForgeRock AS. 016 */ 017package org.opends.dsml.protocol; 018 019 020 021import java.io.IOException; 022import java.util.List; 023import java.util.Set; 024 025import org.forgerock.i18n.LocalizableMessage; 026import org.forgerock.opendj.ldap.DecodeException; 027import org.opends.server.protocols.ldap.ExtendedRequestProtocolOp; 028import org.opends.server.protocols.ldap.ExtendedResponseProtocolOp; 029import org.opends.server.protocols.ldap.LDAPMessage; 030import org.opends.server.protocols.ldap.ProtocolOp; 031import org.opends.server.tools.LDAPConnection; 032import org.forgerock.opendj.ldap.ByteString; 033import org.opends.server.types.LDAPException; 034 035 036/** 037 * This class provides the functionality for the performing an 038 * LDAP EXTENDED operation based on the specified DSML request. 039 */ 040public class DSMLExtendedOperation 041{ 042 private LDAPConnection connection; 043 private Set<String> stringResponses; 044 045 /** 046 * Create an instance with the specified LDAP connection. 047 * 048 * @param connection The LDAP connection to send the request on. 049 * @param stringResponses The OIDs of any operations that have results that 050 * should be returned as strings instead of binary. 051 */ 052 public DSMLExtendedOperation(LDAPConnection connection, 053 Set<String> stringResponses) 054 { 055 this.connection = connection; 056 this.stringResponses = stringResponses; 057 } 058 059 060 061 /** 062 * Determine if the response to a given LDAP extended operation (specified by 063 * OID) should be treated as a string. The default is binary. 064 * 065 * @param oid The OID of the extended operation. 066 * @return <CODE>true</CODE> if the extended operation is known to return a 067 * string, <CODE>false</CODE> otherwise. 068 */ 069 public boolean responseIsString(String oid) 070 { 071 return stringResponses.contains(oid); 072 } 073 074 075 076 /** 077 * Perform the LDAP EXTENDED operation and send the result back to the 078 * client. 079 * 080 * @param objFactory The object factory for this operation. 081 * @param extendedRequest The extended request for this operation. 082 * @param controls Any required controls (e.g. for proxy authz). 083 * 084 * @return The result of the extended operation. 085 * 086 * @throws IOException If an I/O problem occurs. 087 * 088 * @throws LDAPException If an error occurs while interacting with an LDAP 089 * element. 090 * 091 * @throws DecodeException If an error occurs while interacting with an ASN.1 092 * element. 093 */ 094 public ExtendedResponse doOperation(ObjectFactory objFactory, 095 ExtendedRequest extendedRequest, 096 List<org.opends.server.types.Control> controls) 097 throws IOException, LDAPException, DecodeException 098 { 099 ExtendedResponse extendedResponse = objFactory.createExtendedResponse(); 100 extendedResponse.setRequestID(extendedRequest.getRequestID()); 101 102 String requestName = extendedRequest.getRequestName(); 103 Object value = extendedRequest.getRequestValue(); 104 ByteString asnValue = ByteStringUtility.convertValue(value); 105 106 // Create and send the LDAP request to the server. 107 ProtocolOp op = new ExtendedRequestProtocolOp(requestName, asnValue); 108 LDAPMessage msg = new LDAPMessage(DSMLServlet.nextMessageID(), op, 109 controls); 110 connection.getLDAPWriter().writeMessage(msg); 111 112 // Read and decode the LDAP response from the server. 113 LDAPMessage responseMessage = connection.getLDAPReader().readMessage(); 114 115 ExtendedResponseProtocolOp extendedOp = 116 responseMessage.getExtendedResponseProtocolOp(); 117 int resultCode = extendedOp.getResultCode(); 118 LocalizableMessage errorMessage = extendedOp.getErrorMessage(); 119 120 // Set the result code and error message for the DSML response. 121 extendedResponse.setResponseName(extendedOp.getOID()); 122 123 ByteString rawValue = extendedOp.getValue(); 124 value = null; 125 if (rawValue != null) 126 { 127 if (responseIsString(requestName)) 128 { 129 value = rawValue.toString(); 130 } 131 else 132 { 133 value = rawValue.toByteArray(); 134 } 135 } 136 extendedResponse.setResponse(value); 137 extendedResponse.setErrorMessage( 138 errorMessage != null ? errorMessage.toString() : null); 139 ResultCode code = ResultCodeFactory.create(objFactory, resultCode); 140 extendedResponse.setResultCode(code); 141 142 return extendedResponse; 143 } 144 145} 146