com.bdaum.juploadr.uploadapi.locrrest.LocrMethod.java Source code

Java tutorial

Introduction

Here is the source code for com.bdaum.juploadr.uploadapi.locrrest.LocrMethod.java

Source

/*
 * This file is part of the ZoRa project: http://www.photozora.org.
 *
 * ZoRa is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * ZoRa is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ZoRa; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * (c) 2009 Berthold Daum  
 */
package com.bdaum.juploadr.uploadapi.locrrest;

import java.io.IOException;
import java.io.StringReader;
import java.util.Map;
import java.util.SortedMap;

import org.apache.commons.codec.EncoderException;
import org.apache.commons.codec.net.URLCodec;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.scohen.juploadr.Messages;
import org.scohen.juploadr.app.StringSigner;
import org.scohen.juploadr.app.photoset.PhotosetNotFoundException;
import org.scohen.juploadr.upload.FiletypeNotRecognizedException;
import org.scohen.juploadr.upload.HttpClientFactory;
import org.scohen.juploadr.uploadapi.Action;
import org.scohen.juploadr.uploadapi.AuthException;
import org.scohen.juploadr.uploadapi.CommunicationException;
import org.scohen.juploadr.uploadapi.ProtocolException;
import org.scohen.juploadr.uploadapi.Session;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

import com.bdaum.juploadr.uploadapi.locrrest.authentification.GetApiSignature;
import com.bdaum.zoom.net.communities.InvalidAuthTokenException;
import com.bdaum.zoom.net.communities.PhotoNotFoundException;
import com.bdaum.zoom.net.communities.ServiceUnavailableException;
import com.bdaum.zoom.net.communities.UserNotFoundException;
import com.bdaum.zoom.net.core.internal.Activator;

public abstract class LocrMethod implements Action {
    protected static final String URL = "http://de.locr.com/api/"; //$NON-NLS-1$
    protected HttpClient client;
    private URLCodec codec = new URLCodec();
    protected DefaultLocrHandler handler;
    private final Session session;

    // private static Log log = LogFactory.getLog(FlickrMethod.class);

    public LocrMethod(Session session) {
        this.session = session;
        client = HttpClientFactory.getHttpClient(session.getAccount());
    }

    public abstract DefaultLocrHandler getResponseHandler();

    public boolean execute() throws ProtocolException, CommunicationException {

        HttpMethodBase method = getMethod();

        boolean rv = false;
        try {
            int response = client.executeMethod(method);
            if (HttpStatus.SC_OK == response) {
                rv = parseResponse(method.getResponseBodyAsString());
                if (!rv) {
                    throw defaultExceptionFor(handler.getErrorCode());
                }
            } else {
                throw new CommunicationException(Messages.getString("juploadr.ui.error.bad.http.response", //$NON-NLS-1$
                        Activator.getStatusText(response)));
            }
        } catch (InvalidAuthTokenException iat) {
            ((RestLocrApi) session.getApi()).reauthAccount(session);
        } catch (HttpException e) {
            throw new CommunicationException(e.getMessage(), e);
        } catch (IOException e) {
            throw new CommunicationException(e.getMessage(), e);
        } finally {
            method.releaseConnection();
        }
        return rv;

    }

    public int getErrorCode() {
        return handler.getErrorCode();
    }

    private ProtocolException defaultExceptionFor(int errorCode) {
        ProtocolException ex = buildProtocolException(errorCode);
        if (ex == null) {
            // we still don't have an exception, this is very odd.
            ex = new ProtocolException();
        }
        return ex;
    }

    protected ProtocolException buildProtocolException(int errorCode) {
        switch (errorCode) {

        case 100:
            return new ServiceUnavailableException();
        case 101:
            return new AccessDeniedException();
        case 200:
            return new InvalidValueException();
        case 201:
            return new MissingParameterException();
        case 202:
            return new MissingValueException();
        case 203:
            return new ValueNotaNumberException();
        case 204:
            return new ValueOutOfRangeException();
        case 205:
            return new UserNotFoundException();
        case 206:
            return new InvalidAuthTokenException();
        case 207:
            return new PermissionDeniedException();
        case 208:
            return new ReadOnlyException();
        case 209:
            return new FiletypeNotRecognizedException();
        case 210:
            return new UploadLimitException();
        case 211:
            return new PhotoAlreadyExistsException();
        case 212:
            return new PhotoNotFoundException();
        case 213:
            return new AlbumAlreadyExistsException();
        case 214:
            return new NoMoreAlbumsAllowedException();
        case 215:
            return new PhotosetNotFoundException();
        default:
            return null;
        }
    }

    /**
     * @param responseBodyAsString
     * @return
     * @throws AuthException
     */
    public boolean parseResponse(String response) throws ProtocolException {
        try {
            XMLReader reader = XMLReaderFactory.createXMLReader();
            handler = getResponseHandler();
            reader.setContentHandler(handler);
            reader.parse(new InputSource(new StringReader(response)));
            if (!handler.isSuccessful()) {
                throw defaultExceptionFor(handler.getErrorCode());
            }
            return handler.isSuccessful();
        } catch (SAXException e) {
            throw new AuthException(Messages.getString("juploadr.ui.error.response.unreadable.noreason"), //$NON-NLS-1$
                    e);
        } catch (IOException e) {
            // this can't happen
        }
        return false;
    }

    public String getQueryString(boolean signed) {
        StringBuffer queryString = new StringBuffer();
        Map<String, String> params = getParams();
        if (isAuthorized()) {
            authorize(params);
        }
        String method = params.remove("method"); //$NON-NLS-1$
        if (method != null)
            queryString.append(method);
        for (Map.Entry<String, String> entry : params.entrySet()) {
            appendNVP(queryString, entry.getKey(), entry.getValue());
        }
        return queryString.toString();
    }

    private void authorize(Map<String, String> params) {
        if (isAuthorized()) {
            String signature = getApiSignature();
            String password = session.getAccount().getPasswordHash();
            StringBuffer sb = new StringBuffer();
            sb.append(password).append(signature);
            String auth_token = StringSigner.md5(sb.toString());
            // now iterate through all the params, and append them
            params.put("auth_user_name", session.getAccount().getName()); //$NON-NLS-1$
            params.put("api_signature", signature); //$NON-NLS-1$
            params.put("auth_token", auth_token); //$NON-NLS-1$
        }
    }

    protected String getApiSignature() {
        GetApiSignature getApiSignature = new GetApiSignature(session);
        try {
            getApiSignature.execute();
        } catch (ProtocolException e) {
            session.getApi().handleCommunicationError(e);
        } catch (CommunicationException e) {
            session.getApi().handleCommunicationError(e);
        }
        return getApiSignature.getApiSignature();
    }

    private void appendNVP(StringBuffer url, String name, String value) {
        if (url.length() == 0) {
            url.append("?"); //$NON-NLS-1$
        }
        char lastChar = url.charAt(url.length() - 1);
        if (lastChar != '&' && lastChar != '?') {
            url.append("&"); //$NON-NLS-1$
        }
        url.append(name);
        url.append("="); //$NON-NLS-1$
        url.append(encode(value));
    }

    protected String encode(String toEnc) {
        try {
            return codec.encode(toEnc);
        } catch (EncoderException e) {
            // do nothing
        }
        return null;
    }

    public abstract SortedMap<String, String> getParams();

    public abstract boolean isAuthorized();

    public HttpMethodBase getMethod() {
        StringBuffer query = new StringBuffer(URL);
        query.append(getQueryString(true));
        // log.info(query.toString());
        return new GetMethod(query.toString());
    }

    public Session getSession() {
        return session;
    }
}