001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.activemq.ra; 018 019 import java.io.IOException; 020 import java.io.ObjectInputStream; 021 import java.io.ObjectOutputStream; 022 import java.io.PrintWriter; 023 import java.io.Serializable; 024 import java.util.Iterator; 025 import java.util.Set; 026 027 import javax.jms.JMSException; 028 import javax.resource.ResourceException; 029 import javax.resource.spi.ConnectionManager; 030 import javax.resource.spi.ConnectionRequestInfo; 031 import javax.resource.spi.ManagedConnection; 032 import javax.resource.spi.ManagedConnectionFactory; 033 import javax.resource.spi.ResourceAdapter; 034 import javax.resource.spi.ResourceAdapterAssociation; 035 import javax.security.auth.Subject; 036 import org.slf4j.LoggerFactory; 037 038 /** 039 * @version $Revisio n$ TODO: Must override equals and hashCode (JCA spec 16.4) 040 * @org.apache.xbean.XBean element="managedConnectionFactory" 041 */ 042 public class ActiveMQManagedConnectionFactory extends ActiveMQConnectionSupport 043 implements ManagedConnectionFactory, ResourceAdapterAssociation { 044 045 private static final long serialVersionUID = 6196921962230582875L; 046 private PrintWriter logWriter; 047 048 /** 049 * @see javax.resource.spi.ResourceAdapterAssociation#setResourceAdapter(javax.resource.spi.ResourceAdapter) 050 */ 051 public void setResourceAdapter(ResourceAdapter adapter) throws ResourceException { 052 if (!(adapter instanceof MessageResourceAdapter)) { 053 throw new ResourceException("ResourceAdapter is not of type: " + MessageResourceAdapter.class.getName()); 054 } 055 else 056 { 057 if ( log.isDebugEnabled() ) { 058 log.debug("copying standard ResourceAdapter configuration properties"); 059 } 060 ActiveMQConnectionRequestInfo baseInfo = ((MessageResourceAdapter) adapter).getInfo().copy(); 061 if (getClientid() == null) { 062 setClientid(baseInfo.getClientid()); 063 } 064 if (getPassword() == null) { 065 setPassword(baseInfo.getPassword()); 066 } 067 if (getServerUrl() == null) { 068 setServerUrl(baseInfo.getServerUrl()); 069 } 070 if (getUseInboundSession() == null) { 071 setUseInboundSession(baseInfo.getUseInboundSession()); 072 } 073 if (getUserName() == null) { 074 setUserName(baseInfo.getUserName()); 075 } 076 } 077 } 078 079 /** 080 * @see javax.resource.spi.ResourceAdapterAssociation#getResourceAdapter() 081 */ 082 public ResourceAdapter getResourceAdapter() { 083 return null; 084 } 085 086 /** 087 * @see java.lang.Object#equals(java.lang.Object) 088 */ 089 @Override 090 public boolean equals(Object object) { 091 if (object == null || object.getClass() != ActiveMQManagedConnectionFactory.class) { 092 return false; 093 } 094 return ((ActiveMQManagedConnectionFactory)object).getInfo().equals(getInfo()); 095 } 096 097 /** 098 * @see java.lang.Object#hashCode() 099 */ 100 @Override 101 public int hashCode() { 102 return getInfo().hashCode(); 103 } 104 105 /** 106 * Writes this factory during serialization along with the superclass' <i>info</i> property. 107 * This needs to be done manually since the superclass is not serializable itself. 108 * 109 * @param out the stream to write object state to 110 * @throws java.io.IOException if the object cannot be serialized 111 */ 112 private void writeObject(ObjectOutputStream out) throws IOException { 113 if ( logWriter != null && !(logWriter instanceof Serializable) ) { 114 // if the PrintWriter injected by the application server is not 115 // serializable we just drop the reference and let the application 116 // server re-inject a PrintWriter later (after this factory has been 117 // deserialized again) using the standard setLogWriter() method 118 logWriter = null; 119 } 120 out.defaultWriteObject(); 121 out.writeObject(getInfo()); 122 } 123 124 /** 125 * Restores this factory along with the superclass' <i>info</i> property. 126 * This needs to be done manually since the superclass is not serializable itself. 127 * 128 * @param in the stream to read object state from 129 * @throws java.io.IOException if the object state could not be restored 130 * @throws java.lang.ClassNotFoundException if the object state could not be restored 131 */ 132 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 133 in.defaultReadObject(); 134 setInfo((ActiveMQConnectionRequestInfo) in.readObject()); 135 log = LoggerFactory.getLogger(getClass()); 136 } 137 138 /** 139 * @see javax.resource.spi.ManagedConnectionFactory#createConnectionFactory(javax.resource.spi.ConnectionManager) 140 */ 141 public Object createConnectionFactory(ConnectionManager manager) throws ResourceException { 142 return new ActiveMQConnectionFactory(this, manager, getInfo()); 143 } 144 145 /** 146 * This is used when not running in an app server. For now we are creating a 147 * ConnectionFactory that has our SimpleConnectionManager implementation but 148 * it may be a better idea to not support this. The JMS api will have many 149 * quirks the user may not expect when running through the resource adapter. 150 * 151 * @see javax.resource.spi.ManagedConnectionFactory#createConnectionFactory() 152 */ 153 public Object createConnectionFactory() throws ResourceException { 154 return new ActiveMQConnectionFactory(this, new SimpleConnectionManager(), getInfo()); 155 } 156 157 /** 158 * @see javax.resource.spi.ManagedConnectionFactory#createManagedConnection(javax.security.auth.Subject, 159 * javax.resource.spi.ConnectionRequestInfo) 160 */ 161 public ManagedConnection createManagedConnection( 162 Subject subject, 163 ConnectionRequestInfo connectionRequestInfo) throws ResourceException { 164 ActiveMQConnectionRequestInfo amqInfo = getInfo(); 165 if ( connectionRequestInfo instanceof ActiveMQConnectionRequestInfo ) { 166 amqInfo = (ActiveMQConnectionRequestInfo) connectionRequestInfo; 167 } 168 try { 169 return new ActiveMQManagedConnection(subject, makeConnection(amqInfo), amqInfo); 170 } catch (JMSException e) { 171 throw new ResourceException("Could not create connection.", e); 172 } 173 } 174 175 /** 176 * @see javax.resource.spi.ManagedConnectionFactory#matchManagedConnections(java.util.Set, 177 * javax.security.auth.Subject, 178 * javax.resource.spi.ConnectionRequestInfo) 179 */ 180 public ManagedConnection matchManagedConnections( 181 Set connections, 182 Subject subject, 183 ConnectionRequestInfo connectionRequestInfo) throws ResourceException { 184 Iterator iterator = connections.iterator(); 185 while (iterator.hasNext()) { 186 ActiveMQManagedConnection c = (ActiveMQManagedConnection)iterator.next(); 187 if (c.matches(subject, connectionRequestInfo)) { 188 try { 189 c.associate(subject, (ActiveMQConnectionRequestInfo) connectionRequestInfo); 190 return c; 191 } catch (JMSException e) { 192 throw new ResourceException(e); 193 } 194 } 195 } 196 return null; 197 } 198 199 /** 200 * @see javax.resource.spi.ManagedConnectionFactory#setLogWriter(java.io.PrintWriter) 201 */ 202 public void setLogWriter(PrintWriter aLogWriter) throws ResourceException { 203 if ( log.isTraceEnabled() ) { 204 log.trace("setting log writer [" + aLogWriter + "]"); 205 } 206 this.logWriter = aLogWriter; 207 } 208 209 /** 210 * @see javax.resource.spi.ManagedConnectionFactory#getLogWriter() 211 */ 212 public PrintWriter getLogWriter() throws ResourceException { 213 if ( log.isTraceEnabled() ) { 214 log.trace("getting log writer [" + logWriter + "]"); 215 } 216 return logWriter; 217 } 218 219 }