001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *  
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *  
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License. 
018 *  
019 */
020package org.apache.directory.shared.dsmlv2.reponse;
021
022
023import org.apache.directory.shared.dsmlv2.DsmlDecorator;
024import org.apache.directory.shared.ldap.codec.api.LdapApiService;
025import org.apache.directory.shared.ldap.model.message.AbstractResponse;
026import org.apache.directory.shared.ldap.model.message.MessageTypeEnum;
027import org.apache.directory.shared.ldap.model.message.Response;
028import org.dom4j.Element;
029import org.dom4j.tree.DefaultElement;
030
031
032/**
033 * Class representing Error Response.
034 * <br/>
035 * An Error Response has a requestID, a message, and a type which can be :
036 * <ul> 
037 *     <li>NOT_ATTEMPTED,</li>
038 *     <li>COULD_NOT_CONNECT,</li>
039 *     <li>CONNECTION_CLOSED,</li>
040 *     <li>MALFORMED_REQUEST,</li>
041 *     <li>GATEWAY_INTERNAL_ERROR,</li>
042 *     <li>AUTHENTICATION_FAILED,</li>
043 *     <li>UNRESOLVABLE_URI,</li>
044 *     <li>OTHER</li>
045 * </ul>
046 * 
047 * @TODO review this class - maybe it should not be decorated and if it is 
048 * it should extend AbstractResultResponseDsml - by Alex
049 * 
050 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
051 */
052public class ErrorResponse extends AbstractResponse implements Response, DsmlDecorator<Response>
053{
054    private static final String ERROR_RESPONSE_TAG = "errorResponse";
055
056
057    /**
058     * This enum represents the different types of error response
059     *
060     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
061     */
062    public enum ErrorResponseType
063    {
064        /** Not attempted error response type. */
065        NOT_ATTEMPTED,
066        /** Could not connect error response type. */
067        COULD_NOT_CONNECT,
068        /**  error response type. */
069        CONNECTION_CLOSED,
070        /** Malformed request error response type. */
071        MALFORMED_REQUEST,
072        /** Gateway internal error error response type. */
073        GATEWAY_INTERNAL_ERROR,
074        /** Authentication failed error response type. */
075        AUTHENTICATION_FAILED,
076        /** Unresolveable URI error response type. */
077        UNRESOLVABLE_URI,
078        /** Other error response type. */
079        OTHER
080    }
081
082    /** The type of error response */
083    private ErrorResponseType errorType;
084
085    /** The associated message */
086    private String message;
087
088    /** The request ID */
089    private int requestID;
090
091
092    /**
093     * Creates a new instance of ErrorResponse.
094     *
095     * @param id the response eliciting this Request
096     * @param type the message type of the response
097     */
098    public ErrorResponse( int id, MessageTypeEnum type )
099    {
100        super( id, type );
101    }
102
103
104    /**
105     * Creates a new instance of ErrorResponse.
106     *
107     * @param requestID
108     *      the requestID of the response
109     * @param type 
110     *      the type of the response
111     * @param message
112     *      the associated message
113     */
114    public ErrorResponse( int requestID, ErrorResponseType type, String message )
115    {
116        super( requestID, null );
117        this.requestID = requestID;
118        this.errorType = type;
119        this.message = message;
120    }
121
122
123    /**
124     * {@inheritDoc}
125     */
126    public Element toDsml( Element root )
127    {
128        Element element = null;
129
130        if ( root != null )
131        {
132            element = root.addElement( ERROR_RESPONSE_TAG );
133        }
134        else
135        {
136            element = new DefaultElement( ERROR_RESPONSE_TAG );
137        }
138        
139        // RequestID
140        if ( requestID != 0 )
141        {
142            element.addAttribute( "requestID", "" + requestID );
143        }
144
145        // Type
146        element.addAttribute( "type", getTypeDescr( errorType ) );
147
148        // TODO Add Detail
149
150        if ( ( message != null ) && ( !"".equals( message ) ) )
151        {
152            Element messageElement = element.addElement( "message" );
153            messageElement.addText( message );
154        }
155
156        return element;
157    }
158
159
160    /**
161     * Returns the String associated to the error response type
162     * 
163     * @param type 
164     *      the error response type
165     * @return 
166     *      the corresponding String
167     */
168    public String getTypeDescr( ErrorResponseType type )
169    {
170        if ( type.equals( ErrorResponseType.NOT_ATTEMPTED ) )
171        {
172            return "notAttempted";
173        }
174        else if ( type.equals( ErrorResponseType.COULD_NOT_CONNECT ) )
175        {
176            return "couldNotConnect";
177        }
178        else if ( type.equals( ErrorResponseType.CONNECTION_CLOSED ) )
179        {
180            return "connectionClosed";
181        }
182        else if ( type.equals( ErrorResponseType.MALFORMED_REQUEST ) )
183        {
184            return "malformedRequest";
185        }
186        else if ( type.equals( ErrorResponseType.GATEWAY_INTERNAL_ERROR ) )
187        {
188            return "gatewayInternalError";
189        }
190        else if ( type.equals( ErrorResponseType.AUTHENTICATION_FAILED ) )
191        {
192            return "authenticationFailed";
193        }
194        else if ( type.equals( ErrorResponseType.UNRESOLVABLE_URI ) )
195        {
196            return "unresolvableURI";
197        }
198        else if ( type.equals( ErrorResponseType.OTHER ) )
199        {
200            return "other";
201        }
202        else
203        {
204            return "unknown";
205        }
206    }
207
208
209    /**
210     * Gets the message
211     *
212     * @return
213     *      the message
214     */
215    public String getMessage()
216    {
217        return message;
218    }
219
220
221    /**
222     * Sets the message
223     *
224     * @param message
225     *      the message to set
226     */
227    public void setMessage( String message )
228    {
229        this.message = message;
230    }
231
232
233    /**
234     * Gets the request ID
235     *
236     * @return
237     *      the request ID
238     */
239    public int getRequestID()
240    {
241        return requestID;
242    }
243
244
245    /**
246     * Sets the request ID
247     *
248     * @param requestID
249     *      the request ID to set
250     */
251    public void setRequestID( int requestID )
252    {
253        this.requestID = requestID;
254    }
255
256
257    /**
258     * Gets the type of error response
259     *
260     * @return the type of error response
261     */
262    public ErrorResponseType getErrorType()
263    {
264        return errorType;
265    }
266
267
268    /**
269     * Sets the type of error response
270     *
271     * @param errorType the type of error response to set
272     */
273    public void setErrorType( ErrorResponseType errorType )
274    {
275        this.errorType = errorType;
276    }
277
278
279    public LdapApiService getCodecService()
280    {
281        throw new IllegalArgumentException( "This should not be a decorator " +
282                        "but seems it was made into one. We need to do something about" +
283                        "this if this exception is being raise." );
284    }
285
286
287    public Response getDecorated()
288    {
289        return this;
290    }
291}