001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * Granite Data Services is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * Granite Data Services is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 020 * USA, or see <http://www.gnu.org/licenses/>. 021 */ 022package flex.messaging.messages; 023 024import org.granite.logging.Logger; 025import org.granite.messaging.service.ServiceException; 026import org.granite.messaging.service.security.SecurityServiceException; 027 028import java.io.PrintWriter; 029import java.io.StringWriter; 030import java.util.HashMap; 031import java.util.Map; 032 033/** 034 * @author Franck WOLFF 035 */ 036public class ErrorMessage extends AcknowledgeMessage { 037 038 private static final long serialVersionUID = 1L; 039 040 private static final Logger log = Logger.getLogger("org.granite.logging.ExceptionStackTrace"); 041 042 public static final String CODE_SERVER_CALL_FAILED = "Server.Call.Failed"; 043 044 private String faultCode = CODE_SERVER_CALL_FAILED; 045 private String faultDetail; 046 private String faultString; 047 private Object rootCause; 048 private Map<String, Object> extendedData; 049 050 private transient boolean loginError = false; 051 052 public ErrorMessage() { 053 super(); 054 } 055 056 public ErrorMessage(Throwable t) { 057 super(); 058 init(t); 059 } 060 061 public ErrorMessage(Message request) { 062 this(request, false); 063 } 064 065 public ErrorMessage(Message request, Throwable t) { 066 this(request, t, false); 067 } 068 069 public ErrorMessage(Message request, boolean keepClientId) { 070 super(request, keepClientId); 071 } 072 073 public ErrorMessage(Message request, Throwable t, boolean keepClientId) { 074 super(request, keepClientId); 075 if (request instanceof CommandMessage) { 076 loginError = ( 077 ((CommandMessage)request).isLoginOperation() && 078 (t instanceof SecurityServiceException) 079 ); 080 } 081 init(t); 082 } 083 084 private void init(Throwable t) { 085 if (t instanceof ServiceException) { 086 ServiceException se = (ServiceException)t; 087 088 this.faultCode = se.getCode(); 089 this.faultString = se.getMessage(); 090 091 if (t instanceof SecurityServiceException) 092 this.faultDetail = se.getDetail(); 093 else 094 this.faultDetail = se.getDetail() + getStackTrace(t); 095 096 this.extendedData = se.getExtendedData(); 097 } 098 else if (t != null) { 099 this.faultString = t.getMessage(); 100 this.faultDetail = t.getMessage(); 101 } 102 103 if (!(t instanceof SecurityServiceException)) { 104 for (Throwable root = t; root != null; root = root.getCause()) 105 rootCause = root; 106 } 107 if (rootCause != null && !log.isDebugEnabled()) 108 rootCause = ((Throwable)rootCause).getMessage(); 109 } 110 111 private String getStackTrace(Throwable t) { 112 if (!log.isDebugEnabled()) 113 return ""; 114 StringWriter sw = new StringWriter(); 115 t.printStackTrace(new PrintWriter(sw)); 116 return sw.toString().replace("\r\n", "\n").replace('\r', '\n'); 117 } 118 119 public String getFaultCode() { 120 return faultCode; 121 } 122 public void setFaultCode(String faultCode) { 123 this.faultCode = faultCode; 124 } 125 126 public String getFaultDetail() { 127 return faultDetail; 128 } 129 public void setFaultDetail(String faultDetail) { 130 this.faultDetail = faultDetail; 131 } 132 133 public String getFaultString() { 134 return faultString; 135 } 136 public void setFaultString(String faultString) { 137 this.faultString = faultString; 138 } 139 140 public Map<String, Object> getExtendedData() { 141 return extendedData; 142 } 143 public void setExtendedData(Map<String, Object> extendedData) { 144 this.extendedData = extendedData; 145 } 146 147 public Object getRootCause() { 148 return rootCause; 149 } 150 public void setRootCause(Object rootCause) { 151 this.rootCause = rootCause; 152 } 153 154 public boolean loginError() { 155 return loginError; 156 } 157 158 public ErrorMessage copy(Message request) { 159 ErrorMessage copy = new ErrorMessage(request, null); 160 copy.faultCode = faultCode; 161 copy.faultDetail = faultDetail; 162 copy.faultString = faultString; 163 copy.loginError = loginError; 164 copy.rootCause = rootCause; 165 copy.extendedData = new HashMap<String, Object>(extendedData); 166 return copy; 167 } 168 169 @Override 170 public String toString() { 171 return toString(""); 172 } 173 174 @Override 175 public String toString(String indent) { 176 StringBuilder sb = new StringBuilder(512); 177 sb.append(getClass().getName()).append(" {"); 178 sb.append('\n').append(indent).append(" faultCode = ").append(faultCode); 179 sb.append('\n').append(indent).append(" faultDetail = ").append(faultDetail); 180 sb.append('\n').append(indent).append(" faultString = ").append(faultString); 181 sb.append('\n').append(indent).append(" rootCause = ").append(rootCause); 182 sb.append('\n').append(indent).append(" extendedData = ").append(extendedData); 183 super.toString(sb, indent, null); 184 sb.append('\n').append(indent).append('}'); 185 return sb.toString(); 186 } 187}