com.google.android.apps.forscience.whistlepunk.LicenseActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.google.android.apps.forscience.whistlepunk.LicenseActivity.java

Source

/*
 *  Copyright 2016 Google Inc. All Rights Reserved.
 *
 *  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.
 */

package com.google.android.apps.forscience.whistlepunk;

import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.ListFragment;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

/**
 * Displays list of code modules.
 */
public class LicenseActivity extends AppCompatActivity {

    private static final String TAG = "LicenseActivity";
    // Tag and attribute names for parsing license file.
    private static final String TAG_LICENSE = "license";
    private static final String ATTRIB_KEY = "key";
    private static final String TAG_TITLE = "title";
    private static final String TAG_RESOURCE = "resource";
    private static final String TAG_HEADER = "copyrightHeader";

    /**
     * Placeholder text in a license html file which can be replaced. This allows several libraries
     * to share Apache 2, for example.
     */
    public static final String COPYRIGHT_HEADER_PLACEHOLDER = "[_INSERT_COPYRIGHT_HERE_]";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_licenses);

        if (getFragmentManager().findFragmentByTag("list") == null) {
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.add(R.id.container, new LicenseListFragment(), "list");
            ft.commit();
        }

        final ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            if (getFragmentManager().popBackStackImmediate()) {
                return true;
            } else {
                Intent intent = SettingsActivity.getLaunchIntent(this, getString(R.string.action_about),
                        SettingsActivity.TYPE_ABOUT);
                NavUtils.navigateUpTo(this, intent);
                return true;
            }
        }
        return super.onOptionsItemSelected(item);
    }

    public static class LicenseListFragment extends ListFragment {

        private ArrayAdapter<License> mAdapter;

        public LicenseListFragment() {
        }

        @Override
        public void onResume() {
            super.onResume();

            setEmptyText(getActivity().getString(R.string.licenses_empty));
            getActivity().setTitle(R.string.settings_open_source_title);
            new LoadLicenseTask().execute();
        }

        private List<License> getLicenses() {
            DocumentBuilder builder = null;
            List<License> licenses = new ArrayList<>();
            try {
                builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                Document licenseDoc = builder.parse(getResources().openRawResource(R.raw.license_list));
                NodeList licenseNodes = licenseDoc.getElementsByTagName(TAG_LICENSE);
                final int size = licenseNodes.getLength();
                for (int index = 0; index < size; index++) {
                    Node licenseNode = licenseNodes.item(index);
                    License license = new License();
                    license.key = licenseNode.getAttributes().getNamedItem(ATTRIB_KEY).getNodeValue();
                    Node childNode = licenseNode.getFirstChild();
                    while (childNode != null) {
                        String nodeName = childNode.getNodeName();
                        String nodeValue = childNode.getFirstChild() != null
                                ? childNode.getFirstChild().getNodeValue()
                                : null;
                        if (TAG_TITLE.equals(nodeName)) {
                            license.title = nodeValue;
                        } else if (TAG_RESOURCE.equals(nodeName)) {
                            license.resource = nodeValue;
                        } else if (TAG_HEADER.equals(nodeName)) {
                            license.copyrightHeader = nodeValue;
                        }
                        childNode = childNode.getNextSibling();
                    }
                    if (license.isValid()) {
                        licenses.add(license);
                    } else {
                        Log.e(TAG, "Not adding invalid license: " + license);
                    }
                }
            } catch (ParserConfigurationException | SAXException | IOException e) {
                Log.e(TAG, "Could not parse license file.", e);
            }
            Collections.sort(licenses, LICENSE_COMPARATOR);
            return licenses;
        }

        class LoadLicenseTask extends AsyncTask<Void, Void, List<License>> {

            @Override
            protected List<License> doInBackground(Void... params) {
                return getLicenses();
            }

            @Override
            protected void onPostExecute(List<License> licenses) {
                mAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1,
                        android.R.id.text1, licenses);
                setListAdapter(mAdapter);
            }
        }

        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            ((LicenseActivity) getActivity()).showLicense(mAdapter.getItem(position));
        }
    }

    private void showLicense(License license) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.add(R.id.container, LicenseFragment.newInstance(license), "license");
        ft.addToBackStack(license.key);
        ft.commit();
    }

    public static class LicenseFragment extends Fragment {
        private String mTitleToRestore = null;

        private WebView mWebView;

        public LicenseFragment() {
        }

        public static LicenseFragment newInstance(License license) {
            Bundle args = new Bundle();
            args.putString(TAG_TITLE, license.title);
            args.putString(TAG_HEADER, license.copyrightHeader);
            args.putString(TAG_RESOURCE, license.resource);
            LicenseFragment fragment = new LicenseFragment();
            fragment.setArguments(args);
            return fragment;
        }

        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.licenses, container, false);
            mWebView = (WebView) view.findViewById(R.id.license_web_view);
            return view;
        }

        @Override
        public void onStart() {
            super.onStart();
            new LoadStaticHtmlTask(new LoadStaticHtmlTask.StaticHtmlLoadListener() {
                @Override
                public void onDataLoaded(String data) {
                    String copyrightHeader = getArguments().getString(TAG_HEADER);
                    if (!TextUtils.isEmpty(copyrightHeader)) {
                        data = data.replace(COPYRIGHT_HEADER_PLACEHOLDER, copyrightHeader);
                    }
                    mWebView.loadData(data, "text/html", "UTF-8");
                }
            }, getResources(), getResources().getIdentifier(getArguments().getString(TAG_RESOURCE), "raw",
                    getActivity().getPackageName())).execute();
        }

        @Override
        public void onResume() {
            super.onResume();
            if (mTitleToRestore == null) {
                mTitleToRestore = getActivity().getTitle().toString();
            }
            getActivity().setTitle(getArguments().getString(TAG_TITLE));
        }

        @Override
        public void onPause() {
            if (mTitleToRestore != null) {
                getActivity().setTitle(mTitleToRestore);
                mTitleToRestore = null;
            }
            super.onPause();
        }
    }

    /**
     * Represents a license file to show.
     */
    static class License {

        /**
         * Key, not user shown.
         */
        String key;

        /**
         * User readable title. Doesn't need to be translated since these are names.
         */
        String title;

        /**
         * Name of a raw resource file with the license.
         */
        String resource;

        /**
         * Optional copyright header to insert into license file.
         */
        String copyrightHeader;

        @Override
        public String toString() {
            return title;
        }

        public boolean isValid() {
            return !TextUtils.isEmpty(key) && !TextUtils.isEmpty(title) && !TextUtils.isEmpty(resource);
        }
    }

    /**
     * Sorts license objects by title.
     */
    static final Comparator<License> LICENSE_COMPARATOR = new Comparator<License>() {

        @Override
        public int compare(License lhs, License rhs) {
            return lhs.toString().compareTo(rhs.toString());
        }
    };
}