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    
021    package org.granite.tide.seam21;
022    
023    import java.lang.reflect.Method;
024    import java.util.ArrayList;
025    import java.util.HashMap;
026    import java.util.List;
027    import java.util.Map;
028    
029    import org.granite.config.flex.Destination;
030    import org.granite.logging.Logger;
031    import org.granite.messaging.service.ExtendedServiceExceptionHandler;
032    import org.granite.messaging.service.ServiceException;
033    import org.granite.tide.TideMessage;
034    import org.jboss.seam.international.StatusMessage;
035    import org.jboss.seam.international.StatusMessages;
036    
037    import flex.messaging.messages.Message;
038    
039    
040    /**
041     * @author Venkat DANDA
042     * @author Cameron INGRAM
043     *
044     * Update services-config.xml to use the seam service exception handler
045     * <factory id="tideSeamFactory" class="org.granite.tide.seam.SeamServiceFactory" >
046     *      <properties>
047     *              <service-exception-handler>org.granite.tide.seam.SeamServiceExceptionHandler</service-exception-handler>
048     *      </properties>
049     * </factory>
050     */
051    public class Seam21ServiceExceptionHandler extends ExtendedServiceExceptionHandler {
052    
053        private static final long serialVersionUID = -1L;
054        
055        private static final Logger log = Logger.getLogger(Seam21ServiceExceptionHandler.class);
056    
057        
058        public Seam21ServiceExceptionHandler() {
059            super(true);
060        }
061    
062        public Seam21ServiceExceptionHandler(boolean logException) {
063            super(logException);
064        }
065    
066        
067            @Override
068        protected ServiceException getServiceException(Message request, Destination destination, String method, Throwable t) {
069            ServiceException se = super.getServiceException(request, destination, method, t);
070            
071            StatusMessages statusMessages = StatusMessages.instance();
072            if (statusMessages != null) {
073                List<TideMessage> tideMessages = new ArrayList<TideMessage>();
074                Map<String, List<TideMessage>> tideKeyedMessages = new HashMap<String, List<TideMessage>>();
075                try {
076                    // Execute and get the messages (once again reflection hack to use protected methods) 
077                    Method m = StatusMessages.class.getDeclaredMethod("doRunTasks");
078                    m.setAccessible(true);
079                    m.invoke(statusMessages);
080                    
081                    Method m2 = StatusMessages.class.getDeclaredMethod("getMessages");
082                    m2.setAccessible(true);
083                    @SuppressWarnings("unchecked")
084                    List<StatusMessage> messages = (List<StatusMessage>)m2.invoke(statusMessages);
085                    
086                    for (StatusMessage msg : messages) {
087                        String severity = null;
088                        if (msg.getSeverity() == StatusMessage.Severity.INFO)
089                            severity = TideMessage.INFO;
090                        else if (msg.getSeverity() == StatusMessage.Severity.WARN)
091                            severity = TideMessage.WARNING;
092                        else if (msg.getSeverity() == StatusMessage.Severity.ERROR)
093                            severity = TideMessage.ERROR;
094                        else if (msg.getSeverity() == StatusMessage.Severity.FATAL)
095                            severity = TideMessage.FATAL;
096                        
097                        tideMessages.add(new TideMessage(severity, msg.getSummary(), msg.getDetail()));
098                    }
099                    
100                    Method m3 = StatusMessages.class.getDeclaredMethod("getKeyedMessages");
101                    m3.setAccessible(true);
102                    @SuppressWarnings("unchecked")
103                    Map<String, List<StatusMessage>> keyedMessages = (Map<String, List<StatusMessage>>)m3.invoke(statusMessages);
104                    for (Map.Entry<String, List<StatusMessage>> me : keyedMessages.entrySet()) {
105                            List<TideMessage> tmsgs = new ArrayList<TideMessage>(me.getValue().size());
106                        for (StatusMessage msg : me.getValue()) {
107                            String severity = null;
108                            if (msg.getSeverity() == StatusMessage.Severity.INFO)
109                                severity = TideMessage.INFO;
110                            else if (msg.getSeverity() == StatusMessage.Severity.WARN)
111                                severity = TideMessage.WARNING;
112                            else if (msg.getSeverity() == StatusMessage.Severity.ERROR)
113                                severity = TideMessage.ERROR;
114                            else if (msg.getSeverity() == StatusMessage.Severity.FATAL)
115                                severity = TideMessage.FATAL;
116                            
117                            tmsgs.add(new TideMessage(severity, msg.getSummary(), msg.getDetail()));
118                        }
119                        tideKeyedMessages.put(me.getKey(), tmsgs);
120                    }
121                }
122                catch (Exception e) {
123                    log.error("Could not get status messages", e);
124                }
125                se.getExtendedData().put("messages", tideMessages);
126                se.getExtendedData().put("keyedMessages", tideKeyedMessages);
127            }
128            return se;
129        }
130    }