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 */ 017package org.apache.activemq.ra; 018 019import java.io.IOException; 020import java.io.ObjectInputStream; 021import java.io.ObjectOutputStream; 022import java.io.PrintWriter; 023import java.io.Serializable; 024import java.util.Iterator; 025import java.util.Set; 026 027import javax.jms.JMSException; 028import javax.resource.ResourceException; 029import javax.resource.spi.ConnectionManager; 030import javax.resource.spi.ConnectionRequestInfo; 031import javax.resource.spi.ManagedConnection; 032import javax.resource.spi.ManagedConnectionFactory; 033import javax.resource.spi.ResourceAdapter; 034import javax.resource.spi.ResourceAdapterAssociation; 035import javax.security.auth.Subject; 036import 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 */ 042public 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(this + ", copying standard ResourceAdapter configuration properties"); 059 } 060 061 ActiveMQConnectionRequestInfo baseInfo = ((MessageResourceAdapter) adapter).getInfo().copy(); 062 if (getClientid() == null) { 063 setClientid(baseInfo.getClientid()); 064 } 065 if (getPassword() == null) { 066 setPassword(baseInfo.getPassword()); 067 } 068 if (getServerUrl() == null) { 069 setServerUrl(baseInfo.getServerUrl()); 070 } 071 if (getUseInboundSession() == null) { 072 setUseInboundSession(baseInfo.getUseInboundSession()); 073 } 074 if (getUseSessionArgs() == null) { 075 setUseSessionArgs(baseInfo.isUseSessionArgs()); 076 } 077 if (getUserName() == null) { 078 setUserName(baseInfo.getUserName()); 079 } 080 if (getDurableTopicPrefetch() != null) { 081 setDurableTopicPrefetch(baseInfo.getDurableTopicPrefetch()); 082 } 083 if (getOptimizeDurableTopicPrefetch() != null) { 084 setOptimizeDurableTopicPrefetch(baseInfo.getOptimizeDurableTopicPrefetch()); 085 } 086 if (getQueuePrefetch() != null) { 087 setQueuePrefetch(baseInfo.getQueuePrefetch()); 088 } 089 if (getQueueBrowserPrefetch() != null) { 090 setQueueBrowserPrefetch(baseInfo.getQueueBrowserPrefetch()); 091 } 092 if (getTopicPrefetch() != null) { 093 setTopicPrefetch(baseInfo.getTopicPrefetch()); 094 } 095 if (getInputStreamPrefetch() != null) { 096 setInputStreamPrefetch(baseInfo.getInputStreamPrefetch()); 097 } 098 } 099 } 100 101 /** 102 * @see javax.resource.spi.ResourceAdapterAssociation#getResourceAdapter() 103 */ 104 public ResourceAdapter getResourceAdapter() { 105 return null; 106 } 107 108 /** 109 * @see java.lang.Object#equals(java.lang.Object) 110 */ 111 @Override 112 public boolean equals(Object object) { 113 if (object == null || object.getClass() != ActiveMQManagedConnectionFactory.class) { 114 return false; 115 } 116 return ((ActiveMQManagedConnectionFactory)object).getInfo().equals(getInfo()); 117 } 118 119 /** 120 * @see java.lang.Object#hashCode() 121 */ 122 @Override 123 public int hashCode() { 124 return getInfo().hashCode(); 125 } 126 127 /** 128 * Writes this factory during serialization along with the superclass' <i>info</i> property. 129 * This needs to be done manually since the superclass is not serializable itself. 130 * 131 * @param out the stream to write object state to 132 * @throws java.io.IOException if the object cannot be serialized 133 */ 134 private void writeObject(ObjectOutputStream out) throws IOException { 135 if ( logWriter != null && !(logWriter instanceof Serializable) ) { 136 // if the PrintWriter injected by the application server is not 137 // serializable we just drop the reference and let the application 138 // server re-inject a PrintWriter later (after this factory has been 139 // deserialized again) using the standard setLogWriter() method 140 logWriter = null; 141 } 142 out.defaultWriteObject(); 143 out.writeObject(getInfo()); 144 } 145 146 /** 147 * Restores this factory along with the superclass' <i>info</i> property. 148 * This needs to be done manually since the superclass is not serializable itself. 149 * 150 * @param in the stream to read object state from 151 * @throws java.io.IOException if the object state could not be restored 152 * @throws java.lang.ClassNotFoundException if the object state could not be restored 153 */ 154 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 155 in.defaultReadObject(); 156 setInfo((ActiveMQConnectionRequestInfo) in.readObject()); 157 log = LoggerFactory.getLogger(getClass()); 158 } 159 160 /** 161 * @see javax.resource.spi.ManagedConnectionFactory#createConnectionFactory(javax.resource.spi.ConnectionManager) 162 */ 163 public Object createConnectionFactory(ConnectionManager manager) throws ResourceException { 164 return new ActiveMQConnectionFactory(this, manager, getInfo()); 165 } 166 167 /** 168 * This is used when not running in an app server. For now we are creating a 169 * ConnectionFactory that has our SimpleConnectionManager implementation but 170 * it may be a better idea to not support this. The JMS api will have many 171 * quirks the user may not expect when running through the resource adapter. 172 * 173 * @see javax.resource.spi.ManagedConnectionFactory#createConnectionFactory() 174 */ 175 public Object createConnectionFactory() throws ResourceException { 176 return new ActiveMQConnectionFactory(this, new SimpleConnectionManager(), getInfo()); 177 } 178 179 /** 180 * @see javax.resource.spi.ManagedConnectionFactory#createManagedConnection(javax.security.auth.Subject, 181 * javax.resource.spi.ConnectionRequestInfo) 182 */ 183 public ManagedConnection createManagedConnection( 184 Subject subject, 185 ConnectionRequestInfo connectionRequestInfo) throws ResourceException { 186 ActiveMQConnectionRequestInfo amqInfo = getInfo(); 187 if ( connectionRequestInfo instanceof ActiveMQConnectionRequestInfo ) { 188 amqInfo = (ActiveMQConnectionRequestInfo) connectionRequestInfo; 189 } 190 try { 191 return new ActiveMQManagedConnection(subject, makeConnection(amqInfo), amqInfo); 192 } catch (JMSException e) { 193 throw new ResourceException("Could not create connection.", e); 194 } 195 } 196 197 /** 198 * @see javax.resource.spi.ManagedConnectionFactory#matchManagedConnections(java.util.Set, 199 * javax.security.auth.Subject, 200 * javax.resource.spi.ConnectionRequestInfo) 201 */ 202 public ManagedConnection matchManagedConnections( 203 Set connections, 204 Subject subject, 205 ConnectionRequestInfo connectionRequestInfo) throws ResourceException { 206 Iterator iterator = connections.iterator(); 207 while (iterator.hasNext()) { 208 ActiveMQManagedConnection c = (ActiveMQManagedConnection)iterator.next(); 209 if (c.matches(subject, connectionRequestInfo)) { 210 try { 211 c.associate(subject, (ActiveMQConnectionRequestInfo) connectionRequestInfo); 212 return c; 213 } catch (JMSException e) { 214 throw new ResourceException(e); 215 } 216 } 217 } 218 return null; 219 } 220 221 /** 222 * @see javax.resource.spi.ManagedConnectionFactory#setLogWriter(java.io.PrintWriter) 223 */ 224 public void setLogWriter(PrintWriter aLogWriter) throws ResourceException { 225 if ( log.isTraceEnabled() ) { 226 log.trace("setting log writer [" + aLogWriter + "]"); 227 } 228 this.logWriter = aLogWriter; 229 } 230 231 /** 232 * @see javax.resource.spi.ManagedConnectionFactory#getLogWriter() 233 */ 234 public PrintWriter getLogWriter() throws ResourceException { 235 if ( log.isTraceEnabled() ) { 236 log.trace("getting log writer [" + logWriter + "]"); 237 } 238 return logWriter; 239 } 240 241 }