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.extras.extended.storedProcedure;
021
022
023import java.util.ArrayList;
024import java.util.List;
025
026import org.apache.directory.api.asn1.ber.tlv.BerValue;
027import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder;
028import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException;
029import org.apache.directory.api.i18n.I18n;
030import org.apache.directory.api.ldap.model.message.AbstractExtendedRequest;
031import org.apache.directory.api.util.Strings;
032import org.apache.directory.api.util.exception.NotImplementedException;
033
034
035/**
036 * An extended operation requesting the server to execute a stored procedure.
037 * 
038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
039 */
040public class StoredProcedureRequestImpl extends AbstractExtendedRequest implements StoredProcedureRequest
041{
042    private String language = "Java";
043
044    private byte[] procedure = Strings.EMPTY_BYTES;
045
046    private List<StoredProcedureParameter> parameters = new ArrayList<>();
047
048
049    /**
050     * Instantiates a new stored procedure request.
051     *
052     * @param messageId the message id
053     */
054    public StoredProcedureRequestImpl( int messageId )
055    {
056        super( messageId );
057        this.setRequestName( EXTENSION_OID );
058    }
059
060
061    /**
062     * Instantiates a new stored procedure request.
063     */
064    public StoredProcedureRequestImpl()
065    {
066        this.setRequestName( EXTENSION_OID );
067    }
068
069
070    /**
071     * Instantiates a new stored procedure request.
072     *
073     * @param messageId the message id
074     * @param procedure the procedure
075     * @param language the language
076     */
077    public StoredProcedureRequestImpl( int messageId, String procedure, String language )
078    {
079        super( messageId );
080        this.setRequestName( EXTENSION_OID );
081        this.language = language;
082        this.procedure = Strings.getBytesUtf8( procedure );
083    }
084
085
086    // -----------------------------------------------------------------------
087    // Parameters of the Extended Request Payload
088    // -----------------------------------------------------------------------
089
090    /**
091     * {@inheritDoc}
092     */
093    @Override
094    public String getLanguage()
095    {
096        return language;
097    }
098
099
100    /**
101     * {@inheritDoc}
102     */
103    @Override
104    public void setLanguage( String language )
105    {
106        this.language = language;
107    }
108
109
110    /**
111     * {@inheritDoc}
112     */
113    @Override
114    public byte[] getProcedure()
115    {
116        if ( procedure == null )
117        {
118            return null;
119        }
120
121        final byte[] copy = new byte[procedure.length];
122        System.arraycopy( procedure, 0, copy, 0, procedure.length );
123        return copy;
124    }
125
126
127    /**
128     * {@inheritDoc}
129     */
130    @Override
131    public void setProcedure( byte[] procedure )
132    {
133        if ( procedure != null )
134        {
135            this.procedure = new byte[procedure.length];
136            System.arraycopy( procedure, 0, this.procedure, 0, procedure.length );
137        }
138        else
139        {
140            this.procedure = null;
141        }
142    }
143
144
145    /**
146     * {@inheritDoc}
147     */
148    @Override
149    public List<StoredProcedureParameter> getParameters()
150    {
151        return parameters;
152    }
153
154
155    /**
156     * {@inheritDoc}
157     */
158    @Override
159    public void addParameter( StoredProcedureParameter parameter )
160    {
161        parameters.add( parameter );
162    }
163
164
165    /**
166     * Store the procedure's name
167     * 
168     * @param procedure The procedure's name
169     */
170    public void setProcedure( String procedure )
171    {
172        this.procedure = Strings.getBytesUtf8( procedure );
173    }
174
175
176    /**
177     * {@inheritDoc}
178     */
179    @Override
180    public String getProcedureSpecification()
181    {
182        return Strings.utf8ToString( procedure );
183    }
184
185
186    /**
187     * {@inheritDoc}
188     */
189    @Override
190    public int size()
191    {
192        return parameters.size();
193    }
194
195
196    /**
197     * {@inheritDoc}
198     */
199    @Override
200    public Object getParameterType( int index )
201    {
202        if ( !"java".equals( language ) )
203        {
204            return parameters.get( index ).getType();
205        }
206
207        return getJavaParameterType( index );
208    }
209
210
211    /**
212     * Get the parameter type 
213     * 
214     * @param index The parameter position in the list of parameters
215     * @return The found parameter type
216     */
217    public Object getParameterTypeString( int index )
218    {
219        if ( !"java".equals( language ) )
220        {
221            Object obj = parameters.get( index ).getType();
222            
223            if ( obj instanceof byte[] )
224            {
225                return Strings.utf8ToString( ( byte[] ) obj );
226            }
227        }
228
229        return getJavaParameterType( index );
230    }
231
232
233    /**
234     * {@inheritDoc}
235     */
236    @Override
237    public Class<?> getJavaParameterType( int index )
238    {
239        throw new NotImplementedException( I18n.err( I18n.ERR_9104_CLASS_LOADING_OF_PROC_TYPE_NOT_IMPLEMENTED ) );
240    }
241
242
243    /**
244     * {@inheritDoc}
245     */
246    @Override
247    public Object getParameterValue( int index )
248    {
249        if ( !"java".equals( language ) )
250        {
251            return parameters.get( index ).getValue();
252        }
253
254        return getJavaParameterValue( index );
255    }
256
257
258    /**
259     * Get a parameter value
260     * 
261     * @param index The position of the parameter in the list of parameters
262     * @return The paremeter's value
263     */
264    public Object getParameterValueString( int index )
265    {
266        if ( !"java".equals( language ) )
267        {
268            Object obj = parameters.get( index ).getValue();
269            
270            if ( obj instanceof byte[] )
271            {
272                String str = Strings.utf8ToString( ( byte[] ) obj );
273                String type = ( String ) getParameterTypeString( index );
274
275                if ( "int".equals( type ) )
276                {
277                    try
278                    {
279                        return IntegerDecoder.parse( new BerValue( ( byte[] ) obj ) );
280                    }
281                    catch ( IntegerDecoderException e )
282                    {
283                        throw new RuntimeException( I18n.err( I18n.ERR_9200_INTERGER_DECODING_FAILURE,
284                            Strings.dumpBytes( ( byte[] ) obj ) ), e );
285                    }
286                }
287                else
288                {
289                    return str;
290                }
291            }
292        }
293
294        return getJavaParameterValue( index );
295    }
296
297
298    /**
299     * {@inheritDoc}
300     */
301    @Override
302    public Object getJavaParameterValue( int index )
303    {
304        throw new NotImplementedException( I18n.err( I18n.ERR_9105_CONVERSION_VALUE_TO_JAVA_NOT_IMPLEMENTED ) );
305    }
306
307
308    /**
309     * {@inheritDoc}
310     */
311    @Override
312    public void addParameter( Object type, Object value )
313    {
314        /**
315         *
316         * FIXME: Why do we check here whether it's Java or not ?
317         * Codec has nothing to do with these details.
318         *
319         if ( ! this.procedure.getLanguage().equals( "java" ) )
320         {
321             StoredProcedureParameter parameter = new StoredProcedureParameter();
322             parameter.setType( ( byte[] ) type );
323             parameter.setValue( ( byte[] ) value );
324             this.procedure.addParameter( parameter );
325         }
326         
327         * Replacing this code with the one below without the conditional check.
328         
329         */
330
331        StoredProcedureParameter parameter = new StoredProcedureParameter();
332        parameter.setType( ( byte[] ) type );
333        parameter.setValue( ( byte[] ) value );
334        parameters.add( parameter );
335
336        // below here try to convert parameters to their appropriate byte[] representations
337
338        /**
339         * FIXME: What is this for?
340         * 
341         * throw new NotImplementedException( "conversion of value to java type not implemented" );
342         */
343    }
344
345
346    /**
347     * {@inheritDoc}
348     */
349    @Override
350    /**
351     * {@inheritDoc}
352     */
353    public StoredProcedureResponse getResultResponse()
354    {
355        if ( getResponse() == null )
356        {
357            setResponse( new StoredProcedureResponseImpl( getMessageId() ) );
358        }
359
360        return ( StoredProcedureResponse ) getResponse();
361    }
362}