com.google.zxing.client.android.result.supplement.SupplementalInfoRetriever.java Source code

Java tutorial

Introduction

Here is the source code for com.google.zxing.client.android.result.supplement.SupplementalInfoRetriever.java

Source

/*
 * Copyright (C) 2010 ZXing authors
 *
 * 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.zxing.client.android.result.supplement;

import android.content.Context;
import android.os.Handler;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.widget.TextView;
import com.google.zxing.client.android.AndroidHttpClient;
import com.google.zxing.client.result.ISBNParsedResult;
import com.google.zxing.client.result.ParsedResult;
import com.google.zxing.client.result.ProductParsedResult;
import com.google.zxing.client.result.URIParsedResult;
import com.google.zxing.client.android.history.HistoryManager;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

public abstract class SupplementalInfoRetriever implements Callable<Void> {

    private static ExecutorService executorInstance = null;

    private static synchronized ExecutorService getExecutorService() {
        if (executorInstance == null) {
            executorInstance = Executors.newCachedThreadPool(new ThreadFactory() {
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r);
                    t.setDaemon(true);
                    return t;
                }
            });
        }
        return executorInstance;
    }

    public static void maybeInvokeRetrieval(TextView textView, ParsedResult result, Handler handler,
            HistoryManager historyManager, Context context) {

        Collection<SupplementalInfoRetriever> retrievers = new ArrayList<SupplementalInfoRetriever>(1);

        if (result instanceof URIParsedResult) {
            retrievers.add(new URIResultInfoRetriever(textView, (URIParsedResult) result, handler, historyManager,
                    context));
        } else if (result instanceof ProductParsedResult) {
            String productID = ((ProductParsedResult) result).getProductID();
            retrievers.add(new ProductResultInfoRetriever(textView, productID, handler, historyManager, context));
        } else if (result instanceof ISBNParsedResult) {
            String isbn = ((ISBNParsedResult) result).getISBN();
            retrievers.add(new ProductResultInfoRetriever(textView, isbn, handler, historyManager, context));
            retrievers.add(new BookResultInfoRetriever(textView, isbn, handler, historyManager, context));
        }

        for (SupplementalInfoRetriever retriever : retrievers) {
            ExecutorService executor = getExecutorService();
            Future<?> future = executor.submit(retriever);
            // Make sure it's interrupted after a short time though
            executor.submit(new KillerCallable(future, 10, TimeUnit.SECONDS));
        }
    }

    private final WeakReference<TextView> textViewRef;
    private final Handler handler;
    private final HistoryManager historyManager;

    SupplementalInfoRetriever(TextView textView, Handler handler, HistoryManager historyManager) {
        this.textViewRef = new WeakReference<TextView>(textView);
        this.handler = handler;
        this.historyManager = historyManager;
    }

    public final Void call() throws IOException, InterruptedException {
        retrieveSupplementalInfo();
        return null;
    }

    abstract void retrieveSupplementalInfo() throws IOException, InterruptedException;

    final void append(String itemID, String source, String[] newTexts, String linkURL) throws InterruptedException {

        final TextView textView = textViewRef.get();
        if (textView == null) {
            throw new InterruptedException();
        }

        StringBuilder newTextCombined = new StringBuilder();

        if (source != null) {
            newTextCombined.append(source).append(" : ");
        }

        int linkStart = newTextCombined.length();

        boolean first = true;
        for (String newText : newTexts) {
            if (first) {
                newTextCombined.append(newText);
                first = false;
            } else {
                newTextCombined.append(" [");
                newTextCombined.append(newText);
                newTextCombined.append(']');
            }
        }

        int linkEnd = newTextCombined.length();

        String newText = newTextCombined.toString();
        final Spannable content = new SpannableString(newText + "\n\n");
        if (linkURL != null) {
            content.setSpan(new URLSpan(linkURL), linkStart, linkEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }

        handler.post(new Runnable() {
            public void run() {
                textView.append(content);
                textView.setMovementMethod(LinkMovementMethod.getInstance());
            }
        });

        // Add the text to the history.
        historyManager.addHistoryItemDetails(itemID, newText);
    }

    protected static String downloadViaHttp(String uri) throws IOException {
        HttpUriRequest get = new HttpGet(uri);
        AndroidHttpClient client = AndroidHttpClient.newInstance(null);
        HttpResponse response = client.execute(get);
        int status = response.getStatusLine().getStatusCode();
        if (status != 200) {
            throw new IOException();
        }
        return consume(response.getEntity());
    }

    private static String consume(HttpEntity entity) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        InputStream in = null;
        try {
            in = entity.getContent();
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) > 0) {
                out.write(buffer, 0, bytesRead);
            }
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ioe) {
                    // continue
                }
            }
        }
        try {
            return new String(out.toByteArray(), "UTF-8");
        } catch (UnsupportedEncodingException uee) {
            // can't happen
            throw new IllegalStateException(uee);
        }
    }

}