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    }