KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > jms > listener > serversession > AbstractPoolingServerSessionFactory


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.jms.listener.serversession;
18
19 import javax.jms.JMSException JavaDoc;
20 import javax.jms.ServerSession JavaDoc;
21 import javax.jms.Session JavaDoc;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25
26 import org.springframework.core.task.TaskExecutor;
27 import org.springframework.jms.support.JmsUtils;
28 import org.springframework.scheduling.timer.TimerTaskExecutor;
29
30 /**
31  * Abstract base class for ServerSessionFactory implementations
32  * that pool ServerSessionFactory instances.
33  *
34  * <p>Provides a factory method that creates a poolable ServerSession
35  * (to be added as new instance to a pool), a callback method invoked
36  * when a ServerSession finished an execution of its listener (to return
37  * an instance to the pool), and a method to destroy a ServerSession instance
38  * (after removing an instance from the pool).
39  *
40  * @author Juergen Hoeller
41  * @since 2.0
42  * @see org.springframework.jms.listener.serversession.CommonsPoolServerSessionFactory
43  */

44 public abstract class AbstractPoolingServerSessionFactory implements ServerSessionFactory {
45
46     protected final Log logger = LogFactory.getLog(getClass());
47
48     private TaskExecutor taskExecutor;
49
50     private int maxSize;
51
52
53     /**
54      * Specify the TaskExecutor to use for executing ServerSessions
55      * (and consequently, the underlying MessageListener).
56      * <p>Default is a {@link org.springframework.scheduling.timer.TimerTaskExecutor}
57      * for each pooled ServerSession, using one Thread per pooled JMS Session.
58      * Alternatives are a shared TimerTaskExecutor, sharing a single Thread
59      * for the execution of all ServerSessions, or a TaskExecutor
60      * implementation backed by a thread pool.
61      */

62     public void setTaskExecutor(TaskExecutor taskExecutor) {
63         this.taskExecutor = taskExecutor;
64     }
65
66     /**
67      * Return the TaskExecutor to use for executing ServerSessions.
68      */

69     protected TaskExecutor getTaskExecutor() {
70         return this.taskExecutor;
71     }
72
73     /**
74      * Set the maximum size of the pool.
75      */

76     public void setMaxSize(int maxSize) {
77         this.maxSize = maxSize;
78     }
79
80     /**
81      * Return the maximum size of the pool.
82      */

83     public int getMaxSize() {
84         return this.maxSize;
85     }
86
87
88     /**
89      * Create a new poolable ServerSession.
90      * To be called when a new instance should be added to the pool.
91      * @param sessionManager the listener session manager to create the
92      * poolable ServerSession for
93      * @return the new poolable ServerSession
94      * @throws JMSException if creation failed
95      */

96     protected final ServerSession JavaDoc createServerSession(ListenerSessionManager sessionManager) throws JMSException JavaDoc {
97         return new PoolableServerSession(sessionManager);
98     }
99
100     /**
101      * Destroy the given poolable ServerSession.
102      * To be called when an instance got removed from the pool.
103      * @param serverSession the poolable ServerSession to destroy
104      */

105     protected final void destroyServerSession(ServerSession JavaDoc serverSession) {
106         if (serverSession != null) {
107             ((PoolableServerSession) serverSession).close();
108         }
109     }
110
111
112     /**
113      * Template method called by a ServerSession if it finished
114      * execution of its listener and is ready to go back into the pool.
115      * <p>Subclasses should implement the actual returning of the instance
116      * to the pool.
117      * @param serverSession the ServerSession that finished its execution
118      * @param sessionManager the session manager that the ServerSession belongs to
119      */

120     protected abstract void serverSessionFinished(
121             ServerSession JavaDoc serverSession, ListenerSessionManager sessionManager);
122
123
124     /**
125      * ServerSession implementation designed to be pooled.
126      * Creates a new JMS Session on instantiation, reuses it
127      * for all executions, and closes it on <code>close</code>.
128      * <p>Creates a TimerTaskExecutor (using a single Thread) per
129      * ServerSession, unless given a specific TaskExecutor to use.
130      */

131     private class PoolableServerSession implements ServerSession JavaDoc {
132
133         private final ListenerSessionManager sessionManager;
134
135         private final Session JavaDoc session;
136
137         private TaskExecutor taskExecutor;
138
139         private TimerTaskExecutor internalExecutor;
140
141         public PoolableServerSession(final ListenerSessionManager sessionManager) throws JMSException JavaDoc {
142             this.sessionManager = sessionManager;
143             this.session = sessionManager.createListenerSession();
144             this.taskExecutor = getTaskExecutor();
145             if (this.taskExecutor == null) {
146                 this.internalExecutor = new TimerTaskExecutor();
147                 this.internalExecutor.afterPropertiesSet();
148                 this.taskExecutor = this.internalExecutor;
149             }
150         }
151
152         public Session JavaDoc getSession() {
153             return this.session;
154         }
155
156         public void start() {
157             this.taskExecutor.execute(new Runnable JavaDoc() {
158                 public void run() {
159                     try {
160                         sessionManager.executeListenerSession(session);
161                     }
162                     finally {
163                         serverSessionFinished(PoolableServerSession.this, sessionManager);
164                     }
165                 }
166             });
167         }
168
169         public void close() {
170             if (this.internalExecutor != null) {
171                 this.internalExecutor.destroy();
172             }
173             JmsUtils.closeSession(this.session);
174         }
175     }
176
177 }
178
Popular Tags