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 flex.messaging.messages;
022    
023    import org.apache.log4j.Logger;
024    import org.granite.messaging.service.ServiceException;
025    import org.granite.messaging.service.security.SecurityServiceException;
026    
027    import java.io.PrintWriter;
028    import java.io.StringWriter;
029    import java.util.HashMap;
030    import java.util.Map;
031    
032    /**
033     * @author Franck WOLFF
034     */
035    public class ErrorMessage extends AcknowledgeMessage {
036    
037        private static final long serialVersionUID = 1L;
038        
039        private static final Logger log = Logger.getLogger("org.granite.logging.ExceptionStackTrace");
040    
041        private String faultCode = "Server.Call.Failed";
042        private String faultDetail;
043        private String faultString;
044        private Object rootCause;
045        private Map<String, Object> extendedData;
046    
047        private transient boolean loginError = false;
048    
049        public ErrorMessage() {
050            super();
051        }
052    
053        public ErrorMessage(Throwable t) {
054            super();
055            init(t);
056        }
057    
058        public ErrorMessage(Message request) {
059            this(request, false);
060        }
061    
062        public ErrorMessage(Message request, Throwable t) {
063            this(request, t, false);
064        }
065    
066        public ErrorMessage(Message request, boolean keepClientId) {
067            super(request, keepClientId);
068        }
069    
070        public ErrorMessage(Message request, Throwable t, boolean keepClientId) {
071            super(request, keepClientId);
072            if (request instanceof CommandMessage) {
073                loginError = (
074                    ((CommandMessage)request).isLoginOperation() &&
075                    (t instanceof SecurityServiceException)
076                );
077            }
078            init(t);
079        }
080    
081        private void init(Throwable t) {
082            if (t instanceof ServiceException) {
083                ServiceException se = (ServiceException)t;
084    
085                this.faultCode = se.getCode();
086                this.faultString = se.getMessage();
087    
088                if (t instanceof SecurityServiceException)
089                    this.faultDetail = se.getDetail();
090                else
091                    this.faultDetail = se.getDetail() + getStackTrace(t);
092                
093                this.extendedData = se.getExtendedData();
094            }
095            else if (t != null) {
096                this.faultString = t.getMessage();
097                this.faultDetail = t.getMessage();
098            }
099    
100            if (!(t instanceof SecurityServiceException)) {
101                for (Throwable root = t; root != null; root = root.getCause())
102                    rootCause = root;
103            }
104            if (rootCause != null && !log.isDebugEnabled())
105                rootCause = ((Throwable)rootCause).getMessage();
106        }
107    
108        private String getStackTrace(Throwable t) {
109            if (!log.isDebugEnabled())
110                    return "";
111            StringWriter sw = new StringWriter();
112            t.printStackTrace(new PrintWriter(sw));
113            return sw.toString().replace("\r\n", "\n").replace('\r', '\n');
114        }
115    
116        public String getFaultCode() {
117            return faultCode;
118        }
119        public void setFaultCode(String faultCode) {
120            this.faultCode = faultCode;
121        }
122    
123        public String getFaultDetail() {
124            return faultDetail;
125        }
126        public void setFaultDetail(String faultDetail) {
127            this.faultDetail = faultDetail;
128        }
129    
130        public String getFaultString() {
131            return faultString;
132        }
133        public void setFaultString(String faultString) {
134            this.faultString = faultString;
135        }
136    
137        public Map<String, Object> getExtendedData() {
138            return extendedData;
139        }
140        public void setExtendedData(Map<String, Object> extendedData) {
141            this.extendedData = extendedData;
142        }
143    
144        public Object getRootCause() {
145            return rootCause;
146        }
147        public void setRootCause(Object rootCause) {
148            this.rootCause = rootCause;
149        }
150    
151        public boolean loginError() {
152            return loginError;
153        }
154    
155        public ErrorMessage copy(Message request) {
156            ErrorMessage copy = new ErrorMessage(request, null);
157            copy.faultCode = faultCode;
158            copy.faultDetail = faultDetail;
159            copy.faultString = faultString;
160            copy.loginError = loginError;
161            copy.rootCause = rootCause;
162            copy.extendedData = new HashMap<String, Object>(extendedData);
163            return copy;
164        }
165    
166        @Override
167        public String toString() {
168            return toString("");
169        }
170    
171        @Override
172        public String toString(String indent) {
173            StringBuilder sb = new StringBuilder(512);
174            sb.append(getClass().getName()).append(" {");
175            sb.append('\n').append(indent).append("  faultCode = ").append(faultCode);
176            sb.append('\n').append(indent).append("  faultDetail = ").append(faultDetail);
177            sb.append('\n').append(indent).append("  faultString = ").append(faultString);
178            sb.append('\n').append(indent).append("  rootCause = ").append(rootCause);
179            sb.append('\n').append(indent).append("  extendedData = ").append(extendedData);
180            super.toString(sb, indent, null);
181            sb.append('\n').append(indent).append('}');
182            return sb.toString();
183        }
184    }