All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.bonita.services.impl.FileLargeDataRepository Maven / Gradle / Ivy

package org.ow2.bonita.services.impl;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.ow2.bonita.services.LargeDataRepository;
import org.ow2.bonita.util.BonitaRuntimeException;
import org.ow2.bonita.util.ExceptionManager;
import org.ow2.bonita.util.Misc;

public class FileLargeDataRepository implements LargeDataRepository {

  private static final Logger LOG = Logger.getLogger(FileLargeDataRepository.class.getName());
  private final File base;
  private static final Object CONSTRUCTOR_MUTEX = new Object();

  public void clean() {
    Misc.deleteDir(this.base);
    createRepository();
  }
  
  public boolean isEmpty() {
    return checkIsEmpty(this.base);
  }
  
  private boolean checkIsEmpty(File dir) {
    File[] files = dir.listFiles();
    if (files == null) {
      return true;
    }
    for (File file : files) {
      if (file.isFile()) {
        return false;
      } else if (!checkIsEmpty(file)) {
         return false;
      }
    }
    return true;
  }

  public FileLargeDataRepository(final String value) {
    Misc.checkArgsNotNull(value);
    String property = "property:";
    String path = value;
    if (value.startsWith(property)) {
      path = System.getProperty(value.substring(property.length()));
    }
    this.base = new File(path, "bonita-large-data-repository");
    if (LOG.isLoggable(Level.INFO)) {
      LOG.fine("Creating " + getClass().getName() + " with base: " + this.base);
    }
    createRepository();
  }

  public void deleteData(final List categories, final String key) {
    File file = getCompletePath(categories, key, false);
    if (file != null && file.exists()) {
      file.delete();
    }
  }
  
  public void deleteData(List categories) {
    File dir = getPath(categories, false);
    if (dir != null && dir.exists()) {
      Misc.deleteDir(dir);
    }
  }

  public  T getData(final Class clazz, final List categories, final String key) {
    File file = getCompletePath(categories, key, false);

    if (file == null || !file.exists()) {
      return null;
    }
    return (T) getData(clazz, file);
  }
  
  public  Map getData(final Class clazz, final List categories, final Set keys) {
    if (keys == null) {
      return Collections.emptyMap();
    }
    Map result = new HashMap();
    for (String key : keys) {
      result.put(key, getData(clazz, categories, key));
    }
    return result;
  }
  
  public  Map getData(final Class clazz, List categories) {
    File dir = getPath(categories, false);
    if (dir == null || !dir.exists()) {
      return Collections.emptyMap();
    }
    Map result = new HashMap();
    File[] files = dir.listFiles();
    for (File file : files) {
      if (file.isFile()) {
        result.put(file.getName(), (T)getData(clazz, file));
      }
    }
    return result;
  }
  
  public void storeData(final List categories, final String key, final Serializable value, final boolean overWrite) {
    File file = getCompletePath(categories, key, true);

    if (file != null && file.exists()) {
      if (!overWrite) {
        throw new BonitaRuntimeException("File: " + file + " already exists. Impossible to store it again.");
      } else {
        file.delete();
      }
    }
    
    try {
      file.createNewFile();
      Misc.write(file, Misc.serialize(value));
    } catch (IOException e) {
      throw new BonitaRuntimeException(e);
    } catch (ClassNotFoundException e) {
      throw new BonitaRuntimeException(e);
    }
  }

  
  /* PRIVATE METHODS */
  
  @SuppressWarnings("unchecked")
  private  T getData(Class clazz, File file) {
    try {
      byte[] value = Misc.getAllContentFrom(file);
      return (T) Misc.deserialize(value);
    } catch (IOException e) {
      throw new BonitaRuntimeException(e);
    } catch (ClassNotFoundException e) {
      throw new BonitaRuntimeException(e);
    }
  }
  
  private File getPath(final List categories, final boolean create) {
    List convertedCategories = convertCategories(categories);

    File dir = base;
    if (categories != null) {
      for (String category : convertedCategories) {
        File file = getFile(dir, category);
        if (file == null && create) {
          dir = new File(dir.getAbsolutePath() + File.separator + category);
          dir.mkdirs();
        } else if (file == null) {
          return null;
        } else {
          dir = file;
        }
      }
    }
    return dir;
  }
  
  private File getCompletePath(final List categories, final String key, final boolean create) {
    File dir = getPath(categories, create);
    if (dir == null) {
      return null;
    }
    return new File(dir.getAbsolutePath() + File.separator + Misc.convertToJavaIdentifier(key));
  }

  private List convertCategories(final List categories) {
    List result = new ArrayList();
    for (String category : categories) {
      result.add(Misc.convertToJavaIdentifier(category));
    }
    return result;
  }

  private File getFile(final File currentDir, final String category) {
    File[] files = currentDir.listFiles();
    if (files == null || files.length == 0) {
      return null;
    }
    for (File file : files) {
      if (file.isDirectory() && file.getName().equals(category)) {
        return file;
      }
    }
    return null;
  }
  
  private void createRepository() {
    if (LOG.isLoggable(Level.CONFIG)) {
      LOG.config("Configuring Large Data Repository: " + FileLargeDataRepository.class.getName() + " with base: " + base);
    }
    // if repo directory does not exist, create it in mutual exclusion
    // all is done in synchronized blocks, because double-checked locking pattern is broken
    synchronized (CONSTRUCTOR_MUTEX) {
      if (this.base.exists()) {
        if (!this.base.isDirectory() || !this.base.canRead() || !this.base.canWrite()) {
          String message = ExceptionManager.getInstance().getFullMessage("bai_QDAPII_20", this.base.getAbsolutePath());
          throw new BonitaRuntimeException(message);
        }
      } else if (!this.base.mkdirs()) {
        String message = ExceptionManager.getInstance().getFullMessage("bai_QDAPII_21", this.base.getAbsolutePath());
        throw new BonitaRuntimeException(message);
      }
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy