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.tide.seam; 022 023import static org.jboss.seam.annotations.Install.FRAMEWORK; 024 025import java.io.Serializable; 026 027import org.granite.tide.seam.async.AsyncContext; 028import org.jboss.seam.Component; 029import org.jboss.seam.ScopeType; 030import org.jboss.seam.annotations.AutoCreate; 031import org.jboss.seam.annotations.Install; 032import org.jboss.seam.annotations.Name; 033import org.jboss.seam.annotations.Scope; 034import org.jboss.seam.annotations.intercept.BypassInterceptors; 035import org.jboss.seam.async.Schedule; 036import org.jboss.seam.core.Events; 037 038 039/** 040 * TideEvents override to intercept Seam events handling 041 * 042 * @author William DRAI 043 */ 044@Name("org.jboss.seam.core.events") 045@Install(precedence=FRAMEWORK) 046@Scope(ScopeType.STATELESS) 047@BypassInterceptors 048@AutoCreate 049public class TideEvents extends Events { 050 051 052 @Override 053 public void raiseEvent(String type, Object... parameters) { 054 if (ASYNC_EVENT.equals(type)) { 055 TideInvocation.init(); 056 AbstractSeamServiceContext serviceContext = (AbstractSeamServiceContext)Component.getInstance(AbstractSeamServiceContext.COMPONENT_NAME, true); 057 058 WrappedEvent event = (WrappedEvent)parameters[0]; 059 serviceContext.setAsyncContext(event.getAsyncContext()); // Reset context 060 061 raiseEvent(event.getType(), event.getParams()); 062 063 // Send event through Gravity only 064 serviceContext.sendEvent(null, null); 065 } 066 else { 067 super.raiseEvent(type, parameters); 068 069 // Ignore built-in Seam events to avoid stack overflow in component initialization 070 if (!type.startsWith("org.jboss.seam.pre") && !type.startsWith("org.jboss.seam.post")) { 071 // Event should be always handled if we want to allow to send them through Gravity 072 AbstractSeamServiceContext serviceContext = (AbstractSeamServiceContext)Component.getInstance(AbstractSeamServiceContext.COMPONENT_NAME, false); 073 if (serviceContext != null) // ServiceContext is null during Seam initialization 074 serviceContext.raiseEvent(type, parameters); 075 } 076 } 077 } 078 079 080 protected static final String ASYNC_EVENT = "org.granite.tide.seam.AsyncEvent"; 081 082 protected static class WrappedEvent implements Serializable { 083 084 private static final long serialVersionUID = 1L; 085 086 private AsyncContext asyncContext; 087 private String type; 088 private Object[] params; 089 090 public WrappedEvent(AsyncContext asyncContext, String type, Object[] params) { 091 this.asyncContext = asyncContext; 092 this.type = type; 093 this.params = params; 094 } 095 096 public AsyncContext getAsyncContext() { 097 return asyncContext; 098 } 099 100 public String getType() { 101 return type; 102 } 103 104 public Object[] getParams() { 105 return params; 106 } 107 } 108 109 110 @Override 111 public void raiseAsynchronousEvent(String type, Object... parameters) { 112 AbstractSeamServiceContext serviceContext = (AbstractSeamServiceContext)Component.getInstance(AbstractSeamServiceContext.COMPONENT_NAME, false); 113 String sessionId = serviceContext != null ? serviceContext.getSessionId() : null; 114 if (serviceContext != null && sessionId != null) 115 super.raiseAsynchronousEvent(ASYNC_EVENT, new WrappedEvent(serviceContext.getAsyncContext(), type, parameters)); 116 else 117 super.raiseAsynchronousEvent(type, parameters); 118 } 119 120 121 // Seam 2.0 122 @SuppressWarnings("all") 123 public void raiseTimedEvent(String type, Object schedule, Object... parameters) { 124 AbstractSeamServiceContext serviceContext = (AbstractSeamServiceContext)Component.getInstance(AbstractSeamServiceContext.COMPONENT_NAME, false); 125 String sessionId = serviceContext != null ? serviceContext.getSessionId() : null; 126 if (serviceContext != null && sessionId != null) 127 super.raiseTimedEvent(ASYNC_EVENT, (Schedule)schedule, new WrappedEvent(serviceContext.getAsyncContext(), type, parameters)); 128 else 129 super.raiseTimedEvent(type, (Schedule)schedule, parameters); 130 } 131}