001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.sql;
031:
032: import com.caucho.log.Log;
033: import com.caucho.jca.IdlePoolSet;
034: import com.caucho.server.cluster.*;
035: import com.caucho.server.resin.Resin;
036: import com.caucho.util.L10N;
037:
038: import javax.resource.ResourceException;
039: import javax.resource.spi.ConnectionManager;
040: import javax.resource.spi.ConnectionRequestInfo;
041: import javax.resource.spi.ManagedConnection;
042: import javax.resource.spi.ManagedConnectionFactory;
043: import javax.resource.spi.ResourceAdapter;
044: import javax.resource.spi.ValidatingManagedConnectionFactory;
045: import javax.security.auth.Subject;
046: import java.io.PrintWriter;
047: import java.sql.SQLException;
048: import java.util.HashSet;
049: import java.util.Iterator;
050: import java.util.Set;
051: import java.util.logging.Logger;
052:
053: /**
054: * The managed factory implementation.
055: */
056: public class ManagedFactoryImpl implements ManagedConnectionFactory,
057: ValidatingManagedConnectionFactory {
058: protected static final Logger log = Logger
059: .getLogger(ManagedFactoryImpl.class.getName());
060: private static final L10N L = new L10N(ManagedFactoryImpl.class);
061:
062: private DBPoolImpl _dbPool;
063: private DriverConfig[] _drivers;
064: private DriverConfig[] _backupDrivers;
065:
066: private long _roundRobin;
067:
068: ManagedFactoryImpl(DBPoolImpl dbPool, DriverConfig[] drivers,
069: DriverConfig[] backupDrivers) {
070: _dbPool = dbPool;
071: _drivers = drivers;
072: _backupDrivers = backupDrivers;
073:
074: Cluster cluster = Cluster.getLocal();
075: if (cluster != null) {
076: ClusterServer server = cluster.getSelfServer();
077:
078: if (server != null && _drivers.length > 1)
079: _roundRobin = server.getIndex() % _drivers.length;
080: }
081: }
082:
083: /**
084: * Returns the DB pool.
085: */
086: public DBPoolImpl getDBPool() {
087: return _dbPool;
088: }
089:
090: /**
091: * Returns the connection config.
092: */
093: ConnectionConfig getConnectionConfig() {
094: return _dbPool.getConnectionConfig();
095: }
096:
097: /**
098: * Creates the data source the user sees.
099: */
100: public Object createConnectionFactory(ConnectionManager connManager)
101: throws ResourceException {
102: return new DataSourceImpl(this , connManager);
103: }
104:
105: /**
106: * Creates the data source the user sees. Not needed in this case,
107: * since ManagedFactoryImpl is only allowed in Resin.
108: */
109: public Object createConnectionFactory() throws ResourceException {
110: throw new UnsupportedOperationException();
111: }
112:
113: /**
114: * Creates the underlying managed connection.
115: */
116: public ManagedConnection createManagedConnection(Subject subject,
117: ConnectionRequestInfo requestInfo) throws ResourceException {
118: Credential credential = (Credential) requestInfo;
119:
120: SQLException exn = null;
121:
122: for (int i = 0; i < _drivers.length; i++) {
123: int index = (int) (_roundRobin++ % _drivers.length);
124:
125: DriverConfig driver = _drivers[index];
126:
127: try {
128: return new ManagedConnectionImpl(this , driver, _dbPool
129: .getConnectionConfig(), credential);
130: } catch (SQLException e) {
131: exn = e;
132: }
133: }
134:
135: for (int i = 0; i < _backupDrivers.length; i++) {
136: int index = (int) (_roundRobin++ % _backupDrivers.length);
137:
138: DriverConfig driver = _backupDrivers[index];
139:
140: try {
141: return new ManagedConnectionImpl(this , driver, _dbPool
142: .getConnectionConfig(), credential);
143: } catch (SQLException e) {
144: exn = e;
145: }
146: }
147:
148: if (exn != null)
149: throw new ResourceException(exn);
150: else
151: throw new ResourceException(L.l("Can't open database"));
152: }
153:
154: /**
155: * Creates the underlying managed connection.
156: */
157: public ManagedConnection matchManagedConnections(Set connSet,
158: Subject subject, ConnectionRequestInfo requestInfo)
159: throws ResourceException {
160: if (connSet instanceof IdlePoolSet) {
161: IdlePoolSet idle = (IdlePoolSet) connSet;
162:
163: ManagedConnectionImpl mConn = (ManagedConnectionImpl) idle
164: .first();
165:
166: if (mConn == null)
167: return null;
168:
169: Credential mCredentials = mConn.getCredentials();
170:
171: if (requestInfo == mCredentials || requestInfo != null
172: && requestInfo.equals(mCredentials)) {
173: return mConn;
174: }
175: }
176:
177: Iterator iter = connSet.iterator();
178:
179: while (iter.hasNext()) {
180: ManagedConnectionImpl mConn = (ManagedConnectionImpl) iter
181: .next();
182: Credential mCredentials = mConn.getCredentials();
183:
184: if (requestInfo == mCredentials || requestInfo != null
185: && requestInfo.equals(mCredentials)) {
186: return mConn;
187: }
188: }
189:
190: return null;
191: }
192:
193: /**
194: * Returns any invalid connections.
195: */
196: public Set getInvalidConnections(Set connSet)
197: throws ResourceException {
198: Iterator iter = connSet.iterator();
199: HashSet invalidSet = null;
200:
201: while (iter.hasNext()) {
202: ManagedConnectionImpl mConn = (ManagedConnectionImpl) iter
203: .next();
204:
205: if (!mConn.isValid()) {
206: if (invalidSet == null)
207: invalidSet = new HashSet();
208:
209: invalidSet.add(mConn);
210: }
211: }
212:
213: return invalidSet;
214: }
215:
216: public void setLogWriter(PrintWriter out) throws ResourceException {
217: }
218:
219: public PrintWriter getLogWriter() throws ResourceException {
220: return null;
221: }
222:
223: public ResourceAdapter getResourceAdapter() {
224: return null;
225: }
226:
227: public void setResourceAdapter(ResourceAdapter adapter) {
228: }
229: }
|