001 /**
002 *
003 * Copyright 2004 Michael Gaffney
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * 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 **/
018 package org.activemq.ra;
019
020 import java.lang.reflect.Method;
021
022 import javax.jms.Message;
023 import javax.jms.MessageListener;
024 import javax.resource.ResourceException;
025 import javax.resource.spi.endpoint.MessageEndpoint;
026
027 /**
028 * @author <a href="mailto:michael.gaffney@panacya.com">Michael Gaffney </a>
029 */
030 public class MessageEndpointProxy implements MessageListener, MessageEndpoint {
031
032 private static final MessageEndpointState ALIVE = new MessageEndpointAlive();
033 private static final MessageEndpointState DEAD = new MessageEndpointDead();
034
035 private static int proxyCount = 0;
036 private final int proxyID;
037 private MessageEndpoint endpoint;
038 private MessageEndpointState state = ALIVE;
039
040 private static int getID() {
041 return ++proxyCount;
042 }
043
044 public MessageEndpointProxy(MessageEndpoint endpoint) {
045 if (!(endpoint instanceof MessageListener)) {
046 throw new IllegalArgumentException("MessageEndpoint is not a MessageListener");
047 }
048 proxyID = getID();
049 this.endpoint = endpoint;
050 }
051
052 public void beforeDelivery(Method method) throws NoSuchMethodException, ResourceException {
053 state.beforeDelivery(this, method);
054 }
055
056 public void onMessage(Message message) {
057 state.onMessage(this, message);
058 }
059
060 public void afterDelivery() throws ResourceException {
061 state.afterDelivery(this);
062 }
063
064 public void release() {
065 state.release(this);
066 }
067
068 public String toString() {
069 return "MessageEndpointProxy{ " +
070 "proxyID: " + proxyID +
071 ", endpoint: " + endpoint +
072 " }";
073 }
074
075 private abstract static class MessageEndpointState {
076
077 public void beforeDelivery(MessageEndpointProxy proxy, Method method) throws NoSuchMethodException, ResourceException {
078 throw new IllegalStateException();
079 }
080
081 public void onMessage(MessageEndpointProxy proxy, Message message) {
082 throw new IllegalStateException();
083 }
084
085 public void afterDelivery(MessageEndpointProxy proxy) throws ResourceException {
086 throw new IllegalStateException();
087 }
088
089 public void release(MessageEndpointProxy proxy) {
090 throw new IllegalStateException();
091 }
092
093 protected final void transition(MessageEndpointProxy proxy, MessageEndpointState nextState) {
094 proxy.state = nextState;
095 nextState.enter(proxy);
096 }
097
098 protected void enter(MessageEndpointProxy proxy) {
099 }
100 }
101
102 private static class MessageEndpointAlive extends MessageEndpointState {
103
104 public void beforeDelivery(MessageEndpointProxy proxy, Method method) throws NoSuchMethodException, ResourceException {
105 try {
106 proxy.endpoint.beforeDelivery(method);
107 } catch (NoSuchMethodException e) {
108 transition(proxy, DEAD);
109 throw e;
110 } catch (ResourceException e) {
111 transition(proxy, DEAD);
112 throw e;
113 }
114 }
115
116 public void onMessage(MessageEndpointProxy proxy, Message message) {
117 ((MessageListener) proxy.endpoint).onMessage(message);
118 }
119
120 public void afterDelivery(MessageEndpointProxy proxy) throws ResourceException {
121 try {
122 proxy.endpoint.afterDelivery();
123 } catch (ResourceException e) {
124 transition(proxy, DEAD);
125 throw e;
126 }
127 }
128
129 public void release(MessageEndpointProxy proxy) {
130 transition(proxy, DEAD);
131 }
132 }
133
134 private static class MessageEndpointDead extends MessageEndpointState {
135
136 protected void enter(MessageEndpointProxy proxy) {
137 proxy.endpoint.release();
138 proxy.endpoint = null;
139 }
140
141 public void beforeDelivery(MessageEndpointProxy proxy, Method method) throws NoSuchMethodException, ResourceException {
142 throw new InvalidMessageEndpointException();
143 }
144
145 public void onMessage(MessageEndpointProxy proxy, Message message) {
146 throw new InvalidMessageEndpointException();
147 }
148
149 public void afterDelivery(MessageEndpointProxy proxy) throws ResourceException {
150 throw new InvalidMessageEndpointException();
151 }
152
153 public void release(MessageEndpointProxy proxy) {
154 throw new InvalidMessageEndpointException();
155 }
156 }
157 }