Package com.kolich.havalo.io.stores

Source Code of com.kolich.havalo.io.stores.ObjectStore

/**
* Copyright (c) 2013 Mark S. Kolich
* http://mark.koli.ch
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

package com.kolich.havalo.io.stores;

import com.kolich.havalo.entities.types.DiskObject;
import com.kolich.havalo.exceptions.objects.ObjectLoadException;

import java.io.File;
import java.io.IOException;

import static com.kolich.common.util.crypt.Base32Utils.encodeBase32;
import static org.apache.commons.io.FileUtils.forceMkdir;

public abstract class ObjectStore {
 
  /**
   * The max filename length of the ext3 filesystem is 255-bytes. The
   * max filename length of ext4 is 256-bytes.  NTFS claims that their
   * max filename length is also 255-bytes.  The filename length is the
   * max length of any component along the path, not the entire path
   * itself.
   */
  public static final int DEFAULT_MAX_FILENAME_LENGTH = 255;
   
  /**
   * The max length of a cache filename before it's split up
   * into multiple directories.  Default is 255 to work on most
   * file systems.
   */
  protected final int maxFileNameLength_;
 
  protected final File storeDir_;
 
  public ObjectStore(final File storeDir,
                       final int maxFileNameLength) {
    storeDir_ = storeDir;
    maxFileNameLength_ = maxFileNameLength;
  }
 
  public ObjectStore(final File storeDir) {
    this(storeDir, DEFAULT_MAX_FILENAME_LENGTH);
  }
 
  /**
   * Given an index of arbitrary length, returns a {@link File} object
   * that points to a file system safe location on disk that won't blow
   * up because a filename is too long.  This may mean that the filename
   * is split up into multiple directories if necessary.  If the caller
   * wishes to have this method create the required parent directories
   * for the cached entity, set makeParents to true.
   */
  protected final DiskObject getCanonicalObject(final File parent,
                                                  final String index,
                                                  final int maxFileNameLength,
                                                  final boolean makeParentDirs) {
    File f = null;
    try {
      // Get the encoded file name (with extension if one exists);
      // this may be longer than the file system supports, but that's OK
      // because we will split this up accordingly.
      //final String fileName = encode(index, UTF_8);
      final String fileName = encodeBase32(index);
      // If the encoded filename is longer than the max filename length
      // this bean supports, split up the index into a series of directories.
      if(fileName.length() > maxFileNameLength) {
        // Get a series of tokens that represent this cache file in
        // a split set of directories where each element in the path is
        // no longer than the maximum allowed by the file system.
        File root = parent;
        int beginIndex = 0;
        while(beginIndex <= fileName.length()) {
          int endIndex = ((beginIndex + maxFileNameLength) > fileName.length()) ?
            fileName.length() : beginIndex + maxFileNameLength;
          root = new File(root, fileName.substring(beginIndex, endIndex));
          beginIndex += maxFileNameLength;
        }
        f = root;
      } else {
        f = new File(parent, fileName);
      }
      // If the new file does not exist, it's a directory, and we
      // were asked to create it -- then create the parent directories.
      if(makeParentDirs) {       
        try {
          final File parentDir = f.getParentFile();
          forceMkdir(parentDir);
        } catch (Exception e) {
          throw new IOException("Could not create required parent " +
            "directories for object (file=" + f.getAbsolutePath() +
              ")", e);
        }
      }
      return new DiskObject(index, f, new File(parent, fileName));
    } catch (Exception e) {
      throw new ObjectLoadException("Failed to build canonical disk " +
        "object for index/key: " + index, e);
    }
  }
   
  protected final DiskObject getCanonicalObject(final File parent,
                                                  final String index,
                                                  final boolean makeParentDirs) {
    return getCanonicalObject(parent, index, maxFileNameLength_,
      makeParentDirs);
  }
 
  /*
  protected ObjectList listFiles(final File directory,
    final boolean recursive) {
    // A new index.
    final ObjectList index = new ObjectList();
    try {
      // The cache directory path compiled as a valid regular expression.
      final Pattern cacheDirPattern = compile(quote(
        directory.getAbsolutePath()));
      final Collection<File> files = FileUtils.listFiles(directory,
        null, recursive);
      final Iterator<File> it = files.iterator();
      while(it.hasNext()) {
        final File cache = it.next();
        try {
          final StringBuilder sb = new StringBuilder();
          // Strip the cache directory from the front of the file-name.
          final String path = cacheDirPattern.matcher(
            cache.getAbsolutePath()).replaceAll("");
          // For each token in the path, separated by the file separator
          // extract it, then append to the StringBuilder.
          for(final String element : path.split(quote(FILE_SEPARATOR))) {
            sb.append(element);
          }
          // At this point, we have a full path.  Decode the entire
          // String at once, to avoid the case where the file name
          // may have been split right in the middle of an escape
          // pattern (e.g., "%3/B" can only be decoded as "%3B" so we
          // have to decode the entire path string at once, instead of
          // each element one at a time).
          index.addObject(new DiskObject(decodeBase32(sb.toString()),
            cache));
        } catch (Exception e) {
          // Ignore problems with individual files, and move on.
        }
      }
    } catch (Exception e) {
      throw new RepositoryListObjectsException("Failed to build object " +
        "listing of directory: " + ((directory != null) ?
          directory.getAbsolutePath() : "null"), e);
    }
    return index;
  }
   
  protected ObjectList listFiles(final File directory) {
    return listFiles(directory, true);
  }
  */
 
  protected File getStoreDir() {
    return storeDir_;
  }
 
}
TOP

Related Classes of com.kolich.havalo.io.stores.ObjectStore

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.