Android Open Source - Webby Flat File Data Cache






From Project

Back to project page Webby.

License

The source code is released under:

MIT License

If you think the Android project Webby listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.swampmobile.webby.util.cache;
/*  www  . j a v  a 2 s . c o  m*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.swampmobile.webby.util.logging.WebbyLog;
import com.swampmobile.webby.util.time.Duration;

import android.content.Context;
import android.net.Uri;
import android.util.Log;

/**
 * A {@link com.swampmobile.webby.util.cache.DataCache} which persists text data in flat file form.  Specifically,
 * FlatFileDataCache creates text files in the "cache directory" belonging to the
 * {@link android.content.Context} which is provided at instantiation time.
 * 
 * The naming of the files should be irrelevant given that those names are opaque
 * to the functionality of this cache, but the names of the cache files are identical
 * to the ID's of the resources they correspond to.
 * 
 * @author Matt
 *
 */
public class FlatFileDataCache implements DataCache
{
  private static final String TAG = "FlatFileDataCache";
  
  private Context context;
  private File cacheDir;
  
  private Map<Uri, Set<CacheObserver>> resourceObserverMap;
  
  public FlatFileDataCache(Context context)
  {
    this.context = context;
    this.cacheDir = context.getCacheDir();
    
    resourceObserverMap = Collections.synchronizedMap(new HashMap<Uri, Set<CacheObserver>>());
  }
  
  private String convertIdToFilename(Uri id)
  {
    //return request.getUri().hashCode() + "";
    
    char fileSep = '/'; // ... or do this portably.
    char escape = '%'; // ... or some other legal char.
    String s = id.toString();
    int len = s.length();
    StringBuilder sb = new StringBuilder(len);
    for (int i = 0; i < len; i++) {
        char ch = s.charAt(i);
        if (ch < ' ' || ch >= 0x7F || ch == fileSep  // add other illegal chars
            || (ch == '.' && i == 0) // we don't want to collide with "." or ".."!
            || ch == escape) {
            sb.append(escape);
            if (ch < 0x10) {
                sb.append('0');
            }
            sb.append(Integer.toHexString(ch));
        } else {
            sb.append(ch);
        }
    }
    
    return sb.toString();
  }
  
  private File getFileFromId(Uri id)
  {
    return new File(cacheDir.getAbsolutePath() + File.separator + convertIdToFilename(id) );
  }

  private String readStreamToString(InputStream in) throws IOException
  {
    StringBuilder sb = new StringBuilder();
    
    BufferedReader br = new BufferedReader(new InputStreamReader(in));
    String newLine;
    
    while((newLine = br.readLine()) != null)
    {
      sb.append(newLine);
    }
    
    return sb.toString();
  }
  
  @Override
  public boolean containsItem(Uri id)
  {
    File resourceFile = getFileFromId(id);
    
    if(!resourceFile.exists())
      return false;
    
    return true;
  }
  
  @Override
  public boolean isYoungerThan(Uri id, Duration age)
  {
    if(!containsItem(id))
      throw new RuntimeException("The resource you requested does not exist in the cache: " + id);
    
    File resource = getFileFromId(id);
    
    return !age.isExceeded(resource.lastModified(), System.currentTimeMillis());
  }
  
  @Override
  public String readFromCacheSync(Uri id) throws CacheReadException
  {
    WebbyLog.d(TAG, "Reading from cache with id: " + id);
    
    File resourceFile = getFileFromId(id);
    
    if(!resourceFile.exists())
      return "";
    
    try {
      String resource = readStreamToString(new FileInputStream(resourceFile));
      
      return resource;
    } catch (FileNotFoundException e) {
      return "";
    } catch (IOException e) {
      throw new CacheReadException(CacheReadException.ReadError.COULD_NOT_READ_CACHE, e.getMessage());
    }
  }

  @Override
  public void readFromCacheAsync(final Uri id, final CacheReadCallback callback)
  {
    new Thread(new Runnable() 
    {
      @Override
      public void run()
      {
        try {
          String resource = readFromCacheSync(id);
          callback.onSuccessfulRead(resource);
        } catch (CacheReadException e) {
          callback.onReadError(e);
        }
      }
    }).start();
  }

  private void writeResourceToFile(String resource, File resourceFile) throws FileNotFoundException, IOException
  {
    FileOutputStream out = new FileOutputStream(resourceFile);
    
    out.write(resource.getBytes());
    out.flush();
    out.close();
  }
  
  @Override
  public void writeToCacheSync(Uri id, String resource) throws CacheWriteException
  {
    WebbyLog.d(TAG, "Writing to cache with filename: " + id +  '\n' + resource);
    
    File resourceFile = getFileFromId(id);
    resourceFile.getParentFile().mkdirs();
    
    try {
      resourceFile.createNewFile();
      writeResourceToFile(resource, resourceFile);
    } catch (FileNotFoundException e) {
      throw new CacheWriteException(CacheWriteException.WriteError.CANNOT_ACCESS_CACHE, e.getMessage());
    } catch (IOException e) {
      throw new CacheWriteException(CacheWriteException.WriteError.ERROR_WRITING_TO_CACHE, e.getMessage());
    }
  }

  @Override
  public void writeToCacheAsync(final Uri id, final String resource, final CacheWriteCallback callback)
  {
    new Thread(new Runnable() 
    {
      @Override
      public void run()
      {
        try {
          writeToCacheSync(id, resource);
          callback.onSuccessfulWrite();
        } catch (CacheWriteException e) {
          callback.onWriteError(e);
        }
      }
    }).start();
  }

  @Override
  public void registerResourceObserver(Uri id, CacheObserver observer) {
    if(resourceObserverMap.get(id) == null)
      resourceObserverMap.put(id, Collections.synchronizedSet(new HashSet<CacheObserver>()));
    
    Set<CacheObserver> observers = resourceObserverMap.get(id);
    observers.add(observer);
  }

  @Override
  public void unregisterResourceObserver(Uri id, CacheObserver observer) {
    if(resourceObserverMap.get(id) == null)
      return;
    
    resourceObserverMap.get(id).remove(observer);
  }

  @Override
  public void unregisterResourceObserverFromAll(CacheObserver observer) {
    for(Entry<Uri, Set<CacheObserver>> entry : resourceObserverMap.entrySet())
    {
      entry.getValue().remove(observer);
    }
  }
  
  protected void notifyObserversOfChange(Uri id, String resource)
  {
    for(CacheObserver observer : resourceObserverMap.get(id))
    {
      observer.onResourceChange(id, resource);
    }
  }
  
  protected void notifyObserversOfDeletion(Uri id, String resource)
  {
    for(CacheObserver observer : resourceObserverMap.get(id))
    {
      observer.onResourceDeleted(id);
    }
  }

}




Java Source Code List

com.swampmobile.webby.WebbyManager.java
com.swampmobile.webby.Webby.java
com.swampmobile.webby.examples.activities.MainActivity.java
com.swampmobile.webby.examples.activities.WebbyActivity.java
com.swampmobile.webby.examples.activities.WebbyFragmentActivity.java
com.swampmobile.webby.examples.apis.FeedzillaApi.java
com.swampmobile.webby.examples.fragments.WebbyFragment.java
com.swampmobile.webby.examples.requests.TestWebbyRequest.java
com.swampmobile.webby.requests.WebbyRequest.java
com.swampmobile.webby.requests.WebbyResponse.java
com.swampmobile.webby.services.WebbyService.java
com.swampmobile.webby.util.cache.DataCache.java
com.swampmobile.webby.util.cache.FlatFileDataCache.java
com.swampmobile.webby.util.logging.WebbyLog.java
com.swampmobile.webby.util.time.Duration.java