001/* 002 GRANITE DATA SERVICES 003 Copyright (C) 2011 GRANITE DATA SERVICES S.A.S. 004 005 This file is part of Granite Data Services. 006 007 Granite Data Services is free software; you can redistribute it and/or modify 008 it under the terms of the GNU Library General Public License as published by 009 the Free Software Foundation; either version 2 of the License, or (at your 010 option) any later version. 011 012 Granite Data Services is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License 015 for more details. 016 017 You should have received a copy of the GNU Library General Public License 018 along with this library; if not, see <http://www.gnu.org/licenses/>. 019*/ 020 021package org.granite.gravity.jetty8; 022 023import org.eclipse.jetty.continuation.Continuation; 024import org.granite.gravity.AbstractChannel; 025import org.granite.gravity.AsyncHttpContext; 026import org.granite.gravity.Gravity; 027import org.granite.gravity.GravityConfig; 028import org.granite.gravity.MessageReceivingException; 029import org.granite.logging.Logger; 030 031import flex.messaging.messages.AsyncMessage; 032 033/** 034 * @author William DRAI 035 */ 036public class ContinuationChannel extends AbstractChannel { 037 038 private static final Logger log = Logger.getLogger(ContinuationChannel.class); 039 040 private Continuation continuation = null; 041 042 public ContinuationChannel(Gravity gravity, String id, ContinuationChannelFactory factory, String clientType) { 043 super(gravity, id, factory, clientType); 044 } 045 046 public void setContinuation(Continuation continuation) { 047 log.debug("Setting continuation %s for client: %s", continuation, getId()); 048 try { 049 if (this.continuation != null && this.continuation.isSuspended()) { 050 log.debug("Resuming previous continuation %s for client: %s", this.continuation, getId()); 051 this.continuation.resume(); 052 } 053 } 054 finally { 055 this.continuation = continuation; 056 } 057 } 058 059 public void close() { 060 this.continuation = null; 061// try { 062// if (this.continuation != null) 063// this.continuation. 064// } 065// finally { 066// this.continuation = null; 067// } 068 } 069 070 071 public void resume() { 072 log.debug("Resuming pending continuation %s for client: %s", continuation, getId()); 073 try { 074 if (this.continuation != null && this.continuation.isSuspended()) 075 this.continuation.resume(); 076 } 077 finally { 078 this.continuation = null; 079 } 080 } 081 082 @Override 083 public void receive(AsyncMessage message) throws MessageReceivingException { 084 if (message == null) 085 throw new NullPointerException("message cannot be null"); 086 087 GravityConfig gravityConfig = gravity.getGravityConfig(); 088 089 receivedQueueLock.lock(); 090 try { 091 if (receivedQueue.size() + 1 > gravityConfig.getMaxMessagesQueuedPerChannel()) 092 throw new MessageReceivingException(message, "Could not queue message (channel's queue is full) for channel: " + this); 093 094 receivedQueue.add(message); 095 } 096 finally { 097 receivedQueueLock.unlock(); 098 } 099 100 synchronized (this) { 101 resume(); 102 } 103 } 104 105 @Override 106 protected boolean hasAsyncHttpContext() { 107 return false; 108 } 109 110 @Override 111 protected void releaseAsyncHttpContext(AsyncHttpContext context) { 112 } 113 114 @Override 115 protected AsyncHttpContext acquireAsyncHttpContext() { 116 return null; 117 } 118 119 public boolean isLocal() { 120 return true; 121 } 122 123 @Override 124 public void destroy() { 125 try { 126 super.destroy(); 127 } 128 finally { 129 synchronized (this) { 130 close(); 131 } 132 } 133 } 134}