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     */
020    package org.apache.directory.shared.ldap.message.extended;
021    
022    import java.nio.ByteBuffer;
023    
024    import javax.naming.NamingException;
025    import javax.naming.ldap.ExtendedResponse;
026    
027    import org.apache.directory.shared.asn1.codec.EncoderException;
028    import org.apache.directory.shared.i18n.I18n;
029    import org.apache.directory.shared.ldap.NotImplementedException;
030    import org.apache.directory.shared.ldap.codec.extended.operations.storedProcedure.StoredProcedure;
031    import org.apache.directory.shared.ldap.codec.extended.operations.storedProcedure.StoredProcedureContainer;
032    import org.apache.directory.shared.ldap.codec.extended.operations.storedProcedure.StoredProcedureDecoder;
033    import org.apache.directory.shared.ldap.codec.extended.operations.storedProcedure.StoredProcedure.StoredProcedureParameter;
034    import org.apache.directory.shared.ldap.message.ExtendedRequestImpl;
035    import org.apache.directory.shared.ldap.message.internal.InternalResultResponse;
036    import org.apache.directory.shared.ldap.util.StringTools;
037    import org.slf4j.Logger;
038    import org.slf4j.LoggerFactory;
039    
040    
041    /**
042     * An extended operation requesting the server to execute a stored procedure.
043     * 
044     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
045     * @version $Rev$
046     */
047    public class StoredProcedureRequest extends ExtendedRequestImpl
048    {
049        private static final Logger log = LoggerFactory.getLogger( StoredProcedureRequest.class );
050        private static final long serialVersionUID = -4682291068700593492L;
051        public static final String EXTENSION_OID = "1.3.6.1.4.1.18060.0.1.6";
052    
053        private StoredProcedure procedure;
054    
055        
056        public StoredProcedureRequest( int messageId )
057        {
058            super( messageId );
059            this.setOid( EXTENSION_OID );
060            this.procedure = new StoredProcedure();
061        }
062    
063    
064        public StoredProcedureRequest( int messageId, String procedure, String language )
065        {
066            super( messageId );
067            this.setOid( EXTENSION_OID );
068            this.procedure = new StoredProcedure();
069            this.setLanguage( language );
070            this.setProcedure( procedure );
071        }
072    
073    
074        private void encodePayload() throws EncoderException
075        {
076            payload = procedure.encode().array();
077        }
078    
079    
080        public void setPayload( byte[] payload )
081        {
082            StoredProcedureDecoder decoder = new StoredProcedureDecoder();
083            StoredProcedureContainer container = new StoredProcedureContainer();
084            
085            try
086            {
087                decoder.decode( ByteBuffer.wrap( payload ), container );
088                this.procedure = container.getStoredProcedure();
089            }
090            catch ( Exception e )
091            {
092                log.error( I18n.err( I18n.ERR_04165 ), e );
093                throw new RuntimeException( e );
094            }
095        }
096    
097    
098        public ExtendedResponse createExtendedResponse( String id, byte[] berValue, int offset, int length )
099            throws NamingException
100        {
101            StoredProcedureResponse resp = ( StoredProcedureResponse ) getResultResponse();
102            resp.setResponse( berValue );
103            resp.setOid( id );
104            return resp;
105        }
106    
107    
108        public byte[] getEncodedValue()
109        {
110            return getPayload();
111        }
112    
113    
114        public byte[] getPayload()
115        {
116            if ( payload == null )
117            {
118                try
119                {
120                    encodePayload();
121                }
122                catch ( EncoderException e )
123                {
124                    log.error( I18n.err( I18n.ERR_04174 ), e );
125                    throw new RuntimeException( e );
126                }
127            }
128    
129            return payload;
130        }
131    
132    
133        public InternalResultResponse getResultResponse()
134        {
135            if ( response == null )
136            {
137                StoredProcedureResponse spr = new StoredProcedureResponse( getMessageId() );
138                spr.setOid( EXTENSION_OID );
139                response = spr;
140            }
141    
142            return response;
143        }
144    
145    
146        // -----------------------------------------------------------------------
147        // Parameters of the Extended Request Payload
148        // -----------------------------------------------------------------------
149    
150    
151        public String getLanguage()
152        {
153            return procedure.getLanguage();
154        }
155        
156        
157        public void setLanguage( String language )
158        {
159            this.procedure.setLanguage( language );
160        }
161    
162        
163        public void setProcedure( String procedure )
164        {
165            this.procedure.setProcedure( StringTools.getBytesUtf8( procedure ) );
166        }
167    
168        
169        public String getProcedureSpecification()
170        {
171            return StringTools.utf8ToString( procedure.getProcedure() );
172        }
173        
174        
175        public int size()
176        {
177            return this.procedure.getParameters().size();
178        }
179        
180        
181        public Object getParameterType( int index )
182        {
183            if ( ! this.procedure.getLanguage().equals( "java" ) )
184            {
185                return procedure.getParameters().get( index ).getType();
186            }
187    
188            return getJavaParameterType( index );
189        }
190        
191        
192        public Class<?> getJavaParameterType( int index )
193        {
194            throw new NotImplementedException( I18n.err( I18n.ERR_04175 ) );
195        }
196        
197        
198        public Object getParameterValue( int index )
199        {
200            if ( ! this.procedure.getLanguage().equals( "java" ) )
201            {
202                return procedure.getParameters().get( index ).getValue();
203            }
204    
205            return getJavaParameterValue( index );
206        }
207        
208        
209        public Object getJavaParameterValue( int index )
210        {
211            throw new NotImplementedException( I18n.err( I18n.ERR_04176 ) );
212        }
213        
214        
215        public void addParameter( Object type, Object value )
216        {
217            /**
218             *
219             * FIXME: Why do we check here whether it's Java or not ?
220             * Codec has nothing to do with these details.
221             *
222             if ( ! this.procedure.getLanguage().equals( "java" ) )
223             {
224                 StoredProcedureParameter parameter = new StoredProcedureParameter();
225                 parameter.setType( ( byte[] ) type );
226                 parameter.setValue( ( byte[] ) value );
227                 this.procedure.addParameter( parameter );
228             }
229             
230             * Replacing this code with the one below without the conditional check.
231             
232             */
233            
234            StoredProcedureParameter parameter = new StoredProcedureParameter();
235            parameter.setType( ( byte[] ) type );
236            parameter.setValue( ( byte[] ) value );
237            this.procedure.addParameter( parameter );
238    
239            // below here try to convert parameters to their appropriate byte[] representations
240            
241            /**
242             * FIXME: What is this for?
243             * 
244             * throw new NotImplementedException( "conversion of value to java type not implemented" );
245             */
246        }
247    }