001/* 002 * (C) Copyright 2006-2011 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 */ 019 020package org.nuxeo.ecm.core.storage.sql.ra; 021 022import java.util.Calendar; 023 024import javax.naming.Reference; 025import javax.resource.ResourceException; 026import javax.resource.cci.ConnectionSpec; 027import javax.resource.cci.RecordFactory; 028import javax.resource.cci.ResourceAdapterMetaData; 029import javax.resource.spi.ConnectionManager; 030 031import org.apache.commons.logging.LogFactory; 032import org.nuxeo.ecm.core.api.NuxeoException; 033import org.nuxeo.ecm.core.api.repository.FulltextConfiguration; 034import org.nuxeo.ecm.core.storage.sql.Repository; 035import org.nuxeo.ecm.core.storage.sql.Session; 036import org.nuxeo.ecm.core.storage.sql.coremodel.SQLSession; 037import org.nuxeo.runtime.jtajca.NuxeoConnectionManagerConfiguration; 038import org.nuxeo.runtime.jtajca.NuxeoContainer; 039import org.nuxeo.runtime.jtajca.NuxeoContainer.ConnectionManagerWrapper; 040 041/** 042 * The connection factory delegates connection requests to the application server {@link ConnectionManager}. 043 * <p> 044 * An instance of this class is returned to the application when a JNDI lookup is done. 045 * 046 * @author Florent Guillaume 047 */ 048public class ConnectionFactoryImpl implements Repository, org.nuxeo.ecm.core.model.Repository { 049 050 private static final long serialVersionUID = 1L; 051 052 private final ManagedConnectionFactoryImpl managedConnectionFactory; 053 054 private final ConnectionManager connectionManager; 055 056 private final String name; 057 058 private Reference reference; 059 060 /** 061 * This is {@code true} if the connectionManager comes from an application server, or {@code false} if the 062 * {@link ConnectionFactoryImpl} was constructed by application code and passed our manual 063 * {@link ConnectionManagerImpl}. 064 */ 065 @SuppressWarnings("unused") 066 private final boolean managed; 067 068 public ConnectionFactoryImpl(ManagedConnectionFactoryImpl managedConnectionFactory, 069 ConnectionManager connectionManager) { 070 this.managedConnectionFactory = managedConnectionFactory; 071 this.connectionManager = connectionManager; 072 managed = !(connectionManager instanceof ConnectionManagerImpl); 073 name = managedConnectionFactory.getName(); 074 } 075 076 /* 077 * ----- javax.resource.cci.ConnectionFactory ----- 078 */ 079 080 /** 081 * Gets a new connection. 082 * 083 * @param connectionSpec the connection spec (unused) 084 * @return the connection 085 */ 086 @Override 087 public Session getConnection(ConnectionSpec connectionSpec) { 088 return getConnection(); 089 } 090 091 /** 092 * Gets a new connection. 093 * 094 * @return the connection 095 */ 096 @Override 097 public Session getConnection() { 098 try { 099 return (Session) connectionManager.allocateConnection(managedConnectionFactory, null); 100 } catch (ResourceException e) { 101 String msg = e.getMessage(); 102 if (msg != null && msg.startsWith("No ManagedConnections available")) { 103 String err = "Connection pool is fully used"; 104 if (connectionManager instanceof ConnectionManagerWrapper) { 105 ConnectionManagerWrapper cmw = (ConnectionManagerWrapper) connectionManager; 106 NuxeoConnectionManagerConfiguration config = cmw.getConfiguration(); 107 err = err + ", consider increasing " + "nuxeo.vcs.blocking-timeout-millis (currently " 108 + config.getBlockingTimeoutMillis() + ") or " + "nuxeo.vcs.max-pool-size (currently " 109 + config.getMaxPoolSize() + ")"; 110 } 111 throw new NuxeoException(err, e); 112 } 113 throw new NuxeoException(e); 114 } 115 } 116 117 @Override 118 public ResourceAdapterMetaData getMetaData() throws ResourceException { 119 // TODO Auto-generated method stub 120 throw new UnsupportedOperationException("Not implemented"); 121 } 122 123 @Override 124 public RecordFactory getRecordFactory() throws ResourceException { 125 throw new UnsupportedOperationException("Not implemented"); 126 } 127 128 /* 129 * ----- javax.naming.Referenceable ----- 130 */ 131 132 @Override 133 public Reference getReference() { 134 return reference; 135 } 136 137 @Override 138 public void setReference(Reference reference) { 139 this.reference = reference; 140 } 141 142 /* 143 * ----- Repository ----- 144 */ 145 146 @Override 147 public void close() { 148 throw new UnsupportedOperationException("Not implemented"); 149 } 150 151 /* 152 * ----- org.nuxeo.ecm.core.model.Repository ----- 153 */ 154 155 @Override 156 public String getName() { 157 return name; 158 } 159 160 @Override 161 public org.nuxeo.ecm.core.model.Session getSession() { 162 return new SQLSession(getConnection(), this); 163 } 164 165 @Override 166 public void shutdown() { 167 try { 168 NuxeoContainer.disposeConnectionManager(connectionManager); 169 } catch (RuntimeException e) { 170 LogFactory.getLog(ConnectionFactoryImpl.class).warn("cannot dispose connection manager of " + name); 171 } 172 try { 173 managedConnectionFactory.shutdown(); 174 } catch (NuxeoException e) { 175 LogFactory.getLog(ConnectionFactoryImpl.class).warn("cannot shutdown connection factory " + name); 176 } 177 } 178 179 @Override 180 public FulltextConfiguration getFulltextConfiguration() { 181 return managedConnectionFactory.getFulltextConfiguration(); 182 } 183 184 /* 185 * ----- org.nuxeo.ecm.core.model.RepositoryManagement ----- 186 */ 187 188 @Override 189 public int getActiveSessionsCount() { 190 return managedConnectionFactory.getActiveSessionsCount(); 191 } 192 193 @Override 194 public long getCacheSize() { 195 return managedConnectionFactory.getCacheSize(); 196 } 197 198 @Override 199 public long getCachePristineSize() { 200 return managedConnectionFactory.getCachePristineSize(); 201 } 202 203 @Override 204 public long getCacheSelectionSize() { 205 return managedConnectionFactory.getCacheSelectionSize(); 206 } 207 208 @Override 209 public int clearCaches() { 210 return managedConnectionFactory.clearCaches(); 211 } 212 213 @Override 214 public void processClusterInvalidationsNext() { 215 managedConnectionFactory.processClusterInvalidationsNext(); 216 } 217 218 @Override 219 public void markReferencedBinaries() { 220 managedConnectionFactory.markReferencedBinaries(); 221 } 222 223 @Override 224 public int cleanupDeletedDocuments(int max, Calendar beforeTime) { 225 return managedConnectionFactory.cleanupDeletedDocuments(max, beforeTime); 226 } 227 228}