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