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.messaging.amf.process; 022 023import java.util.Date; 024 025import org.granite.config.GraniteConfig; 026import org.granite.context.GraniteContext; 027import org.granite.logging.Logger; 028import org.granite.messaging.service.ServiceException; 029import org.granite.messaging.service.ServiceFactory; 030import org.granite.messaging.service.ServiceInvoker; 031import org.granite.messaging.service.security.SecurityService; 032import org.granite.messaging.service.security.SecurityServiceException; 033import org.granite.messaging.webapp.ServletGraniteContext; 034import org.granite.util.UUIDUtil; 035 036import flex.messaging.messages.AcknowledgeMessage; 037import flex.messaging.messages.CommandMessage; 038import flex.messaging.messages.ErrorMessage; 039import flex.messaging.messages.Message; 040import flex.messaging.messages.RemotingMessage; 041 042/** 043 * @author Franck WOLFF 044 */ 045public abstract class AMF3MessageProcessor { 046 047 private static final Logger log = Logger.getLogger(AMF3MessageProcessor.class); 048 049 public static Message process(Message request) { 050 GraniteContext context = GraniteContext.getCurrentInstance(); 051 AMF3MessageInterceptor interceptor = context.getGraniteConfig().getAmf3MessageInterceptor(); 052 053 Message response = null; 054 try { 055 if (interceptor != null) 056 interceptor.before(request); 057 058 if (request instanceof RemotingMessage) 059 response = processRemotingMessage((RemotingMessage)request); 060 else if (request instanceof CommandMessage) 061 response = processCommandMessage((CommandMessage)request); 062 else 063 throw new IllegalArgumentException("Unknown request message type: " + request); 064 } 065 finally { 066 if (interceptor != null) 067 interceptor.after(request, response); 068 } 069 070 if (context.getSessionId() != null) { 071 response.setHeader("org.granite.sessionId", context.getSessionId()); 072 if (((ServletGraniteContext)context).getSession(false) != null) { 073 long serverTime = new Date().getTime(); 074 ((ServletGraniteContext)context).getSession().setAttribute(GraniteContext.SESSION_LAST_ACCESSED_TIME_KEY, serverTime); 075 response.setHeader("org.granite.time", serverTime); 076 response.setHeader("org.granite.sessionExp", ((ServletGraniteContext)context).getSession().getMaxInactiveInterval()); 077 } 078 } 079 080 return response; 081 } 082 083 public static Message processCommandMessage(CommandMessage request) { 084 085 log.debug(">> Processing AMF3 request:\n%s", request); 086 087 Message response = null; 088 if (request.isSecurityOperation()) { 089 GraniteContext context = GraniteContext.getCurrentInstance(); 090 GraniteConfig config = context.getGraniteConfig(); 091 092 if (!config.hasSecurityService()) 093 log.warn("Ignored security operation (no security settings in granite-config.xml): %s", request); 094 else { 095 SecurityService securityService = config.getSecurityService(); 096 try { 097 if (request.isLoginOperation()) 098 securityService.login(request.getBody(), (String)request.getHeader(Message.CREDENTIALS_CHARSET_HEADER)); 099 else if (request.isLogoutOperation()) 100 securityService.logout(); 101 else 102 log.warn("Unknown security operation: %s", request); 103 } catch (Exception e) { 104 if (e instanceof SecurityServiceException) { 105 securityService.handleSecurityException((SecurityServiceException)e); 106 log.debug(e, "Could not process security operation: %s", request); 107 } 108 else 109 log.error(e, "Could not process security operation: %s", request); 110 response = new ErrorMessage(request, e); 111 } 112 } 113 } 114 115 if (response == null) { 116 response = new AcknowledgeMessage(request); 117 // For SDK 2.0.1_Hotfix2. 118 if (request.isSecurityOperation()) 119 response.setBody("success"); 120 } 121 122 // For SDK 2.0.1_Hotfix2. 123 if ("nil".equals(request.getHeader(Message.DS_ID_HEADER))) 124 response.getHeaders().put(Message.DS_ID_HEADER, UUIDUtil.randomUUID()); 125 126 log.debug("<< Returning AMF3 response:\n%s", response); 127 128 return response; 129 } 130 131 public static Message processRemotingMessage(RemotingMessage request) { 132 133 log.debug(">> Processing AMF3 request:\n%s", request); 134 135 Message response = null; 136 try { 137 // Execute method on service. 138 ServiceFactory factory = ServiceFactory.getFactoryInstance(request); 139 ServiceInvoker<?> service = factory.getServiceInstance(request); 140 Object result = service.invoke(request); 141 142 response = new AcknowledgeMessage(request); 143 response.setBody(result); 144 } catch (ServiceException e) { 145 log.debug(e, "Could not process remoting message: %s", request); 146 response = new ErrorMessage(request, e); 147 } 148 149 log.debug("<< Returning AMF3 response:\n%s", response); 150 151 return response; 152 } 153}