001/*
002 * Copyright (c) 2006-2014 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Florent Guillaume
011 */
012package org.nuxeo.ecm.core.storage.sql.ra;
013
014import javax.naming.InitialContext;
015import javax.naming.NamingException;
016import javax.resource.ResourceException;
017import javax.resource.spi.ConnectionManager;
018
019import org.nuxeo.ecm.core.repository.RepositoryFactory;
020import org.nuxeo.ecm.core.storage.sql.RepositoryDescriptor;
021import org.nuxeo.ecm.core.storage.sql.coremodel.SQLRepositoryService;
022import org.nuxeo.runtime.api.Framework;
023import org.nuxeo.runtime.jtajca.NuxeoConnectionManagerConfiguration;
024import org.nuxeo.runtime.jtajca.NuxeoContainer;
025
026/**
027 * Pooling repository factory.
028 * <p>
029 * This class is mentioned in the repository extension point defining a given repository.
030 * <p>
031 * To function properly, it needs the bundle nuxeo-runtime-jtajca to be depoyed.
032 */
033public class PoolingRepositoryFactory implements RepositoryFactory {
034
035    private String repositoryName;
036
037    @Override
038    public void init(String repositoryName) {
039        this.repositoryName = repositoryName;
040    }
041
042    @Override
043    public Object call() {
044        SQLRepositoryService sqlRepositoryService = Framework.getLocalService(SQLRepositoryService.class);
045        RepositoryDescriptor descriptor = sqlRepositoryService.getRepositoryDescriptor(repositoryName);
046        ManagedConnectionFactoryImpl managedConnectionFactory = new ManagedConnectionFactoryImpl();
047        managedConnectionFactory.setName(descriptor.name);
048        try {
049            ConnectionManager connectionManager = lookupConnectionManager(descriptor.pool);
050            return managedConnectionFactory.createConnectionFactory(connectionManager);
051        } catch (NamingException | ResourceException e) {
052            throw new RuntimeException(e);
053        }
054    }
055
056    /**
057     * Various binding names for the ConnectionManager. They depend on the application server used and how the
058     * configuration is done.
059     */
060    private static final String[] CM_NAMES_PREFIXES = { "java:comp/NuxeoConnectionManager/",
061            "java:comp/env/NuxeoConnectionManager/", "java:NuxeoConnectionManager/" };
062
063    protected static ConnectionManager lookupConnectionManager(NuxeoConnectionManagerConfiguration pool)
064            throws NamingException {
065        String name = pool.getName();
066        // Check in container
067        ConnectionManager cm = NuxeoContainer.getConnectionManager(name);
068        if (cm != null) {
069            return cm;
070        }
071        // Check in JNDI
072        InitialContext context = new InitialContext();
073        for (String prefix : CM_NAMES_PREFIXES) {
074            try {
075                cm = (ConnectionManager) context.lookup(prefix + name);
076                if (cm != null) {
077                    return cm;
078                }
079            } catch (NamingException e) {
080                // try next one
081            }
082        }
083        // Creation from descriptor pool config
084        return NuxeoContainer.initConnectionManager(pool);
085    }
086
087}