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.server.ldap.handlers.extended;
021    
022    
023    import java.io.Serializable;
024    import java.nio.ByteBuffer;
025    import java.util.ArrayList;
026    import java.util.Collections;
027    import java.util.HashSet;
028    import java.util.List;
029    import java.util.Set;
030    
031    import org.apache.commons.lang.SerializationUtils;
032    import org.apache.directory.server.core.entry.ClonedServerEntry;
033    import org.apache.directory.server.core.sp.StoredProcEngine;
034    import org.apache.directory.server.core.sp.StoredProcEngineConfig;
035    import org.apache.directory.server.core.sp.StoredProcExecutionManager;
036    import org.apache.directory.server.core.sp.java.JavaStoredProcEngineConfig;
037    import org.apache.directory.server.ldap.ExtendedOperationHandler;
038    import org.apache.directory.server.ldap.LdapServer;
039    import org.apache.directory.server.ldap.LdapSession;
040    import org.apache.directory.shared.asn1.ber.Asn1Decoder;
041    import org.apache.directory.shared.asn1.ber.IAsn1Container;
042    import org.apache.directory.shared.ldap.codec.extended.operations.storedProcedure.StoredProcedure;
043    import org.apache.directory.shared.ldap.codec.extended.operations.storedProcedure.StoredProcedureContainer;
044    import org.apache.directory.shared.ldap.codec.extended.operations.storedProcedure.StoredProcedureDecoder;
045    import org.apache.directory.shared.ldap.codec.extended.operations.storedProcedure.StoredProcedure.StoredProcedureParameter;
046    import org.apache.directory.shared.ldap.message.extended.StoredProcedureRequest;
047    import org.apache.directory.shared.ldap.message.extended.StoredProcedureResponse;
048    import org.apache.directory.shared.ldap.message.internal.InternalExtendedRequest;
049    import org.apache.directory.shared.ldap.message.internal.InternalExtendedResponse;
050    import org.apache.directory.shared.ldap.name.DN;
051    import org.apache.directory.shared.ldap.sp.LdapContextParameter;
052    import org.apache.directory.shared.ldap.util.StringTools;
053    
054    
055    /**
056     * @org.apache.xbean.XBean
057     *
058     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
059     * @version $Rev$ $Date$
060     */
061    public class StoredProcedureExtendedOperationHandler implements ExtendedOperationHandler
062    {
063        private StoredProcExecutionManager manager;
064        private static final Object[] EMPTY_CLASS_ARRAY = new Object[0];
065        
066        
067        public StoredProcedureExtendedOperationHandler()
068        {
069            super();
070            //StoredProcEngineConfig javaxScriptSPEngineConfig = new JavaxStoredProcEngineConfig();
071            StoredProcEngineConfig javaSPEngineConfig = new JavaStoredProcEngineConfig();
072            List<StoredProcEngineConfig> spEngineConfigs = new ArrayList<StoredProcEngineConfig>();
073            //spEngineConfigs.add( javaxScriptSPEngineConfig );
074            spEngineConfigs.add( javaSPEngineConfig );
075            String spContainer = "ou=Stored Procedures,ou=system";
076            this.manager = new StoredProcExecutionManager( spContainer, spEngineConfigs );
077        }
078    
079    
080        public void handleExtendedOperation( LdapSession session, InternalExtendedRequest req ) throws Exception
081        {
082            StoredProcedure spBean = decodeBean( req.getPayload() );
083            
084            String procedure = StringTools.utf8ToString( spBean.getProcedure() );
085            ClonedServerEntry spUnit = manager.findStoredProcUnit( session.getCoreSession(), procedure );
086            StoredProcEngine engine = manager.getStoredProcEngineInstance( spUnit );
087            
088            List<Object> valueList = new ArrayList<Object>( spBean.getParameters().size() );
089            
090            for ( StoredProcedureParameter pPojo:spBean.getParameters() )
091            {
092                byte[] serializedValue = pPojo.getValue();
093                Object value = SerializationUtils.deserialize( serializedValue );
094                
095                if ( value.getClass().equals( LdapContextParameter.class ) )
096                {
097                    String paramCtx = ( ( LdapContextParameter ) value ).getValue();
098                    value = session.getCoreSession().lookup( new DN( paramCtx ) );
099                }
100                
101                valueList.add( value );
102            }
103            
104            Object[] values = valueList.toArray( EMPTY_CLASS_ARRAY );
105            
106            Object response = engine.invokeProcedure( session.getCoreSession(), procedure, values );
107            
108            byte[] serializedResponse = SerializationUtils.serialize( ( Serializable ) response );
109            ( ( InternalExtendedResponse )( req.getResultResponse() ) ).setResponse( serializedResponse );
110            session.getIoSession().write( req.getResultResponse() );
111            
112        }
113        
114        private StoredProcedure decodeBean( byte[] payload )
115        {
116            Asn1Decoder storedProcedureDecoder = new StoredProcedureDecoder();
117            ByteBuffer stream = ByteBuffer.wrap( payload );
118            IAsn1Container storedProcedureContainer = new StoredProcedureContainer();
119    
120            try
121            {
122                storedProcedureDecoder.decode( stream, storedProcedureContainer );
123            }
124            catch ( Exception de )
125            {
126                de.printStackTrace();
127            }
128    
129            StoredProcedure spBean = ( ( StoredProcedureContainer ) storedProcedureContainer ).getStoredProcedure();
130            
131            return spBean;
132        }
133    
134        
135        public String getOid()
136        {
137            return StoredProcedureRequest.EXTENSION_OID;
138        }
139    
140    
141        private static final Set<String> EXTENSION_OIDS;
142        
143        static
144        {
145            Set<String> s = new HashSet<String>();
146            s.add( StoredProcedureRequest.EXTENSION_OID );
147            s.add( StoredProcedureResponse.EXTENSION_OID );
148            EXTENSION_OIDS = Collections.unmodifiableSet( s );
149        }
150        
151        
152        public Set<String> getExtensionOids()
153        {
154            return EXTENSION_OIDS;
155        }
156    
157    
158        public void setLdapServer( LdapServer ldapServer )
159        {
160        }
161    }