/*
* Copyright (C) 2011 asksven
*
* 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.asksven.betterbatterystats.data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
//import com.asksven.android.common.utils.DataStorage;
import com.asksven.betterbatterystats.LogSettings;
import android.content.Context;
import android.util.Log;
/**
* @author sven
* Static class as fassade to the cache of references
*/
public class ReferenceStore
{
public static final String REF_UPDATED = "com.asksven.betterbatterystats.REF_UPDATED";
/** the storage for references */
private static Map<String, Reference> m_refStore = new HashMap<String, Reference>();
/** the logging tag */
private static final String TAG = "ReferenceStore";
/**
* Return the speaking reference names for references created after refFileName (or all if refFileName is empty or null)
* @param refName
* @param ctx
* @return
*/
public static List<String> getReferenceLabels(String refFileName, Context ctx)
{
List<String> ret = new ArrayList<String>();
long time = 0;
// if a ref name was passed get the time that ref was created
if ((refFileName != null) && !refFileName.equals("") )
{
Reference ref = getReferenceByName(refFileName, ctx);
if (ref != null)
{
time = ref.m_creationTime;
}
}
ReferenceDBHelper db = ReferenceDBHelper.getInstance(ctx);
ret = db.fetchAllLabels(time);
return ret;
}
/**
* Return the internal reference names for references created after refFileName (or all if refFileName is empty or null)
* @param refName
* @param ctx
* @return
*/
public static List<String> getReferenceNames(String refFileName, Context ctx)
{
List<String> ret = new ArrayList<String>();
long time = 0;
// if a ref name was passed get the time that ref was created
if ((refFileName != null) && !refFileName.equals("") )
{
Reference ref = getReferenceByName(refFileName, ctx);
if (ref != null)
{
time = ref.m_creationTime;
}
}
ReferenceDBHelper db = ReferenceDBHelper.getInstance(ctx);
ret = db.fetchAllKeys(time);
return ret;
}
/**
* Returns a reference given a name
* @param refName the name of the reference
* @param ctx
* @return
*/
public static Reference getReferenceByName(String refName, Context ctx)
{
ReferenceDBHelper db = ReferenceDBHelper.getInstance(ctx);
// the reference names are lazily loaded too
if (m_refStore.keySet().isEmpty())
{
populateReferenceNames(ctx);
}
// we use lazy loading so we must check if there is a reference there
if (m_refStore.get(refName) == null)
{
Reference thisRef = db.fetchReferenceByKey(refName);
m_refStore.put(refName, thisRef);
if (LogSettings.DEBUG)
{
if (thisRef != null)
{
Log.i(TAG, "Retrieved reference from storage: " + thisRef.whoAmI());
}
else
{
Log.i(TAG, "Reference " + refName + " was not found");
}
}
}
else
{
if (LogSettings.DEBUG)
Log.i(TAG, "Retrieved reference from cache: " + m_refStore.get(refName).whoAmI());
}
Reference ret = m_refStore.get(refName);
return ret;
}
/**
* Adds a reference to the cache and persists it asynchronously
* @param refName the name
* @param ref
* @param ctx
*/
public static synchronized void put(String refName, final Reference ref, final Context ctx)
{
m_refStore.put(refName, ref);
if (LogSettings.DEBUG)
Log.i(TAG, "Serializing reference " + refName);
// Do this asynchronously as the data is already in the cache
Runnable runnable = new Runnable()
{
@Override
public void run()
{
serializeRef(ref, ctx);
}
};
new Thread(runnable).start();
}
/**
* Invalidates a reference in the cache storage
* @param refName the name
* @param ref
* @param ctx
*/
public static void invalidate(String refName, Context ctx)
{
m_refStore.put(refName, null);
ReferenceDBHelper db = ReferenceDBHelper.getInstance(ctx);
db.deleteReference(refName);
}
/**
* Invalidates the whole cache
* @param ref
* @param ctx
*/
public static synchronized void rebuildCache(Context ctx)
{
m_refStore.clear();
populateReferenceNames(ctx);
}
/**
* Returns whether a reference exists
* @param ref
* @param ctx
* @return
*/
public static boolean hasReferenceByName(String ref, Context ctx)
{
boolean ret = false;
Reference myCheckRef = getReferenceByName(ref, ctx);
if ((myCheckRef != null) && (myCheckRef.m_refKernelWakelocks != null))
{
ret = true;
} else
{
ret = false;
}
return ret;
}
/**
* Marshalls a reference to storage
* @param refs
* @param ctx
*/
private static void serializeRef(Reference refs, Context ctx)
{
ReferenceDBHelper db = ReferenceDBHelper.getInstance(ctx);
db.addOrUpdateReference(refs);
Log.i(TAG, "Saved ref " + refs.m_fileName);
}
/**
* Fill the cache names of all existing refernces
* @param ctx
*/
private static void populateReferenceNames(Context ctx)
{
ReferenceDBHelper db = ReferenceDBHelper.getInstance(ctx);
List<String> refs = db.fetchAllKeys(0);
if (LogSettings.DEBUG)
Log.i(TAG, "Populating cache");
for (int i=0; i < refs.size(); i++)
{
m_refStore.put(refs.get(i), null);
if (LogSettings.DEBUG)
Log.i(TAG, "Added ref " + refs.get(i));
}
if (LogSettings.DEBUG)
Log.i(TAG, "Finished populating cache");
}
/**
* Deletes (nulls) all serialized refererences
* @param ctx
*/
public static void deleteAllRefs(Context ctx)
{
if (LogSettings.DEBUG)
Log.i(TAG, "Deleting all references");
ReferenceDBHelper db = ReferenceDBHelper.getInstance(ctx);
db.deleteReferences();
m_refStore.clear();
}
public static void logReferences(Context ctx)
{
ReferenceDBHelper db = ReferenceDBHelper.getInstance(ctx);
db.logCacheContent();
}
}