001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.api.ldap.codec.factory; 021 022import java.util.Collection; 023import java.util.Iterator; 024 025import org.apache.directory.api.asn1.ber.tlv.BerValue; 026import org.apache.directory.api.asn1.util.Asn1Buffer; 027import org.apache.directory.api.ldap.codec.api.LdapApiService; 028import org.apache.directory.api.ldap.codec.api.LdapCodecConstants; 029import org.apache.directory.api.ldap.model.entry.Attribute; 030import org.apache.directory.api.ldap.model.entry.Modification; 031import org.apache.directory.api.ldap.model.entry.ModificationOperation; 032import org.apache.directory.api.ldap.model.entry.Value; 033import org.apache.directory.api.ldap.model.message.Message; 034import org.apache.directory.api.ldap.model.message.ModifyRequest; 035 036/** 037 * The ModifyRequest factory. 038 * 039 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 040 */ 041public final class ModifyRequestFactory implements Messagefactory 042{ 043 /** The static instance */ 044 public static final ModifyRequestFactory INSTANCE = new ModifyRequestFactory(); 045 046 private ModifyRequestFactory() 047 { 048 // Nothing to do 049 } 050 051 052 /** 053 * Encode the values, recursively 054 * <pre> 055 * 0x04 LL attributeValue 056 * ... 057 * 0x04 LL attributeValue 058 * </pre> 059 * 060 * @param buffer The buffer where to put the PDU 061 * @param values the values to encode 062 */ 063 private void encodeValues( Asn1Buffer buffer, Iterator<Value> values ) 064 { 065 if ( values.hasNext() ) 066 { 067 Value value = values.next(); 068 069 // Recurse on the values 070 encodeValues( buffer, values ); 071 072 // The value 073 if ( value.isHumanReadable() ) 074 { 075 BerValue.encodeOctetString( buffer, value.getString() ); 076 } 077 else 078 { 079 BerValue.encodeOctetString( buffer, value.getBytes() ); 080 } 081 } 082 } 083 084 /** 085 * Recursively encode the modifications, starting from the last one. 086 * <pre> 087 * 0x30 LL modification sequence 088 * 0x0A 0x01 operation 089 * 0x30 LL modification 090 * 0x04 LL type 091 * 0x31 LL vals 092 * 0x04 LL attributeValue 093 * ... 094 * 0x04 LL attributeValue 095 * </pre> 096 * 097 * @param buffer The buffer where to put the PDU 098 * @param modifications the modifications to encode 099 */ 100 private void encodeModifications( Asn1Buffer buffer, Iterator<Modification> modifications ) 101 { 102 if ( modifications.hasNext() ) 103 { 104 Modification modification = modifications.next(); 105 106 // Recurse 107 encodeModifications( buffer, modifications ); 108 109 int start = buffer.getPos(); 110 111 // The Attribute 112 Attribute attribute = modification.getAttribute(); 113 114 // The values, if any 115 if ( modification.getAttribute().size() != 0 ) 116 { 117 encodeValues( buffer, modification.getAttribute().iterator() ); 118 119 // the value set 120 BerValue.encodeSet( buffer, start ); 121 } 122 else if ( modification.getOperation() != ModificationOperation.INCREMENT_ATTRIBUTE ) 123 { 124 // the value set, if not a INCREMENT operation 125 BerValue.encodeSet( buffer, start ); 126 } 127 128 // The attribute type 129 BerValue.encodeOctetString( buffer, attribute.getUpId() ); 130 131 // The attribute sequence 132 BerValue.encodeSequence( buffer, start ); 133 134 // The operation 135 BerValue.encodeEnumerated( buffer, modification.getOperation().getValue() ); 136 137 // The modification sequence 138 BerValue.encodeSequence( buffer, start ); 139 } 140 } 141 142 /** 143 * Encode the ModifyRequest message to a PDU. 144 * <br> 145 * ModifyRequest : 146 * <pre> 147 * 0x66 LL 148 * 0x04 LL object 149 * 0x30 LL modifications 150 * 0x30 LL modification sequence 151 * 0x0A 0x01 operation 152 * 0x30 LL modification 153 * 0x04 LL type 154 * 0x31 LL vals 155 * 0x04 LL attributeValue 156 * ... 157 * 0x04 LL attributeValue 158 * ... 159 * 0x30 LL modification sequence 160 * 0x0A 0x01 operation 161 * 0x30 LL modification 162 * 0x04 LL type 163 * 0x31 LL vals 164 * 0x04 LL attributeValue 165 * ... 166 * 0x04 LL attributeValue 167 * </pre> 168 * 169 * @param codec The LdapApiService instance 170 * @param buffer The buffer where to put the PDU 171 * @param message the ModifyRequest to encode 172 */ 173 @Override 174 public void encodeReverse( LdapApiService codec, Asn1Buffer buffer, Message message ) 175 { 176 int start = buffer.getPos(); 177 ModifyRequest modifyRequest = ( ModifyRequest ) message; 178 179 // The modifications, if any 180 Collection<Modification> modifications = modifyRequest.getModifications(); 181 182 if ( ( modifications != null ) && ( !modifications.isEmpty() ) ) 183 { 184 encodeModifications( buffer, modifications.iterator() ); 185 186 // The modifications sequence 187 BerValue.encodeSequence( buffer, start ); 188 } 189 190 // The entry DN 191 BerValue.encodeOctetString( buffer, modifyRequest.getName().getName() ); 192 193 // The ModifyRequest tag 194 BerValue.encodeSequence( buffer, LdapCodecConstants.MODIFY_REQUEST_TAG, start ); 195 } 196}