at.bitfire.davdroid.syncadapter.QueryServerDialogFragment.java Source code

Java tutorial

Introduction

Here is the source code for at.bitfire.davdroid.syncadapter.QueryServerDialogFragment.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Richard Hirner (bitfire web engineering).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     Richard Hirner (bitfire web engineering) - initial API and implementation
 ******************************************************************************/
package at.bitfire.davdroid.syncadapter;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.LinkedList;
import java.util.List;

import org.apache.http.HttpException;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.Toast;
import at.bitfire.davdroid.R;
import at.bitfire.davdroid.webdav.DavIncapableException;
import at.bitfire.davdroid.webdav.HttpPropfind.Mode;
import at.bitfire.davdroid.webdav.WebDavResource;

public class QueryServerDialogFragment extends DialogFragment implements LoaderCallbacks<ServerInfo> {
    private static final String TAG = "davdroid.QueryServerDialogFragment";
    public static final String EXTRA_BASE_URL = "base_uri", EXTRA_USER_NAME = "user_name",
            EXTRA_PASSWORD = "password", EXTRA_AUTH_PREEMPTIVE = "auth_preemptive";

    ProgressBar progressBar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Light);
        setCancelable(false);

        Loader<ServerInfo> loader = getLoaderManager().initLoader(0, getArguments(), this);
        if (savedInstanceState == null) // http://code.google.com/p/android/issues/detail?id=14944
            loader.forceLoad();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.query_server, container, false);
        return v;
    }

    @Override
    public Loader<ServerInfo> onCreateLoader(int id, Bundle args) {
        Log.i(TAG, "onCreateLoader");
        return new ServerInfoLoader(getActivity(), args);
    }

    @Override
    public void onLoadFinished(Loader<ServerInfo> loader, ServerInfo serverInfo) {
        if (serverInfo.getErrorMessage() != null)
            Toast.makeText(getActivity(), serverInfo.getErrorMessage(), Toast.LENGTH_LONG).show();
        else {
            SelectCollectionsFragment selectCollections = new SelectCollectionsFragment();
            Bundle arguments = new Bundle();
            arguments.putSerializable(SelectCollectionsFragment.KEY_SERVER_INFO, serverInfo);
            selectCollections.setArguments(arguments);

            getFragmentManager().beginTransaction().replace(R.id.fragment_container, selectCollections)
                    .addToBackStack(null).commitAllowingStateLoss();
        }

        getDialog().dismiss();
    }

    @Override
    public void onLoaderReset(Loader<ServerInfo> arg0) {
    }

    static class ServerInfoLoader extends AsyncTaskLoader<ServerInfo> {
        private static final String TAG = "davdroid.ServerInfoLoader";
        Bundle args;

        public ServerInfoLoader(Context context, Bundle args) {
            super(context);
            this.args = args;
        }

        @Override
        public ServerInfo loadInBackground() {
            ServerInfo serverInfo = new ServerInfo(args.getString(EXTRA_BASE_URL), args.getString(EXTRA_USER_NAME),
                    args.getString(EXTRA_PASSWORD), args.getBoolean(EXTRA_AUTH_PREEMPTIVE));

            try {
                // (1/5) detect capabilities
                WebDavResource base = new WebDavResource(new URI(serverInfo.getBaseURL()), serverInfo.getUserName(),
                        serverInfo.getPassword(), serverInfo.isAuthPreemptive(), true);
                base.options();

                serverInfo.setCardDAV(base.supportsDAV("addressbook"));
                serverInfo.setCalDAV(base.supportsDAV("calendar-access"));
                if (!base.supportsMethod("PROPFIND") || !base.supportsMethod("REPORT")
                        || (!serverInfo.isCalDAV() && !serverInfo.isCardDAV()))
                    throw new DavIncapableException(getContext().getString(R.string.neither_caldav_nor_carddav));

                // (2/5) get principal URL
                base.propfind(Mode.CURRENT_USER_PRINCIPAL);

                String principalPath = base.getCurrentUserPrincipal();
                if (principalPath != null)
                    Log.i(TAG, "Found principal path: " + principalPath);
                else
                    throw new DavIncapableException(getContext().getString(R.string.error_principal_path));

                // (3/5) get home sets
                WebDavResource principal = new WebDavResource(base, principalPath);
                principal.propfind(Mode.HOME_SETS);

                String pathAddressBooks = null;
                if (serverInfo.isCardDAV()) {
                    pathAddressBooks = principal.getAddressbookHomeSet();
                    if (pathAddressBooks != null)
                        Log.i(TAG, "Found address book home set: " + pathAddressBooks);
                    else
                        throw new DavIncapableException(
                                getContext().getString(R.string.error_home_set_address_books));
                }

                String pathCalendars = null;
                if (serverInfo.isCalDAV()) {
                    pathCalendars = principal.getCalendarHomeSet();
                    if (pathCalendars != null)
                        Log.i(TAG, "Found calendar home set: " + pathCalendars);
                    else
                        throw new DavIncapableException(getContext().getString(R.string.error_home_set_calendars));
                }

                // (4/5) get address books
                if (serverInfo.isCardDAV()) {
                    WebDavResource homeSetAddressBooks = new WebDavResource(principal, pathAddressBooks, true);
                    homeSetAddressBooks.propfind(Mode.MEMBERS_COLLECTIONS);

                    List<ServerInfo.ResourceInfo> addressBooks = new LinkedList<ServerInfo.ResourceInfo>();
                    if (homeSetAddressBooks.getMembers() != null)
                        for (WebDavResource resource : homeSetAddressBooks.getMembers())
                            if (resource.isAddressBook()) {
                                Log.i(TAG, "Found address book: " + resource.getLocation().getRawPath());
                                ServerInfo.ResourceInfo info = new ServerInfo.ResourceInfo(
                                        ServerInfo.ResourceInfo.Type.ADDRESS_BOOK,
                                        resource.getLocation().getRawPath(), resource.getDisplayName(),
                                        resource.getDescription(), resource.getColor());
                                addressBooks.add(info);
                            }

                    serverInfo.setAddressBooks(addressBooks);
                }

                // (5/5) get calendars
                if (serverInfo.isCalDAV()) {
                    WebDavResource homeSetCalendars = new WebDavResource(principal, pathCalendars, true);
                    homeSetCalendars.propfind(Mode.MEMBERS_COLLECTIONS);

                    List<ServerInfo.ResourceInfo> calendars = new LinkedList<ServerInfo.ResourceInfo>();
                    if (homeSetCalendars.getMembers() != null)
                        for (WebDavResource resource : homeSetCalendars.getMembers())
                            if (resource.isCalendar()) {
                                Log.i(TAG, "Found calendar: " + resource.getLocation().getRawPath());
                                if (resource.getSupportedComponents() != null) {
                                    // CALDAV:supported-calendar-component-set available
                                    boolean supportsEvents = false;
                                    for (String supportedComponent : resource.getSupportedComponents())
                                        if (supportedComponent.equalsIgnoreCase("VEVENT"))
                                            supportsEvents = true;
                                    if (!supportsEvents) // ignore collections without VEVENT support
                                        continue;
                                }
                                ServerInfo.ResourceInfo info = new ServerInfo.ResourceInfo(
                                        ServerInfo.ResourceInfo.Type.CALENDAR, resource.getLocation().getRawPath(),
                                        resource.getDisplayName(), resource.getDescription(), resource.getColor());
                                info.setTimezone(resource.getTimezone());
                                calendars.add(info);
                            }

                    serverInfo.setCalendars(calendars);
                }

            } catch (URISyntaxException e) {
                serverInfo.setErrorMessage(getContext().getString(R.string.exception_uri_syntax, e.getMessage()));
            } catch (IOException e) {
                serverInfo.setErrorMessage(getContext().getString(R.string.exception_io, e.getLocalizedMessage()));
            } catch (DavIncapableException e) {
                serverInfo.setErrorMessage(
                        getContext().getString(R.string.exception_incapable_resource, e.getLocalizedMessage()));
            } catch (HttpException e) {
                serverInfo
                        .setErrorMessage(getContext().getString(R.string.exception_http, e.getLocalizedMessage()));
            }

            return serverInfo;
        }
    }
}