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.server.core.api.sp;
021
022
023import java.util.List;
024
025import javax.naming.directory.SearchControls;
026
027import org.apache.directory.api.ldap.model.constants.SchemaConstants;
028import org.apache.directory.api.ldap.model.cursor.Cursor;
029import org.apache.directory.api.ldap.model.entry.Entry;
030import org.apache.directory.api.ldap.model.entry.Value;
031import org.apache.directory.api.ldap.model.exception.LdapException;
032import org.apache.directory.api.ldap.model.filter.EqualityNode;
033import org.apache.directory.api.ldap.model.filter.ExprNode;
034import org.apache.directory.api.ldap.model.message.AliasDerefMode;
035import org.apache.directory.api.ldap.model.message.SearchScope;
036import org.apache.directory.api.ldap.model.name.Dn;
037import org.apache.directory.api.ldap.model.schema.AttributeType;
038import org.apache.directory.server.core.api.CoreSession;
039import org.apache.directory.server.core.api.entry.ClonedServerEntry;
040import org.apache.directory.server.i18n.I18n;
041
042
043/**
044 * A Factory type class which holds a registry of supported {@link StoredProcEngineConfig}s. A container reference
045 * as the base for Stored Procedure storage on the DIT is also handled by this class.
046 * 
047 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
048 */
049public class StoredProcExecutionManager
050{
051    private final String storedProcContainer;
052
053    private final List<StoredProcEngineConfig> storedProcEngineConfigs;
054
055
056    /**
057     * Creates a {@link StoredProcExecutionManager} instance.
058     * 
059     * @param storedProcContainer The base of the DIT subtree used for storing stored procedure units.
060     * @param storedProcEngineConfigs A list of {@link StoredProcEngineConfig}s to register different {@link StoredProcEngine}s with this manager.
061     */
062    public StoredProcExecutionManager( final String storedProcContainer,
063        final List<StoredProcEngineConfig> storedProcEngineConfigs )
064    {
065        this.storedProcContainer = storedProcContainer;
066        this.storedProcEngineConfigs = storedProcEngineConfigs;
067    }
068
069
070    /**
071     * Finds and returns a stored procedure unit entry whose identifier name
072     * is extracted from fullSPName.
073     * 
074     * @param session the session with a core directory service
075     * @param fullSPName Full name of the Stored Procedure including the unit name.
076     * @return The entry associated with the SP Unit.
077     * @throws Exception If the unit cannot be located or any other error occurs.
078     */
079    public Entry findStoredProcUnit( CoreSession session, String fullSPName ) throws Exception
080    {
081        SearchControls controls = new SearchControls();
082        controls.setReturningAttributes( SchemaConstants.ALL_USER_ATTRIBUTES_ARRAY );
083        controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
084        String spUnitName = StoredProcUtils.extractStoredProcUnitName( fullSPName );
085
086        AttributeType storeProcUnitNamAT = session.getDirectoryService()
087            .getSchemaManager().lookupAttributeTypeRegistry( "storedProcUnitName" );
088        ExprNode filter = new EqualityNode<String>( storeProcUnitNamAT,
089            new Value( storeProcUnitNamAT, spUnitName ) );
090        Dn dn = session.getDirectoryService().getDnFactory().create( storedProcContainer );
091        Cursor<Entry> results = session.search( dn, SearchScope.SUBTREE, filter,
092            AliasDerefMode.DEREF_ALWAYS );
093        
094        if ( results.first() )
095        {
096            Entry entry = results.get();
097            results.close();
098
099            return entry;
100        }
101
102        return null;
103    }
104
105
106    /**
107     * Initializes and returns a {@link StoredProcEngine} instance which can operate on spUnitEntry
108     * considering its specific stored procedure language.
109     * 
110     * @param spUnitEntry The entry which a {@link StoredProcEngine} type will be mathched with respect to the language identifier.
111     * @return A {@link StoredProcEngine} associated with spUnitEntry.
112     * @throws org.apache.directory.api.ldap.model.exception.LdapException If no {@link StoredProcEngine} that can be associated with the language identifier in spUnitEntry can be found.
113     */
114    public StoredProcEngine getStoredProcEngineInstance( Entry spUnitEntry ) throws LdapException
115    {
116        String spLangId = ( ( ClonedServerEntry ) spUnitEntry ).getOriginalEntry().get( "storedProcLangId" )
117            .getString();
118
119        for ( StoredProcEngineConfig engineConfig : storedProcEngineConfigs )
120        {
121            if ( engineConfig.getStoredProcLangId().equalsIgnoreCase( spLangId ) )
122            {
123                Class<? extends StoredProcEngine> engineType = engineConfig.getStoredProcEngineType();
124                StoredProcEngine engine;
125
126                try
127                {
128                    engine = engineType.newInstance();
129                }
130                catch ( InstantiationException | IllegalAccessException e )
131                {
132                    LdapException ne = new LdapException( e.getMessage(), e );
133                    ne.initCause( e );
134                    throw ne;
135                }
136
137                engine.setSPUnitEntry( ( Entry ) ( ( ClonedServerEntry ) spUnitEntry ).getOriginalEntry() );
138                return engine;
139            }
140
141        }
142
143        throw new LdapException( I18n.err( I18n.ERR_294, spLangId ) );
144
145    }
146
147}