com.jbirdvegas.mgerrit.helpers.Tools.java Source code

Java tutorial

Introduction

Here is the source code for com.jbirdvegas.mgerrit.helpers.Tools.java

Source

package com.jbirdvegas.mgerrit.helpers;

/*
 * Copyright (C) 2013 Android Open Kang Project (AOKP)
 *  Author: Jon Stanford (JBirdVegas), 2013
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.android.volley.Cache;
import com.android.volley.NetworkResponse;
import com.android.volley.toolbox.HttpHeaderParser;
import com.nhaarman.listviewanimations.appearance.SingleAnimationAdapter;
import com.nhaarman.listviewanimations.appearance.simple.SwingBottomInAnimationAdapter;
import com.jbirdvegas.mgerrit.Prefs;
import com.jbirdvegas.mgerrit.R;
import com.jbirdvegas.mgerrit.objects.FileInfo;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Duration;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

public class Tools {

    private static final String GERRIT_DATETIME_FORMAT = "yyyy-MM-dd hh:mm:ss.SSS";
    private static final String HUMAN_READABLE_DATETIME_FORMAT = "MMMM dd, yyyy '%s' hh:mm:ss aa";
    private static final String HUMAN_READABLE_DATE_FORMAT = "MMMM dd, yyyy";
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat
            .forPattern("yyyy-MM-dd HH:mm:ss.SSS").withLocale(Locale.US);

    public static String stackTraceToString(Throwable e) {
        StringBuilder sb = new StringBuilder(0);
        sb.append(e.getLocalizedMessage()).append("\n\n");
        for (StackTraceElement element : e.getStackTrace()) {
            sb.append("-- ").append(element.toString()).append('\n');
        }
        return sb.toString();
    }

    /**
     * Enables or disables listview animations. This simply toggles the
     *  adapter, initialising a new adapter if necessary.
     * @param enable Whether to enable animations on the listview
     * @return The outer-most adapter that was applied to the list view.
     *  a non-null instance of animAdapter if enable, defaultAdapter otherwise.
     */
    public static BaseAdapter toggleAnimations(boolean enable, ListView lv, SingleAnimationAdapter animAdapter,
            BaseAdapter defaultAdapter) {
        if (enable) {
            if (animAdapter == null) {
                animAdapter = new SwingBottomInAnimationAdapter(defaultAdapter);
                animAdapter.setAbsListView(lv);
            }
            lv.setAdapter(animAdapter);
            return animAdapter;
        } else if (defaultAdapter != null) {
            lv.setAdapter(defaultAdapter);
            return defaultAdapter;
        } else
            return null;
    }

    /**
     * Queries the active network and determine if it has Internet connectivity.
     * @param context Application or activity context
     * @return Whether we are connected to the internet, regardless of the network type
     */
    public static boolean isConnected(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    }

    /**
     * PrettyPrint the Gerrit provided timestamp
     * format into a more human readable format
     *
     * I have no clue what the ten zeros after the seconds are good for as
     * the exact same ten zeros are in all databases regardless of the stamp's
     * time or timezone... it comes from Google so we just handle oddities downstream :(
     * from "2013-06-09 19:47:40.000"
     * to Jun 09, 2013 07:47 40ms PM
     *
     * @return String representation of the date
     *         example: Jun 09, 2013 07:47 40ms PM
     */
    @SuppressWarnings("SimpleDateFormatWithoutLocale")
    public static String prettyPrintDate(Context context, String date, TimeZone serverTimeZone,
            TimeZone localTimeZone) {
        try {
            SimpleDateFormat currentDateFormat = new SimpleDateFormat(GERRIT_DATETIME_FORMAT, Locale.US);
            DateFormat humanDateFormat = new SimpleDateFormat(
                    String.format(HUMAN_READABLE_DATETIME_FORMAT, context.getString(R.string.at)),
                    Locale.getDefault());
            // location of server
            currentDateFormat.setTimeZone(serverTimeZone);
            // local location
            humanDateFormat.setTimeZone(localTimeZone);
            return humanDateFormat.format(currentDateFormat.parse(date));
        } catch (ParseException e) {
            e.printStackTrace();
            return date;
        }
    }

    public static String prettyPrintDate(Date date) {
        DateFormat humanDateFormat = new SimpleDateFormat(HUMAN_READABLE_DATE_FORMAT, Locale.getDefault());
        return humanDateFormat.format(date);
    }

    public static void colorPath(Resources r, TextView view, String statusText, boolean usingLightTheme) {
        FileInfo.Status status = FileInfo.Status.getValue(statusText);
        int green = r.getColor(R.color.text_green);
        int red = r.getColor(R.color.text_red);

        if (status == FileInfo.Status.ADDED) {
            view.setTextColor(green);
        } else if (status == FileInfo.Status.DELETED) {
            view.setTextColor(red);
        } else {
            // Need to determine from the current theme what the default color is and set it back
            if (usingLightTheme) {
                view.setTextColor(r.getColor(R.color.text_light));
            } else {
                view.setTextColor(r.getColor(R.color.text_dark));
            }
        }
    }

    /**
     * @param filePath A path to a file
     * @return The short file name from a full file path
     */
    public static String getFileName(String filePath) {
        // Remove the path from the filename
        int idx = filePath.lastIndexOf("/");
        return idx >= 0 ? filePath.substring(idx + 1) : filePath;
    }

    public static String getWebAddress(Context context, int commitNumber) {
        return String.format("%s#/c/%d/", Prefs.getCurrentGerrit(context), commitNumber);
    }

    public static Intent createShareIntent(Context context, String changeid, int changeNumber) {
        String webAddress = Tools.getWebAddress(context, changeNumber);
        return createShareIntent(context, changeid, webAddress);
    }

    public static Intent createShareIntent(Context context, String changeid, String webAddress) {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("text/plain");
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        intent.putExtra(Intent.EXTRA_SUBJECT,
                String.format(context.getResources().getString(R.string.commit_shared_from_mgerrit), changeid));
        intent.putExtra(Intent.EXTRA_TEXT, webAddress + " #mGerrit");
        return intent;
    }

    public static String getFileExtention(String filename) {
        int start = filename.lastIndexOf(".");
        return filename.substring(++start);
    }

    public static boolean isImage(String filePath) {
        String fileExtention = getFileExtention(filePath);
        return fileExtention.equals("png") || fileExtention.equals("jpg");
    }

    public static String getRevisionUrl(Context context, Integer changeNumber, Integer patchSetNumber) {
        String ps;
        if (patchSetNumber == null || patchSetNumber < 1)
            ps = "current";
        else
            ps = String.valueOf(patchSetNumber);
        return String.format("%schanges/%d/revisions/%s/patch?zip", Prefs.getCurrentGerrit(context), changeNumber,
                ps);
    }

    /**
     * Extracts a {@link com.android.volley.Cache.Entry} from a {@link com.android.volley.NetworkResponse}.
     * Cache-control headers are ignored.
     * @param response The network response to parse headers from
     * @return a cache entry for the given response, or null if the response is not cacheable.
     * @link http://stackoverflow.com/questions/16781244/android-volley-jsonobjectrequest-caching
     */
    public static Cache.Entry parseIgnoreCacheHeaders(NetworkResponse response, long cacheRefreshTime,
            long cacheExpiresTime) {
        long now = System.currentTimeMillis();

        Map<String, String> headers = response.headers;
        long serverDate = 0;
        String headerValue;

        headerValue = headers.get("Date");
        if (headerValue != null) {
            serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
        }

        final long softExpire = now + cacheRefreshTime;
        final long ttl = now + cacheExpiresTime;

        Cache.Entry entry = new Cache.Entry();
        entry.data = response.data;
        entry.etag = null; // Not worried about etag
        entry.softTtl = softExpire;
        entry.ttl = ttl;
        entry.serverDate = serverDate;
        entry.responseHeaders = headers;
        return entry;
    }

    public static DateTime parseDate(String dateStr, TimeZone serverTimeZone, TimeZone localTimeZone) {
        try {
            DateTime d = DATE_TIME_FORMATTER.withZone(DateTimeZone.forTimeZone(serverTimeZone))
                    .parseDateTime(dateStr);
            return d.withZone(DateTimeZone.forTimeZone(localTimeZone)).withMillisOfDay(0);
        } catch (IllegalArgumentException e) {
            return new DateTime(0);
        }
    }
}