001 /*
002 GRANITE DATA SERVICES
003 Copyright (C) 2012 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.client.messaging.messages.responses;
022
023 import java.io.IOException;
024 import java.io.ObjectInput;
025 import java.io.ObjectOutput;
026 import java.util.Map;
027
028 /**
029 * @author Franck WOLFF
030 */
031 public final class FaultMessage extends AbstractResponseMessage {
032
033 public static enum Code {
034 UNKNOWN,
035
036 SERVER_CALL_FAILED,
037
038 INVALID_CREDENTIALS,
039 AUTHENTICATION_FAILED,
040 NOT_LOGGED_IN,
041 SESSION_EXPIRED,
042 ACCESS_DENIED,
043
044 VALIDATION_FAILED,
045 OPTIMISTIC_LOCK
046 }
047
048 private Code code;
049 private String description;
050 private String details;
051 private Object cause;
052 private Map<String, Object> extended;
053
054 private String unknownCode;
055
056 public FaultMessage() {
057 }
058
059 public FaultMessage(
060 String clientId,
061 String correlationId,
062 Code code,
063 String description,
064 String details,
065 Object cause,
066 Map<String, Object> extended) {
067
068 super(clientId, correlationId);
069
070 this.code = code;
071 this.description = description;
072 this.details = details;
073 this.cause = cause;
074 this.extended = extended;
075 }
076
077 public FaultMessage(
078 String id,
079 String clientId,
080 long timestamp,
081 long timeToLive,
082 Map<String, Object> headers,
083 String correlationId,
084 Code code,
085 String description,
086 String details,
087 Object cause,
088 Map<String, Object> extended) {
089
090 super(id, clientId, timestamp, timeToLive, headers, correlationId);
091
092 this.code = code;
093 this.description = description;
094 this.details = details;
095 this.cause = cause;
096 this.extended = extended;
097 }
098
099 @Override
100 public Type getType() {
101 return Type.FAULT;
102 }
103
104 public boolean isSecurityFault() {
105 switch (code) {
106 case UNKNOWN:
107 return unknownCode != null && unknownCode.startsWith("Server.Security.");
108
109 case INVALID_CREDENTIALS:
110 case AUTHENTICATION_FAILED:
111 case NOT_LOGGED_IN:
112 case SESSION_EXPIRED:
113 case ACCESS_DENIED:
114 return true;
115
116 default:
117 return false;
118 }
119 }
120
121 @Override
122 public Object getData() {
123 return toString();
124 }
125
126 public Code getCode() {
127 return code;
128 }
129
130 public void setCode(Code code) {
131 this.code = code;
132 }
133
134 public String getDescription() {
135 return description;
136 }
137
138 public void setDescription(String description) {
139 this.description = description;
140 }
141
142 public String getDetails() {
143 return details;
144 }
145
146 public void setDetails(String details) {
147 this.details = details;
148 }
149
150 public Object getCause() {
151 return cause;
152 }
153
154 public void setCause(Object cause) {
155 this.cause = cause;
156 }
157
158 public Map<String, Object> getExtended() {
159 return extended;
160 }
161
162 public void setExtended(Map<String, Object> extended) {
163 this.extended = extended;
164 }
165
166 public String getUnknownCode() {
167 return unknownCode;
168 }
169
170 public void setUnknownCode(String unknownCode) {
171 this.unknownCode = unknownCode;
172 }
173
174 @Override
175 public FaultMessage copy() {
176 FaultMessage message = new FaultMessage();
177
178 super.copy(message);
179
180 message.code = code;
181 message.description = description;
182 message.details = details;
183 message.cause = cause;
184 message.extended = extended;
185
186 return message;
187 }
188
189 @Override
190 @SuppressWarnings("unchecked")
191 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
192 super.readExternal(in);
193
194 code = (Code)in.readObject();
195 description = in.readUTF();
196 details = in.readUTF();
197 cause = in.readObject();
198 extended = (Map<String, Object>)in.readObject();
199 }
200
201 @Override
202 public void writeExternal(ObjectOutput out) throws IOException {
203 super.writeExternal(out);
204
205 out.writeObject(code);
206 if (description != null)
207 out.writeUTF(description);
208 else
209 out.writeObject(null);
210 if (details != null)
211 out.writeUTF(details);
212 else
213 out.writeObject(null);
214 out.writeObject(cause);
215 out.writeObject(extended);
216 }
217
218 @Override
219 public StringBuilder toString(StringBuilder sb) {
220 return super.toString(sb)
221 .append("\n code=").append(code)
222 .append("\n description=").append(description)
223 .append("\n details=").append(details)
224 .append("\n cause=").append(cause)
225 .append("\n extended=").append(extended);
226 }
227 }