com.scoreflex.ScoreflexJobQueue.java Source code

Java tutorial

Introduction

Here is the source code for com.scoreflex.ScoreflexJobQueue.java

Source

/*
 * Licensed to Scoreflex (www.scoreflex.com) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. Scoreflex licenses this
 * file to you 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.scoreflex;

import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.SharedPreferences;
import android.util.Log;

/**
 * A simple persistent job queue which saves itself on disk using SharedPreferences
 * and wraps an {@link ArrayBlockingQueue}.
 *
 *
 */
class ScoreflexJobQueue {
    private static int DEFAULT_CAPACITY = 100;

    /**
     * Queued objects.
     *
     *
     */
    public interface Job {
        public String getId();

        public JSONObject getJobDescription();

        public void repost();
    }

    private static ScoreflexJobQueue sDefaultQueue = new ScoreflexJobQueue("DefaultScoreflexJobQueue",
            DEFAULT_CAPACITY);

    /**
     * Returns the default job queue.
     * @return
     */
    public static ScoreflexJobQueue getDefaultQueue() {
        return sDefaultQueue;
    }

    private String mQueueName;
    private Object mMutex = new Object();
    private ArrayBlockingQueue<InternalJob> mQueue;

    /**
     * Creates a queue with the specified name
     * @param queueName The name of the queue, which determines the queue's storage location
     * @param capacity The maximum number of jobs the queue can hold
     */
    public ScoreflexJobQueue(String queueName, int capacity) {
        mQueueName = queueName;
        mQueue = new ArrayBlockingQueue<ScoreflexJobQueue.InternalJob>(capacity);
        restore();
    }

    /**
     * Creates and stores a job in the queue based on the provided description
     * @param jobDescription
     * @return The stored job or null if something went wrong (the queue is full for instance)
     */

    public synchronized Job postJobWithDescription(JSONObject jobDescription) {
        if (0 == mQueue.remainingCapacity())
            return null;

        String jobId = UUID.randomUUID().toString();
        InternalJob job = new InternalJob(jobId, jobDescription);
        mQueue.add(job);
        save();
        return job;
    }

    /**
     * This call blocks until the next job is available.
     * @return
     * @throws InterruptedException
     */
    public Job nextJob() throws InterruptedException {
        InternalJob job = mQueue.take();
        save();
        return job;
    }

    private String getPrefName() {
        return String.format("_scoreflex_job_queue_%s", mQueueName);
    }

    /**
     * Saves the job queue on disk.
     */
    protected void save() {
        synchronized (mMutex) {
            try {
                InternalJob jobs[] = new InternalJob[mQueue.size()];
                mQueue.toArray(jobs);
                JSONArray jsonArray = new JSONArray();
                for (int i = 0; i < jobs.length; i++) {
                    jsonArray.put(jobs[i].toJSON());
                }

                SharedPreferences prefs = Scoreflex.getSharedPreferences();
                SharedPreferences.Editor editor = prefs.edit();
                editor.putString(getPrefName(), jsonArray.toString());
                editor.commit();

            } catch (JSONException e) {
                Log.e("Scoreflex", "Could not save job queue", e);
            }

        }
    }

    /**
     * Restores the job queue from its on-disk version.
     */
    protected void restore() {
        synchronized (mMutex) {
            try {
                SharedPreferences prefs = Scoreflex.getSharedPreferences();
                String jsonString = prefs.getString(getPrefName(), "[]");
                JSONArray jsonArray = new JSONArray(jsonString);

                mQueue.clear();

                for (int i = 0; i < jsonArray.length(); i++) {
                    mQueue.add(new InternalJob(jsonArray.getJSONObject(i)));
                }
            } catch (JSONException e) {
                Log.e("Scoreflex", "Could not restore job queue");
            }
        }
    }

    private class InternalJob implements Job {
        protected String mId;
        protected JSONObject mJobDescription;

        public InternalJob(String id, JSONObject description) {
            mId = id;
            mJobDescription = description;
        }

        public InternalJob(JSONObject json) throws JSONException {
            mId = json.getString("id");
            mJobDescription = json.getJSONObject("description");
        }

        public JSONObject toJSON() throws JSONException {
            JSONObject json = new JSONObject();
            json.put("id", mId);
            json.put("description", mJobDescription);
            return json;
        }

        public String getId() {
            return mId;
        }

        public JSONObject getJobDescription() {
            return mJobDescription;
        }

        public void repost() {
            mQueue.add(this);
            save();
        }

        @Override
        public boolean equals(Object object) {

            if (!(object instanceof InternalJob))
                return false;

            InternalJob job = (InternalJob) object;

            if (null == mId && null == job.mId)
                return super.equals(object);

            if (null == job.mId)
                return false;

            return job.mId.equals(mId);

        }
    }
}