001/*
002 * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.storage.sql.ra;
020
021import javax.naming.InitialContext;
022import javax.naming.NamingException;
023import javax.resource.ResourceException;
024import javax.resource.spi.ConnectionManager;
025
026import org.nuxeo.ecm.core.repository.RepositoryFactory;
027import org.nuxeo.ecm.core.storage.sql.RepositoryDescriptor;
028import org.nuxeo.ecm.core.storage.sql.coremodel.SQLRepositoryService;
029import org.nuxeo.runtime.api.Framework;
030import org.nuxeo.runtime.jtajca.NuxeoConnectionManagerConfiguration;
031import org.nuxeo.runtime.jtajca.NuxeoContainer;
032
033/**
034 * Repository factory for VCS, the repository implements internally a JCA pool of sessions.
035 */
036public class PoolingRepositoryFactory implements RepositoryFactory {
037
038    protected final String repositoryName;
039
040    public PoolingRepositoryFactory(String repositoryName) {
041        this.repositoryName = repositoryName;
042    }
043
044    @Override
045    public Object call() {
046        SQLRepositoryService sqlRepositoryService = Framework.getService(SQLRepositoryService.class);
047        RepositoryDescriptor descriptor = sqlRepositoryService.getRepositoryDescriptor(repositoryName);
048        ManagedConnectionFactoryImpl managedConnectionFactory = new ManagedConnectionFactoryImpl(repositoryName);
049        try {
050            NuxeoConnectionManagerConfiguration pool = descriptor.pool;
051            if (pool == null) {
052                pool = new NuxeoConnectionManagerConfiguration();
053                pool.setName("repository/" + repositoryName);
054            }
055            ConnectionManager connectionManager = lookupConnectionManager(pool);
056            return managedConnectionFactory.createConnectionFactory(connectionManager);
057        } catch (NamingException | ResourceException e) {
058            throw new RuntimeException(e);
059        }
060    }
061
062    /**
063     * Various binding names for the ConnectionManager. They depend on the application server used and how the
064     * configuration is done.
065     */
066    private static final String[] CM_NAMES_PREFIXES = { "java:comp/NuxeoConnectionManager/",
067            "java:comp/env/NuxeoConnectionManager/", "java:NuxeoConnectionManager/" };
068
069    protected static ConnectionManager lookupConnectionManager(NuxeoConnectionManagerConfiguration pool)
070            throws NamingException {
071        String name = pool.getName();
072        // Check in container
073        ConnectionManager cm = NuxeoContainer.getConnectionManager(name);
074        if (cm != null) {
075            return cm;
076        }
077        // Check in JNDI
078        InitialContext context = new InitialContext();
079        for (String prefix : CM_NAMES_PREFIXES) {
080            try {
081                cm = (ConnectionManager) context.lookup(prefix + name);
082                if (cm != null) {
083                    return cm;
084                }
085            } catch (NamingException e) {
086                // try next one
087            }
088        }
089        // Creation from descriptor pool config
090        return NuxeoContainer.initConnectionManager(pool);
091    }
092
093}