mirror of
				https://github.com/owncloud/android-library.git
				synced 2025-11-04 12:28:25 +00:00 
			
		
		
		
	Added forbidden exception parser
This commit is contained in:
		
							parent
							
								
									769116a7d1
								
							
						
					
					
						commit
						21121e0189
					
				@ -0,0 +1,143 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					/* ownCloud Android Library is available under MIT license
 | 
				
			||||||
 | 
					 *   Copyright (C) 2016 ownCloud GmbH.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *   Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					 *   of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					 *   in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					 *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					 *   copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					 *   furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *   The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					 *   all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
				
			||||||
 | 
					 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
				
			||||||
 | 
					 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
				
			||||||
 | 
					 *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
				
			||||||
 | 
					 *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
				
			||||||
 | 
					 *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
				
			||||||
 | 
					 *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					 *   THE SOFTWARE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package com.owncloud.android.lib.common.operations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.util.Xml;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.xmlpull.v1.XmlPullParser;
 | 
				
			||||||
 | 
					import org.xmlpull.v1.XmlPullParserException;
 | 
				
			||||||
 | 
					import org.xmlpull.v1.XmlPullParserFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.io.InputStream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Parser for forbidden server exception
 | 
				
			||||||
 | 
					 * @author masensio
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class ForbiddenExceptionParser {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final String EXCEPTION_STRING = "OCA\\DAV\\Connector\\Sabre\\Exception\\Forbidden";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // No namespaces
 | 
				
			||||||
 | 
						private static final String ns = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Nodes for XML Parser
 | 
				
			||||||
 | 
					    private static final String NODE_ERROR = "d:error";
 | 
				
			||||||
 | 
						private static final String NODE_MESSAGE = "s:message";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
						 * Parse is as an forbidden exception
 | 
				
			||||||
 | 
						 * @param is
 | 
				
			||||||
 | 
						 * @return reason for forbidden exception
 | 
				
			||||||
 | 
						 * @throws XmlPullParserException
 | 
				
			||||||
 | 
						 * @throws IOException
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public String parseXMLResponse(InputStream is) throws XmlPullParserException,
 | 
				
			||||||
 | 
					            IOException {
 | 
				
			||||||
 | 
					        String errorMessage = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
								// XMLPullParser
 | 
				
			||||||
 | 
								XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
 | 
				
			||||||
 | 
								factory.setNamespaceAware(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								XmlPullParser parser = Xml.newPullParser();
 | 
				
			||||||
 | 
								parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
 | 
				
			||||||
 | 
								parser.setInput(is, null);
 | 
				
			||||||
 | 
								parser.nextTag();
 | 
				
			||||||
 | 
					            errorMessage = readError(parser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							} finally {
 | 
				
			||||||
 | 
								is.close();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return errorMessage;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Parse OCS node
 | 
				
			||||||
 | 
						 * @param parser
 | 
				
			||||||
 | 
						 * @return reason for forbidden exception
 | 
				
			||||||
 | 
						 * @throws XmlPullParserException
 | 
				
			||||||
 | 
						 * @throws IOException
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						private String readError (XmlPullParser parser) throws XmlPullParserException, IOException {
 | 
				
			||||||
 | 
					        String message = "";
 | 
				
			||||||
 | 
							parser.require(XmlPullParser.START_TAG,  ns , NODE_ERROR);
 | 
				
			||||||
 | 
							while (parser.next() != XmlPullParser.END_TAG) {
 | 
				
			||||||
 | 
								if (parser.getEventType() != XmlPullParser.START_TAG) {
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								String name = parser.getName();
 | 
				
			||||||
 | 
								// read NODE_MESSAGE
 | 
				
			||||||
 | 
					            if (name.equalsIgnoreCase(NODE_MESSAGE)) {
 | 
				
			||||||
 | 
					                message = readText(parser);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
									skip(parser);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					        return message;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Skip tags in parser procedure
 | 
				
			||||||
 | 
						 * @param parser
 | 
				
			||||||
 | 
						 * @throws XmlPullParserException
 | 
				
			||||||
 | 
						 * @throws IOException
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
 | 
				
			||||||
 | 
							if (parser.getEventType() != XmlPullParser.START_TAG) {
 | 
				
			||||||
 | 
								throw new IllegalStateException();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							int depth = 1;
 | 
				
			||||||
 | 
							while (depth != 0) {
 | 
				
			||||||
 | 
								switch (parser.next()) {
 | 
				
			||||||
 | 
								case XmlPullParser.END_TAG:
 | 
				
			||||||
 | 
									depth--;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case XmlPullParser.START_TAG:
 | 
				
			||||||
 | 
									depth++;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    	/**
 | 
				
			||||||
 | 
						 * Read the text from a node
 | 
				
			||||||
 | 
						 * @param parser
 | 
				
			||||||
 | 
						 * @return Text of the node
 | 
				
			||||||
 | 
						 * @throws IOException
 | 
				
			||||||
 | 
						 * @throws XmlPullParserException
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
 | 
				
			||||||
 | 
							String result = "";
 | 
				
			||||||
 | 
							if (parser.next() == XmlPullParser.TEXT) {
 | 
				
			||||||
 | 
								result = parser.getText();
 | 
				
			||||||
 | 
								parser.nextTag();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -101,8 +101,6 @@ public class InvalidCharacterExceptionParser {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		return exception.equalsIgnoreCase(EXCEPTION_STRING) ||
 | 
							return exception.equalsIgnoreCase(EXCEPTION_STRING) ||
 | 
				
			||||||
				exception.equalsIgnoreCase(EXCEPTION_UPLOAD_STRING);
 | 
									exception.equalsIgnoreCase(EXCEPTION_UPLOAD_STRING);
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
 | 
				
			|||||||
@ -63,7 +63,9 @@ import javax.net.ssl.SSLException;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class RemoteOperationResult implements Serializable {
 | 
					public class RemoteOperationResult implements Serializable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Generated - should be refreshed every time the class changes!! */
 | 
					    /**
 | 
				
			||||||
 | 
					     * Generated - should be refreshed every time the class changes!!
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private static final long serialVersionUID = 4968939884332372230L;
 | 
					    private static final long serialVersionUID = 4968939884332372230L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static final String TAG = RemoteOperationResult.class.getSimpleName();
 | 
					    private static final String TAG = RemoteOperationResult.class.getSimpleName();
 | 
				
			||||||
@ -131,10 +133,10 @@ public class RemoteOperationResult implements Serializable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Public constructor from result code.
 | 
					     * Public constructor from result code.
 | 
				
			||||||
     *
 | 
					     * <p>
 | 
				
			||||||
     * To be used when the caller takes the responsibility of interpreting the result of a {@link RemoteOperation}
 | 
					     * To be used when the caller takes the responsibility of interpreting the result of a {@link RemoteOperation}
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param code      {@link ResultCode} decided by the caller.
 | 
					     * @param code {@link ResultCode} decided by the caller.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public RemoteOperationResult(ResultCode code) {
 | 
					    public RemoteOperationResult(ResultCode code) {
 | 
				
			||||||
        mCode = code;
 | 
					        mCode = code;
 | 
				
			||||||
@ -146,12 +148,12 @@ public class RemoteOperationResult implements Serializable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Public constructor from exception.
 | 
					     * Public constructor from exception.
 | 
				
			||||||
     *
 | 
					     * <p>
 | 
				
			||||||
     * To be used when an exception prevented the end of the {@link RemoteOperation}.
 | 
					     * To be used when an exception prevented the end of the {@link RemoteOperation}.
 | 
				
			||||||
     *
 | 
					     * <p>
 | 
				
			||||||
     * Determines a {@link ResultCode} depending on the type of the exception.
 | 
					     * Determines a {@link ResultCode} depending on the type of the exception.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param e     Exception that interrupted the {@link RemoteOperation}
 | 
					     * @param e Exception that interrupted the {@link RemoteOperation}
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public RemoteOperationResult(Exception e) {
 | 
					    public RemoteOperationResult(Exception e) {
 | 
				
			||||||
        mException = e;
 | 
					        mException = e;
 | 
				
			||||||
@ -205,28 +207,28 @@ public class RemoteOperationResult implements Serializable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Public constructor from separate elements of an HTTP or DAV response.
 | 
					     * Public constructor from separate elements of an HTTP or DAV response.
 | 
				
			||||||
     *
 | 
					     * <p>
 | 
				
			||||||
     * To be used when the result needs to be interpreted from the response of an HTTP/DAV method.
 | 
					     * To be used when the result needs to be interpreted from the response of an HTTP/DAV method.
 | 
				
			||||||
     *
 | 
					     * <p>
 | 
				
			||||||
     * Determines a {@link ResultCode} from the already executed method received as a parameter. Generally,
 | 
					     * Determines a {@link ResultCode} from the already executed method received as a parameter. Generally,
 | 
				
			||||||
     * will depend on the HTTP code and HTTP response headers received. In some cases will inspect also the
 | 
					     * will depend on the HTTP code and HTTP response headers received. In some cases will inspect also the
 | 
				
			||||||
     * response body.
 | 
					     * response body.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param success       The operation was considered successful or not.
 | 
					     * @param success    The operation was considered successful or not.
 | 
				
			||||||
     * @param httpMethod    HTTP/DAV method already executed which response will be examined to interpret the
 | 
					     * @param httpMethod HTTP/DAV method already executed which response will be examined to interpret the
 | 
				
			||||||
     *                      result.
 | 
					     *                   result.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public RemoteOperationResult(boolean success, HttpMethod httpMethod) throws IOException {
 | 
					    public RemoteOperationResult(boolean success, HttpMethod httpMethod) throws IOException {
 | 
				
			||||||
        this(
 | 
					        this(
 | 
				
			||||||
            success,
 | 
					                success,
 | 
				
			||||||
            httpMethod.getStatusCode(),
 | 
					                httpMethod.getStatusCode(),
 | 
				
			||||||
            httpMethod.getStatusText(),
 | 
					                httpMethod.getStatusText(),
 | 
				
			||||||
            httpMethod.getResponseHeaders()
 | 
					                httpMethod.getResponseHeaders()
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (mHttpCode == HttpStatus.SC_BAD_REQUEST) {   // 400
 | 
					        if (mHttpCode == HttpStatus.SC_BAD_REQUEST) {   // 400
 | 
				
			||||||
            String bodyResponse = httpMethod.getResponseBodyAsString();
 | 
					            String bodyResponse = httpMethod.getResponseBodyAsString();
 | 
				
			||||||
                // do not get for other HTTP codes!; could not be available
 | 
					            // do not get for other HTTP codes!; could not be available
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (bodyResponse != null && bodyResponse.length() > 0) {
 | 
					            if (bodyResponse != null && bodyResponse.length() > 0) {
 | 
				
			||||||
                InputStream is = new ByteArrayInputStream(bodyResponse.getBytes());
 | 
					                InputStream is = new ByteArrayInputStream(bodyResponse.getBytes());
 | 
				
			||||||
@ -242,23 +244,38 @@ public class RemoteOperationResult implements Serializable {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (mHttpCode == HttpStatus.SC_FORBIDDEN) {
 | 
				
			||||||
 | 
					            String bodyResponse = httpMethod.getResponseBodyAsString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (bodyResponse != null && bodyResponse.length() > 0) {
 | 
				
			||||||
 | 
					                InputStream is = new ByteArrayInputStream(bodyResponse.getBytes());
 | 
				
			||||||
 | 
					                ForbiddenExceptionParser xmlParser = new ForbiddenExceptionParser();
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    mHttpPhrase = xmlParser.parseXMLResponse(is);
 | 
				
			||||||
 | 
					                } catch (Exception e) {
 | 
				
			||||||
 | 
					                    Log_OC.w(TAG, "Error reading exception from server: " + e.getMessage());
 | 
				
			||||||
 | 
					                    // mCode stays as set in this(success, httpCode, headers)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Public constructor from separate elements of an HTTP or DAV response.
 | 
					     * Public constructor from separate elements of an HTTP or DAV response.
 | 
				
			||||||
     *
 | 
					     * <p>
 | 
				
			||||||
     * To be used when the result needs to be interpreted from HTTP response elements that could come from
 | 
					     * To be used when the result needs to be interpreted from HTTP response elements that could come from
 | 
				
			||||||
     * different requests (WARNING: black magic, try to avoid).
 | 
					     * different requests (WARNING: black magic, try to avoid).
 | 
				
			||||||
     *
 | 
					     * <p>
 | 
				
			||||||
     * If all the fields come from the same HTTP/DAV response, {@link #RemoteOperationResult(boolean, HttpMethod)}
 | 
					     * If all the fields come from the same HTTP/DAV response, {@link #RemoteOperationResult(boolean, HttpMethod)}
 | 
				
			||||||
     * should be used instead.
 | 
					     * should be used instead.
 | 
				
			||||||
     *
 | 
					     * <p>
 | 
				
			||||||
     * Determines a {@link ResultCode} depending on the HTTP code and HTTP response headers received.
 | 
					     * Determines a {@link ResultCode} depending on the HTTP code and HTTP response headers received.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param success       The operation was considered successful or not.
 | 
					     * @param success     The operation was considered successful or not.
 | 
				
			||||||
     * @param httpCode      HTTP status code returned by an HTTP/DAV method.
 | 
					     * @param httpCode    HTTP status code returned by an HTTP/DAV method.
 | 
				
			||||||
     * @param httpPhrase    HTTP status line phrase returned by an HTTP/DAV method
 | 
					     * @param httpPhrase  HTTP status line phrase returned by an HTTP/DAV method
 | 
				
			||||||
     * @param httpHeaders   HTTP response header returned by an HTTP/DAV method
 | 
					     * @param httpHeaders HTTP response header returned by an HTTP/DAV method
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public RemoteOperationResult(boolean success, int httpCode, String httpPhrase, Header[] httpHeaders) {
 | 
					    public RemoteOperationResult(boolean success, int httpCode, String httpPhrase, Header[] httpHeaders) {
 | 
				
			||||||
        this(success, httpCode, httpPhrase);
 | 
					        this(success, httpCode, httpPhrase);
 | 
				
			||||||
@ -283,12 +300,12 @@ public class RemoteOperationResult implements Serializable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Private constructor for results built interpreting a HTTP or DAV response.
 | 
					     * Private constructor for results built interpreting a HTTP or DAV response.
 | 
				
			||||||
     *
 | 
					     * <p>
 | 
				
			||||||
     * Determines a {@link ResultCode} depending of the type of the exception.
 | 
					     * Determines a {@link ResultCode} depending of the type of the exception.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param success       Operation was successful or not.
 | 
					     * @param success    Operation was successful or not.
 | 
				
			||||||
     * @param httpCode      HTTP status code returned by the HTTP/DAV method.
 | 
					     * @param httpCode   HTTP status code returned by the HTTP/DAV method.
 | 
				
			||||||
     * @param httpPhrase    HTTP status line phrase returned by the HTTP/DAV method
 | 
					     * @param httpPhrase HTTP status line phrase returned by the HTTP/DAV method
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private RemoteOperationResult(boolean success, int httpCode, String httpPhrase) {
 | 
					    private RemoteOperationResult(boolean success, int httpCode, String httpPhrase) {
 | 
				
			||||||
        mSuccess = success;
 | 
					        mSuccess = success;
 | 
				
			||||||
@ -324,8 +341,8 @@ public class RemoteOperationResult implements Serializable {
 | 
				
			|||||||
                default:
 | 
					                default:
 | 
				
			||||||
                    mCode = ResultCode.UNHANDLED_HTTP_CODE;         // UNKNOWN ERROR
 | 
					                    mCode = ResultCode.UNHANDLED_HTTP_CODE;         // UNKNOWN ERROR
 | 
				
			||||||
                    Log_OC.d(TAG,
 | 
					                    Log_OC.d(TAG,
 | 
				
			||||||
                        "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " +
 | 
					                            "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " +
 | 
				
			||||||
                        mHttpCode + " " + mHttpPhrase
 | 
					                                    mHttpCode + " " + mHttpPhrase
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user