001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2006-2008 Sun Microsystems, Inc. 025 * Portions Copyright 2012-2014 ForgeRock AS. 026 */ 027package org.opends.dsml.protocol; 028 029 030 031import java.io.IOException; 032import java.util.List; 033import java.util.Set; 034 035import org.forgerock.i18n.LocalizableMessage; 036import org.forgerock.opendj.ldap.DecodeException; 037import org.opends.server.protocols.ldap.ExtendedRequestProtocolOp; 038import org.opends.server.protocols.ldap.ExtendedResponseProtocolOp; 039import org.opends.server.protocols.ldap.LDAPMessage; 040import org.opends.server.protocols.ldap.ProtocolOp; 041import org.opends.server.tools.LDAPConnection; 042import org.forgerock.opendj.ldap.ByteString; 043import org.opends.server.types.LDAPException; 044 045 046/** 047 * This class provides the functionality for the performing an 048 * LDAP EXTENDED operation based on the specified DSML request. 049 */ 050public class DSMLExtendedOperation 051{ 052 private LDAPConnection connection; 053 private Set<String> stringResponses; 054 055 /** 056 * Create an instance with the specified LDAP connection. 057 * 058 * @param connection The LDAP connection to send the request on. 059 * @param stringResponses The OIDs of any operations that have results that 060 * should be returned as strings instead of binary. 061 */ 062 public DSMLExtendedOperation(LDAPConnection connection, 063 Set<String> stringResponses) 064 { 065 this.connection = connection; 066 this.stringResponses = stringResponses; 067 } 068 069 070 071 /** 072 * Determine if the response to a given LDAP extended operation (specified by 073 * OID) should be treated as a string. The default is binary. 074 * 075 * @param oid The OID of the extended operation. 076 * @return <CODE>true</CODE> if the extended operation is known to return a 077 * string, <CODE>false</CODE> otherwise. 078 */ 079 public boolean responseIsString(String oid) 080 { 081 return stringResponses.contains(oid); 082 } 083 084 085 086 /** 087 * Perform the LDAP EXTENDED operation and send the result back to the 088 * client. 089 * 090 * @param objFactory The object factory for this operation. 091 * @param extendedRequest The extended request for this operation. 092 * @param controls Any required controls (e.g. for proxy authz). 093 * 094 * @return The result of the extended operation. 095 * 096 * @throws IOException If an I/O problem occurs. 097 * 098 * @throws LDAPException If an error occurs while interacting with an LDAP 099 * element. 100 * 101 * @throws DecodeException If an error occurs while interacting with an ASN.1 102 * element. 103 */ 104 public ExtendedResponse doOperation(ObjectFactory objFactory, 105 ExtendedRequest extendedRequest, 106 List<org.opends.server.types.Control> controls) 107 throws IOException, LDAPException, DecodeException 108 { 109 ExtendedResponse extendedResponse = objFactory.createExtendedResponse(); 110 extendedResponse.setRequestID(extendedRequest.getRequestID()); 111 112 String requestName = extendedRequest.getRequestName(); 113 Object value = extendedRequest.getRequestValue(); 114 ByteString asnValue = ByteStringUtility.convertValue(value); 115 116 // Create and send the LDAP request to the server. 117 ProtocolOp op = new ExtendedRequestProtocolOp(requestName, asnValue); 118 LDAPMessage msg = new LDAPMessage(DSMLServlet.nextMessageID(), op, 119 controls); 120 connection.getLDAPWriter().writeMessage(msg); 121 122 // Read and decode the LDAP response from the server. 123 LDAPMessage responseMessage = connection.getLDAPReader().readMessage(); 124 125 ExtendedResponseProtocolOp extendedOp = 126 responseMessage.getExtendedResponseProtocolOp(); 127 int resultCode = extendedOp.getResultCode(); 128 LocalizableMessage errorMessage = extendedOp.getErrorMessage(); 129 130 // Set the result code and error message for the DSML response. 131 extendedResponse.setResponseName(extendedOp.getOID()); 132 133 ByteString rawValue = extendedOp.getValue(); 134 value = null; 135 if (rawValue != null) 136 { 137 if (responseIsString(requestName)) 138 { 139 value = rawValue.toString(); 140 } 141 else 142 { 143 value = rawValue.toByteArray(); 144 } 145 } 146 extendedResponse.setResponse(value); 147 extendedResponse.setErrorMessage( 148 errorMessage != null ? errorMessage.toString() : null); 149 ResultCode code = ResultCodeFactory.create(objFactory, resultCode); 150 extendedResponse.setResultCode(code); 151 152 return extendedResponse; 153 } 154 155} 156