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.apache.commons.logging.LogFactory;
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 = LogFactory.getLog(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 }