net.dahanne.gallery.g2.java.client.business.G2Client.java Source code

Java tutorial

Introduction

Here is the source code for net.dahanne.gallery.g2.java.client.business.G2Client.java

Source

/**
 *  g2-java-client, a Menalto Gallery2 Java Client API
 *  URLs: https://github.com/anthonydahanne/ReGalAndroid , http://blog.dahanne.net
 *  Copyright (c) 2010 Anthony Dahanne
 *  This program 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 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
 */

package net.dahanne.gallery.g2.java.client.business;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import net.dahanne.gallery.commons.model.Album;
import net.dahanne.gallery.commons.remote.GalleryConnectionException;
import net.dahanne.gallery.commons.remote.ImpossibleToLoginException;
import net.dahanne.gallery.g2.java.client.model.G2Album;
import net.dahanne.gallery.g2.java.client.model.G2Picture;
import net.dahanne.gallery.g2.java.client.ssl.FakeSocketFactory;
import net.dahanne.gallery.g2.java.client.utils.G2ConvertUtils;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerPNames;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.cookie.Cookie;
import org.apache.http.cookie.params.CookieSpecPNames;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.impl.cookie.BrowserCompatSpec;
import org.apache.http.impl.cookie.CookieSpecBase;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * @author Anthony Dahanne
 * 
 */
public class G2Client {

    private static final String UPLOAD_FAILED = "Upload Failed";
    private static final String FAILED = "failed";
    private static final Charset UTF_8 = Charset.forName("UTF-8");
    private static final String EQUALS = "=";
    /**
     * Final static constants
     */
    private static final BasicNameValuePair LOGIN_CMD_NAME_VALUE_PAIR = new BasicNameValuePair("g2_form[cmd]",
            "login");
    private static final BasicNameValuePair FETCH_ALBUMS_CMD_NAME_VALUE_PAIR = new BasicNameValuePair(
            "g2_form[cmd]", "fetch-albums");
    private static final BasicNameValuePair FETCH_ALBUMS_IMAGES_CMD_NAME_VALUE_PAIR = new BasicNameValuePair(
            "g2_form[cmd]", "fetch-album-images");
    private static final BasicNameValuePair CREATE_ALBUM_CMD_NAME_VALUE_PAIR = new BasicNameValuePair(
            "g2_form[cmd]", "new-album");
    private static final String GR2PROTO = "#__GR2PROTO__";
    private static final String STATUS = "status";
    private static final String ITEM_NAME = "item_name";
    private static final String ALBUM_NAME = "album_name";

    private static final BasicNameValuePair G2_CONTROLLER_NAME_VALUE_PAIR = new BasicNameValuePair("g2_controller",
            "remote.GalleryRemote");
    private static final BasicNameValuePair PROTOCOL_VERSION_NAME_VALUE_PAIR = new BasicNameValuePair(
            "g2_form[protocol_version]", "2.0");
    private static final String MAIN_PHP = "main.php";
    private static final String USER_AGENT = "User-Agent";
    static final String GR_STAT_SUCCESS = "0";

    /**
     * instance variables
     */
    private String authToken;
    private final CookieSpecBase cookieSpecBase = new BrowserCompatSpec();
    private final List<Cookie> sessionCookies = new ArrayList<Cookie>();

    private final DefaultHttpClient defaultHttpClient;
    private G2Album rootAlbum;
    private final Logger logger = LoggerFactory.getLogger(G2Client.class);
    private final BasicHeader basicHeader;

    public G2Client(String userAgent) {
        this.basicHeader = new BasicHeader(USER_AGENT, userAgent);
        sessionCookies.add(new BasicClientCookie("", ""));
        // the httpclient initialization is heavy, we create one for
        // G2ConnectionUtils
        defaultHttpClient = createHttpClient();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * net.dahanne.android.regalandroid.utils.RemoteGallery#fetchImages(java
     * .lang.String, int)
     */
    public HashMap<String, String> fetchImages(String galleryUrl, int albumName) throws GalleryConnectionException {
        List<NameValuePair> nameValuePairsFetchImages = new ArrayList<NameValuePair>();
        nameValuePairsFetchImages.add(FETCH_ALBUMS_IMAGES_CMD_NAME_VALUE_PAIR);
        nameValuePairsFetchImages.add(new BasicNameValuePair("g2_form[set_albumName]", "" + albumName));

        HashMap<String, String> properties = sendCommandToGallery(galleryUrl, nameValuePairsFetchImages, null);
        return properties;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * net.dahanne.android.regalandroid.utils.RemoteGallery#fetchAlbums(java
     * .lang.String)
     */
    public HashMap<String, String> fetchAlbums(String galleryUrl) throws GalleryConnectionException {
        List<NameValuePair> nameValuePairsFetchAlbums = new ArrayList<NameValuePair>();
        nameValuePairsFetchAlbums.add(FETCH_ALBUMS_CMD_NAME_VALUE_PAIR);

        HashMap<String, String> properties = sendCommandToGallery(galleryUrl, nameValuePairsFetchAlbums, null);
        return properties;

    }

    public void loginToGallery(String galleryUrl, String user, String password) throws ImpossibleToLoginException {
        // we reset the last login
        sessionCookies.clear();
        sessionCookies.add(new BasicClientCookie("", ""));

        List<NameValuePair> sb = new ArrayList<NameValuePair>();
        sb.add(LOGIN_CMD_NAME_VALUE_PAIR);
        sb.add(new BasicNameValuePair("g2_form[uname]", "" + user));
        sb.add(new BasicNameValuePair("g2_form[password]", "" + password));
        HashMap<String, String> properties;
        try {
            properties = sendCommandToGallery(galleryUrl, sb, null);
        } catch (GalleryConnectionException e) {
            throw new ImpossibleToLoginException(e);
        }
        // auth_token retrieval, used by G2 against cross site forgery
        authToken = null;
        if (properties.get("status") != null) {
            if (properties.get("status").equals(GR_STAT_SUCCESS)) {
                authToken = properties.get("auth_token");
            } else {
                throw new ImpossibleToLoginException(properties.get("status_text"));
            }
        }
        //the login request did not return properties; issue #24 
        if (properties.isEmpty()) {
            throw new ImpossibleToLoginException(
                    "The Gallery did not return login properties; check your gallery installation and/or your settings");
        }

    }

    public InputStream getInputStreamFromUrl(String url) throws GalleryConnectionException {
        InputStream content = null;
        try {
            HttpGet httpGet = new HttpGet(url);
            httpGet.setHeader(basicHeader);
            // Setting a cookie header
            httpGet.setHeader(getCookieHeader(cookieSpecBase));
            // Execute HTTP Get Request
            HttpResponse response = defaultHttpClient.execute(httpGet);
            // System.out.println(response.getEntity().getContentLength());
            content = response.getEntity().getContent();
        } catch (Exception e) {
            throw new GalleryConnectionException(e.getMessage());
        }
        return content;
    }

    private Header getCookieHeader(CookieSpecBase cookieSpecBase) {
        List<Cookie> cookies = new ArrayList<Cookie>();
        cookies.addAll(sessionCookies);
        List<Header> cookieHeader = cookieSpecBase.formatCookies(cookies);
        return cookieHeader.get(0);
    }

    private MultipartEntity createMultiPartEntityForSendImageToGallery(int albumName, File imageFile,
            String imageName, String summary, String description) throws GalleryConnectionException {
        if (imageName == null) {
            imageName = imageFile.getName().substring(0, imageFile.getName().indexOf("."));
        }

        MultipartEntity multiPartEntity;
        try {
            multiPartEntity = new MultipartEntity();
            multiPartEntity.addPart("g2_controller", new StringBody("remote.GalleryRemote", UTF_8));
            multiPartEntity.addPart("g2_form[cmd]", new StringBody("add-item", UTF_8));
            multiPartEntity.addPart("g2_form[set_albumName]", new StringBody("" + albumName, UTF_8));
            if (authToken != null) {
                multiPartEntity.addPart("g2_authToken", new StringBody(authToken, UTF_8));
            }
            multiPartEntity.addPart("g2_form[caption]", new StringBody(imageName, UTF_8));
            multiPartEntity.addPart("g2_form[extrafield.Summary]", new StringBody(summary, UTF_8));
            multiPartEntity.addPart("g2_form[extrafield.Description]", new StringBody(description, UTF_8));
            multiPartEntity.addPart("g2_userfile", new FileBody(imageFile));
        } catch (Exception e) {
            throw new GalleryConnectionException(e.getMessage());
        }
        return multiPartEntity;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * net.dahanne.android.regalandroid.utils.RemoteGallery#createNewAlbum(java
     * .lang.String, int, java.lang.String, java.lang.String, java.lang.String)
     */
    public int createNewAlbum(String galleryUrl, int parentAlbumName, String albumName, String albumTitle,
            String albumDescription) throws GalleryConnectionException {
        int newAlbumName = 0;

        List<NameValuePair> nameValuePairsFetchImages = new ArrayList<NameValuePair>();
        nameValuePairsFetchImages.add(CREATE_ALBUM_CMD_NAME_VALUE_PAIR);
        nameValuePairsFetchImages.add(new BasicNameValuePair("g2_form[set_albumName]", "" + parentAlbumName));
        nameValuePairsFetchImages.add(new BasicNameValuePair("g2_form[newAlbumName]", albumName));
        nameValuePairsFetchImages.add(new BasicNameValuePair("g2_form[newAlbumTitle]", albumTitle));
        nameValuePairsFetchImages.add(new BasicNameValuePair("g2_form[newAlbumDesc]", albumDescription));

        HashMap<String, String> properties = sendCommandToGallery(galleryUrl, nameValuePairsFetchImages, null);
        for (Entry<String, String> entry : properties.entrySet()) {
            if (entry.getKey().equals(ALBUM_NAME)) {
                newAlbumName = new Integer(entry.getValue()).intValue();
            }
        }
        return newAlbumName;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * net.dahanne.android.regalandroid.utils.RemoteGallery#sendImageToGallery
     * (java.lang.String, int, java.io.File, java.lang.String, java.lang.String,
     * java.lang.String)
     */
    public int sendImageToGallery(String galleryUrl, int albumName, File imageFile, String imageName,
            String summary, String description) throws GalleryConnectionException {

        int imageCreatedName = 0;

        MultipartEntity multiPartEntity = createMultiPartEntityForSendImageToGallery(albumName, imageFile,
                imageName, summary, description);
        HashMap<String, String> properties = sendCommandToGallery(galleryUrl, null, multiPartEntity);

        for (Entry<String, String> entry : properties.entrySet()) {
            if (entry.getKey().equals(ITEM_NAME)) {
                imageCreatedName = new Integer(entry.getValue()).intValue();
                break;
            }
            if (entry.getValue().contains(FAILED)) {
                throw new GalleryConnectionException(UPLOAD_FAILED);
            }
        }
        return imageCreatedName;
    }

    public String getAuthToken() {
        return authToken;
    }

    public void setAuthToken(String authToken) {
        this.authToken = authToken;
    }

    public List<Cookie> getSessionCookies() {
        return sessionCookies;
    }

    private DefaultHttpClient createHttpClient() {
        // avoid instanciating
        SchemeRegistry schemeRegistry = new SchemeRegistry();
        // http scheme
        schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        // https scheme
        schemeRegistry.register(new Scheme("https", new FakeSocketFactory(), 443));

        HttpParams params = new BasicHttpParams();
        params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
        params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
        params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);

        ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);

        return new DefaultHttpClient(cm, params);
    }

    /**
     * This is the central method for each command sent to the gallery
     * 
     * @param galleryUrl
     * @param nameValuePairsForThisCommand
     * @param multiPartEntity
     *            (for sendImageToGallery only)
     * @return
     * @throws GalleryConnectionException
     */
    private HashMap<String, String> sendCommandToGallery(String galleryUrl,
            List<NameValuePair> nameValuePairsForThisCommand, HttpEntity multiPartEntity)
            throws GalleryConnectionException {
        logger.debug("galleryUrl : {} -- nameValuePairsForThisCommand : {}", galleryUrl,
                nameValuePairsForThisCommand);

        HashMap<String, String> properties = new HashMap<String, String>();
        try {

            // retrieve previous cookies
            List<Cookie> cookies = defaultHttpClient.getCookieStore().getCookies();
            // if (cookies.isEmpty()) {
            // System.out.println("None");
            // } else {
            // for (int i = 0; i < cookies.size(); i++) {
            // System.out.println("- " + cookies.get(i).toString());
            // }
            // }

            // disable expect-continue handshake (lighttpd doesn't supportit)
            defaultHttpClient.getParams().setBooleanParameter("http.protocol.expect-continue", false);

            // bug #25 : for embedded gallery, should not add main.php
            String correctedGalleryUrl = galleryUrl;
            if (!G2ConvertUtils.isEmbeddedGallery(galleryUrl)) {
                correctedGalleryUrl = galleryUrl + "/" + MAIN_PHP;
            }

            HttpPost httpPost = new HttpPost(correctedGalleryUrl);

            // if we send an image to the gallery, we pass it to the gallery
            // through multipartEntity
            httpPost.setHeader(basicHeader);
            // Setting the cookie
            httpPost.setHeader(getCookieHeader(cookieSpecBase));
            if (multiPartEntity != null) {
                ((HttpEntityEnclosingRequestBase) httpPost).setEntity(multiPartEntity);
            }
            // otherwise, UrlEncodedFormEntity is used
            else {
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                nameValuePairs.add(G2_CONTROLLER_NAME_VALUE_PAIR);
                nameValuePairs.add(new BasicNameValuePair("g2_authToken", authToken));

                nameValuePairs.add(PROTOCOL_VERSION_NAME_VALUE_PAIR);
                nameValuePairs.addAll(nameValuePairsForThisCommand);
                httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            }
            // add apache patterns for cookies
            String[] patternsArray = new String[2];
            patternsArray[0] = "EEE, dd MMM-yyyy-HH:mm:ss z";
            patternsArray[1] = "EEE, dd MMM yyyy HH:mm:ss z";
            // be extremely careful here, android httpclient needs it to be an
            // array of string, not an arraylist
            defaultHttpClient.getParams().setParameter(CookieSpecPNames.DATE_PATTERNS, patternsArray);
            HttpResponse response = null;
            // Execute HTTP Post Request and retrieve content
            try {
                response = defaultHttpClient.execute(httpPost);
            } catch (ClassCastException e) {
                // happens if using the http client not from android
                List<String> patternsList = Arrays.asList(patternsArray);
                defaultHttpClient.getParams().setParameter(CookieSpecPNames.DATE_PATTERNS, patternsList);
                response = defaultHttpClient.execute(httpPost);
            }
            int status = response.getStatusLine().getStatusCode();
            if (status >= 400 && status <= 500) {
                logger.debug("status is an error : {}", status);
                throw new GalleryConnectionException("The server returned an error : " + status);
            }

            InputStream content = response.getEntity().getContent();
            BufferedReader rd = new BufferedReader(new InputStreamReader(content), 4096);
            // do not forget the cookies
            sessionCookies.addAll(cookies);
            logger.debug("Beginning reading the response");
            String line;
            boolean gr2ProtoStringWasFound = false;
            while ((line = rd.readLine()) != null) {
                logger.debug(line);
                if (line.contains(GR2PROTO)) {
                    gr2ProtoStringWasFound = true;
                }
                if (line.contains(EQUALS) && gr2ProtoStringWasFound) {
                    String key = line.substring(0, line.indexOf(EQUALS));
                    String value = line.substring(line.indexOf(EQUALS) + 1);
                    if (key.equals(STATUS) && value.equals("403")) {
                        throw new GalleryConnectionException(
                                "The file was received, but could not be processed or added to the album.");
                    }
                    properties.put(key, value);
                }
            }
            logger.debug("Ending reading the response");
            rd.close();
        } catch (IOException e) {
            // something went wrong, let's throw the info to the UI
            throw new GalleryConnectionException(e);
        } catch (IllegalArgumentException e) {
            // the url is not correct
            throw new GalleryConnectionException(e);
        }
        return properties;
    }

    /**
     * This is where we convert the infos from the gallery to G2Picture objects
     * 
     * @param fetchImages
     * @return
     * @throws GalleryConnectionException 
     */
    public Collection<G2Picture> extractG2PicturesFromProperties(HashMap<String, String> fetchImages)
            throws GalleryConnectionException {
        Map<Integer, G2Picture> picturesMap = new HashMap<Integer, G2Picture>();
        List<Integer> tmpImageNumbers = new ArrayList<Integer>();
        int imageNumber = 0;
        for (Entry<String, String> entry : fetchImages.entrySet()) {
            if (entry.getKey().contains("image") && !entry.getKey().contains("image_count")) {
                // what is the picture id of this field ?
                imageNumber = new Integer(entry.getKey().substring(entry.getKey().lastIndexOf(".") + 1));
                G2Picture picture = null;
                // a new picture, let's create it!
                if (!tmpImageNumbers.contains(imageNumber)) {
                    picture = new G2Picture();
                    picture.setId(imageNumber);
                    picturesMap.put(imageNumber, picture);
                    tmpImageNumbers.add(imageNumber);

                }
                // a known picture, let's get it back
                else {
                    picture = picturesMap.get(imageNumber);
                }

                try {
                    if (entry.getKey().contains("image.title.")) {
                        picture.setTitle(entry.getValue());

                    } else if (entry.getKey().contains("image.thumbName.")) {
                        picture.setThumbName(entry.getValue());
                    } else if (entry.getKey().contains("image.thumb_width.")) {
                        picture.setThumbWidth(new Integer(entry.getValue()));
                    } else if (entry.getKey().contains("image.thumb_height.")) {
                        picture.setThumbHeight(new Integer(entry.getValue()));
                    } else if (entry.getKey().contains("image.resizedName.")) {
                        picture.setResizedName(entry.getValue());
                    } else if (entry.getKey().contains("image.resized_width.")) {
                        picture.setResizedWidth(new Integer(entry.getValue()));
                    } else if (entry.getKey().contains("image.resized_height.")) {
                        picture.setResizedHeight(new Integer(entry.getValue()));
                    } else if (entry.getKey().contains("image.name.")) {
                        picture.setName(entry.getValue());
                    } else if (entry.getKey().contains("image.raw_width.")) {
                        picture.setRawWidth(new Integer(entry.getValue()));
                    } else if (entry.getKey().contains("image.raw_height.")) {
                        picture.setRawHeight(new Integer(entry.getValue()));
                    } else if (entry.getKey().contains("image.raw_filesize.")) {
                        picture.setRawFilesize(new Integer(entry.getValue()));
                    } else if (entry.getKey().contains("image.caption.")) {
                        picture.setCaption(entry.getValue());
                    } else if (entry.getKey().contains("image.forceExtension.")) {
                        picture.setForceExtension(entry.getValue());
                    } else if (entry.getKey().contains("image.hidden.")) {
                        picture.setHidden(Boolean.valueOf(entry.getValue()));
                    }

                } catch (NumberFormatException nfe) {
                    throw new GalleryConnectionException(nfe);
                }
            }
        }
        return picturesMap.values();

    }

    public Map<Integer, Album> getAllAlbums(String galleryUrl) throws GalleryConnectionException {
        HashMap<String, String> albumsProperties = this.fetchAlbums(galleryUrl);

        Map<Integer, G2Album> nonSortedAlbums = extractAlbumFromProperties(albumsProperties);

        Map<Integer, Album> albumss = new HashMap<Integer, Album>();
        for (Integer key : nonSortedAlbums.keySet()) {
            albumss.put(key, G2ConvertUtils.g2AlbumToAlbum(nonSortedAlbums.get(key)));
        }

        return albumss;
    }

    /**
     * 
     * From an HashMap of albumProperties (obtained from the remote gallery),
     * returns a List of Albums
     * 
     * @param albumsProperties
     * @return List<Album>
     * @throws GalleryConnectionException 
     */
    public Map<Integer, G2Album> extractAlbumFromProperties(HashMap<String, String> albumsProperties)
            throws GalleryConnectionException {
        int albumNumber = 0;
        Map<Integer, G2Album> albumsMap = new HashMap<Integer, G2Album>();
        List<Integer> tmpAlbumNumbers = new ArrayList<Integer>();

        for (Entry<String, String> entry : albumsProperties.entrySet()) {
            if (entry.getKey().contains("album") && !entry.getKey().contains("debug")
                    && !entry.getKey().contains("album_count")) {
                // what is the album id of this field ?
                albumNumber = new Integer(entry.getKey().substring(entry.getKey().lastIndexOf(".") + 1));
                G2Album album = null;
                // a new album, let's create it!
                if (!tmpAlbumNumbers.contains(albumNumber)) {
                    album = new G2Album();
                    album.setId(albumNumber);
                    albumsMap.put(albumNumber, album);
                    tmpAlbumNumbers.add(albumNumber);

                }
                // a known album, let's get it back
                else {
                    album = albumsMap.get(albumNumber);
                }
                try {
                    if (entry.getKey().contains("album.title.")) {

                        String title = StringEscapeUtils.unescapeHtml(entry.getValue());
                        title = StringEscapeUtils.unescapeJava(title);
                        album.setTitle(title);
                    } else if (entry.getKey().contains("album.name.")) {
                        album.setName(new Integer(entry.getValue()));
                    } else if (entry.getKey().contains("album.summary.")) {
                        album.setSummary(entry.getValue());
                    } else if (entry.getKey().contains("album.parent.")) {
                        album.setParentName(new Integer(entry.getValue()));
                    } else if (entry.getKey().contains("album.info.extrafields.")) {
                        album.setExtrafields(entry.getValue());
                    }

                } catch (NumberFormatException nfe) {
                    throw new GalleryConnectionException(nfe);
                }
            }
        }

        return albumsMap;

    }

    /**
     * This method converts G2Album into Album and then organize the album hierarchy
     * 
     * @param albums
     * @return
     */
    public Album organizeAlbumsHierarchy(Map<Integer, G2Album> albums) {
        Album rootAlbum = null;
        Map<Integer, Album> albumss = new HashMap<Integer, Album>();
        for (Integer key : albums.keySet()) {
            albumss.put(key, G2ConvertUtils.g2AlbumToAlbum(albums.get(key)));
        }

        for (Album album : albumss.values()) {

            // set the root album as soon as we discover it
            if (album.getParentName() == 0) {
                rootAlbum = album;
            }

            int parentName = album.getParentName();
            // look for the parent id
            int parentId = 0;
            for (Album album2 : albumss.values()) {
                if (album2.getName() == parentName) {
                    parentId = album2.getId();
                    break;
                }
            }
            Album parent = albumss.get(parentId);
            album.setParent(parent);
            if (parent != null) {
                parent.getSubAlbums().add(album);
            }
        }

        return rootAlbum;

    }

    public void setRootAlbum(G2Album rootAlbum) {
        this.rootAlbum = rootAlbum;
    }

    public G2Album getRootAlbum() {
        return rootAlbum;
    }

}