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    @Override
111    public byte[] getProcedure()
112    {
113        if ( procedure == null )
114        {
115            return null;
116        }
117
118        final byte[] copy = new byte[procedure.length];
119        System.arraycopy( procedure, 0, copy, 0, procedure.length );
120        return copy;
121    }
122
123
124    @Override
125    public void setProcedure( byte[] procedure )
126    {
127        if ( procedure != null )
128        {
129            this.procedure = new byte[procedure.length];
130            System.arraycopy( procedure, 0, this.procedure, 0, procedure.length );
131        }
132        else
133        {
134            this.procedure = null;
135        }
136    }
137
138
139    @Override
140    public List<StoredProcedureParameter> getParameters()
141    {
142        return parameters;
143    }
144
145
146    @Override
147    public void addParameter( StoredProcedureParameter parameter )
148    {
149        parameters.add( parameter );
150    }
151
152
153    /**
154     * Store the procedure's name
155     * 
156     * @param procedure The procedure's name
157     */
158    public void setProcedure( String procedure )
159    {
160        this.procedure = Strings.getBytesUtf8( procedure );
161    }
162
163
164    /**
165     * {@inheritDoc}
166     */
167    @Override
168    public String getProcedureSpecification()
169    {
170        return Strings.utf8ToString( procedure );
171    }
172
173
174    /**
175     * {@inheritDoc}
176     */
177    @Override
178    public int size()
179    {
180        return parameters.size();
181    }
182
183
184    /**
185     * {@inheritDoc}
186     */
187    @Override
188    public Object getParameterType( int index )
189    {
190        if ( !"java".equals( language ) )
191        {
192            return parameters.get( index ).getType();
193        }
194
195        return getJavaParameterType( index );
196    }
197
198
199    /**
200     * Get the parameter type 
201     * 
202     * @param index The parameter position in the list of parameters
203     * @return The found parameter type
204     */
205    public Object getParameterTypeString( int index )
206    {
207        if ( !"java".equals( language ) )
208        {
209            Object obj = parameters.get( index ).getType();
210            
211            if ( obj instanceof byte[] )
212            {
213                return Strings.utf8ToString( ( byte[] ) obj );
214            }
215        }
216
217        return getJavaParameterType( index );
218    }
219
220
221    /**
222     * {@inheritDoc}
223     */
224    @Override
225    public Class<?> getJavaParameterType( int index )
226    {
227        throw new NotImplementedException( I18n.err( I18n.ERR_04175 ) );
228    }
229
230
231    /**
232     * {@inheritDoc}
233     */
234    @Override
235    public Object getParameterValue( int index )
236    {
237        if ( !"java".equals( language ) )
238        {
239            return parameters.get( index ).getValue();
240        }
241
242        return getJavaParameterValue( index );
243    }
244
245
246    /**
247     * Get a parameter value
248     * 
249     * @param index The position of the parameter in the list of parameters
250     * @return The paremeter's value
251     */
252    public Object getParameterValueString( int index )
253    {
254        if ( !"java".equals( language ) )
255        {
256            Object obj = parameters.get( index ).getValue();
257            
258            if ( obj instanceof byte[] )
259            {
260                String str = Strings.utf8ToString( ( byte[] ) obj );
261                String type = ( String ) getParameterTypeString( index );
262
263                if ( "int".equals( type ) )
264                {
265                    try
266                    {
267                        return IntegerDecoder.parse( new BerValue( ( byte[] ) obj ) );
268                    }
269                    catch ( IntegerDecoderException e )
270                    {
271                        throw new RuntimeException( "Failed to decode INTEGER: "
272                            + Strings.dumpBytes( ( byte[] ) obj ), e );
273                    }
274                }
275                else
276                {
277                    return str;
278                }
279            }
280        }
281
282        return getJavaParameterValue( index );
283    }
284
285
286    /**
287     * {@inheritDoc}
288     */
289    @Override
290    public Object getJavaParameterValue( int index )
291    {
292        throw new NotImplementedException( I18n.err( I18n.ERR_04176 ) );
293    }
294
295
296    /**
297     * {@inheritDoc}
298     */
299    @Override
300    public void addParameter( Object type, Object value )
301    {
302        /**
303         *
304         * FIXME: Why do we check here whether it's Java or not ?
305         * Codec has nothing to do with these details.
306         *
307         if ( ! this.procedure.getLanguage().equals( "java" ) )
308         {
309             StoredProcedureParameter parameter = new StoredProcedureParameter();
310             parameter.setType( ( byte[] ) type );
311             parameter.setValue( ( byte[] ) value );
312             this.procedure.addParameter( parameter );
313         }
314         
315         * Replacing this code with the one below without the conditional check.
316         
317         */
318
319        StoredProcedureParameter parameter = new StoredProcedureParameter();
320        parameter.setType( ( byte[] ) type );
321        parameter.setValue( ( byte[] ) value );
322        parameters.add( parameter );
323
324        // below here try to convert parameters to their appropriate byte[] representations
325
326        /**
327         * FIXME: What is this for?
328         * 
329         * throw new NotImplementedException( "conversion of value to java type not implemented" );
330         */
331    }
332
333
334    @Override
335    /**
336     * {@inheritDoc}
337     */
338    public StoredProcedureResponse getResultResponse()
339    {
340        if ( getResponse() == null )
341        {
342            setResponse( new StoredProcedureResponseImpl( getMessageId() ) );
343        }
344
345        return ( StoredProcedureResponse ) getResponse();
346    }
347}