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