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 * https://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; 035import org.apache.directory.api.util.CollectionUtils; 036 037/** 038 * The ModifyRequest factory. 039 * 040 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 041 */ 042public final class ModifyRequestFactory implements Messagefactory 043{ 044 /** The static instance */ 045 public static final ModifyRequestFactory INSTANCE = new ModifyRequestFactory(); 046 047 private ModifyRequestFactory() 048 { 049 // Nothing to do 050 } 051 052 053 /** 054 * Encode the values, in reverse order 055 * <pre> 056 * 0x04 LL attributeValue 057 * ... 058 * 0x04 LL attributeValue 059 * </pre> 060 * 061 * @param buffer The buffer where to put the PDU 062 * @param values the values to encode 063 */ 064 private void encodeValues( Asn1Buffer buffer, Iterator<Value> values ) 065 { 066 values = CollectionUtils.reverse( values ); 067 while ( values.hasNext() ) 068 { 069 Value value = values.next(); 070 071 // The value 072 if ( value.isHumanReadable() ) 073 { 074 BerValue.encodeOctetString( buffer, value.getString() ); 075 } 076 else 077 { 078 BerValue.encodeOctetString( buffer, value.getBytes() ); 079 } 080 } 081 } 082 083 /** 084 * Encode the modifications, starting from the last one. 085 * <pre> 086 * 0x30 LL modification sequence 087 * 0x0A 0x01 operation 088 * 0x30 LL modification 089 * 0x04 LL type 090 * 0x31 LL vals 091 * 0x04 LL attributeValue 092 * ... 093 * 0x04 LL attributeValue 094 * </pre> 095 * 096 * @param buffer The buffer where to put the PDU 097 * @param modifications the modifications to encode 098 */ 099 private void encodeModifications( Asn1Buffer buffer, Iterator<Modification> modifications ) 100 { 101 modifications = CollectionUtils.reverse( modifications ); 102 while ( modifications.hasNext() ) 103 { 104 Modification modification = modifications.next(); 105 106 int start = buffer.getPos(); 107 108 // The Attribute 109 Attribute attribute = modification.getAttribute(); 110 111 // The values, if any 112 if ( modification.getAttribute().size() != 0 ) 113 { 114 encodeValues( buffer, modification.getAttribute().iterator() ); 115 116 // the value set 117 BerValue.encodeSet( buffer, start ); 118 } 119 else if ( modification.getOperation() != ModificationOperation.INCREMENT_ATTRIBUTE ) 120 { 121 // the value set, if not a INCREMENT operation 122 BerValue.encodeSet( buffer, start ); 123 } 124 125 // The attribute type 126 BerValue.encodeOctetString( buffer, attribute.getUpId() ); 127 128 // The attribute sequence 129 BerValue.encodeSequence( buffer, start ); 130 131 // The operation 132 BerValue.encodeEnumerated( buffer, modification.getOperation().getValue() ); 133 134 // The modification sequence 135 BerValue.encodeSequence( buffer, start ); 136 } 137 } 138 139 /** 140 * Encode the ModifyRequest message to a PDU. 141 * <br> 142 * ModifyRequest : 143 * <pre> 144 * 0x66 LL 145 * 0x04 LL object 146 * 0x30 LL modifications 147 * 0x30 LL modification sequence 148 * 0x0A 0x01 operation 149 * 0x30 LL modification 150 * 0x04 LL type 151 * 0x31 LL vals 152 * 0x04 LL attributeValue 153 * ... 154 * 0x04 LL attributeValue 155 * ... 156 * 0x30 LL modification sequence 157 * 0x0A 0x01 operation 158 * 0x30 LL modification 159 * 0x04 LL type 160 * 0x31 LL vals 161 * 0x04 LL attributeValue 162 * ... 163 * 0x04 LL attributeValue 164 * </pre> 165 * 166 * @param codec The LdapApiService instance 167 * @param buffer The buffer where to put the PDU 168 * @param message the ModifyRequest to encode 169 */ 170 @Override 171 public void encodeReverse( LdapApiService codec, Asn1Buffer buffer, Message message ) 172 { 173 int start = buffer.getPos(); 174 ModifyRequest modifyRequest = ( ModifyRequest ) message; 175 176 // The modifications, if any 177 Collection<Modification> modifications = modifyRequest.getModifications(); 178 179 if ( ( modifications != null ) && ( !modifications.isEmpty() ) ) 180 { 181 encodeModifications( buffer, modifications.iterator() ); 182 183 // The modifications sequence 184 BerValue.encodeSequence( buffer, start ); 185 } 186 187 // The entry DN 188 BerValue.encodeOctetString( buffer, modifyRequest.getName().getName() ); 189 190 // The ModifyRequest tag 191 BerValue.encodeSequence( buffer, LdapCodecConstants.MODIFY_REQUEST_TAG, start ); 192 } 193}