View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    https://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.directory.api.ldap.codec.actions.response.extended;
21  
22  
23  import org.apache.directory.api.asn1.DecoderException;
24  import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
25  import org.apache.directory.api.asn1.ber.tlv.TLV;
26  import org.apache.directory.api.asn1.util.Oid;
27  import org.apache.directory.api.i18n.I18n;
28  import org.apache.directory.api.ldap.codec.api.ExtendedOperationFactory;
29  import org.apache.directory.api.ldap.codec.api.LdapApiService;
30  import org.apache.directory.api.ldap.codec.api.LdapMessageContainer;
31  import org.apache.directory.api.ldap.model.message.ExtendedResponse;
32  import org.apache.directory.api.util.Strings;
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  
36  
37  /**
38   * The action used to store a Response Name to an ExtendedResponse
39   * <pre>
40   * LdapMessage ::= ... ExtendedResponse ...
41   * ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
42   *     COMPONENTS OF LDAPResult,
43   *     responseName   [10] LDAPOID OPTIONAL,
44   *     ...
45   * </pre>
46   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
47   */
48  public class StoreExtendedResponseName extends GrammarAction<LdapMessageContainer<ExtendedResponse>>
49  {
50      /** The logger */
51      private static final Logger LOG = LoggerFactory.getLogger( StoreExtendedResponseName.class );
52  
53      /**
54       * Instantiates a new response name action.
55       */
56      public StoreExtendedResponseName()
57      {
58          super( "Store response name" );
59      }
60  
61  
62      /**
63       * {@inheritDoc}
64       */
65      public void action( LdapMessageContainer<ExtendedResponse> container ) throws DecoderException
66      {
67          // Get the Name and store it in the ExtendedResponse. That will
68          // allow us to find the proper extended response instance, if it's 
69          // already declared. Otherwise, we will use a default ExtendedResponse
70          // in which the value will be stored un-decoded.
71          TLV tlv = container.getCurrentTLV();
72  
73          // We have to handle the special case of a 0 length matched
74          // OID
75          if ( tlv.getLength() == 0 )
76          {
77              String msg = I18n.err( I18n.ERR_05122_NULL_NAME );
78              LOG.error( msg );
79              throw new DecoderException( msg );
80          }
81          else
82          {
83              byte[] responseNameBytes = tlv.getValue().getData();
84              String responseName = Strings.asciiBytesToString( responseNameBytes );
85  
86              try
87              {
88                  // Check the OID first, if it's invalid, reject the operation
89                  if ( !Oid.isOid( responseName ) )
90                  {
91                      String msg = I18n.err( I18n.ERR_05159_INVALID_RESPONSE_NAME_OID,
92                          responseName, Strings.dumpBytes( responseNameBytes ) );
93                      LOG.error( msg );
94      
95                      // throw an exception, we will get a PROTOCOL_ERROR
96                      throw new DecoderException( msg );
97                  }
98      
99                  // Get the extended request factory from the LdapApiService, if it's registered
100                 LdapApiService codec = container.getLdapCodecService();
101                 ExtendedOperationFactory factory = codec.getExtendedResponseFactories().get( responseName );
102                 ExtendedResponse extendedResponse = container.getMessage();
103                 
104                 if ( factory != null )
105                 {
106                     // Create the extended response
107                     extendedResponse = factory.newResponse();
108 
109                     // Move the LDAPResult in the newly created response
110                     LdapMessageContainer.copyLdapResult( container.getMessage(), extendedResponse );
111                     extendedResponse.setMessageId( container.getMessageId() );
112                     container.setMessage( extendedResponse );
113                 }
114                 else
115                 {
116                    extendedResponse.setResponseName( responseName );
117                 }
118 
119                 container.setExtendedFactory( factory );
120                 
121                 if ( LOG.isDebugEnabled() )
122                 {
123                     LOG.debug( I18n.msg( I18n.MSG_05172_OID_READ, extendedResponse.getResponseName() ) );
124                 }
125             }
126             catch ( DecoderException de )
127             {
128                 String msg = I18n.err( I18n.ERR_05159_INVALID_RESPONSE_NAME_OID,
129                     responseName, Strings.dumpBytes( responseNameBytes ) );
130                 LOG.error( I18n.err( I18n.ERR_05114_ERROR_MESSAGE, msg, de.getMessage() ) );
131 
132                 // Rethrow the exception, we will get a PROTOCOL_ERROR
133                 throw de;
134             }
135         }
136 
137         // We can have an END transition
138         container.setGrammarEndAllowed( true );
139     }
140 }