Package gov.lanl.adore.djatoka.openurl

Source Code of gov.lanl.adore.djatoka.openurl.SimpleListResolver

/*
* Copyright (c) 2008  Los Alamos National Security, LLC.
*
* Los Alamos National Laboratory
* Research Library
* Digital Library Research & Prototyping Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/

package gov.lanl.adore.djatoka.openurl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import gov.lanl.adore.djatoka.util.ImageRecord;
import info.openurl.oom.entities.Referent;

/**
* Default IReferentResolver implementation that uses a tab delimited file to
* define the association between rft_id and file path.  The imgIndexFile should
* be defined in the OpenURLJP2KService.properties file as SimpleListResolver.imgIndexFile.
*
* Property: SimpleListResolver.imgIndexFile=imgIndex.txt
* Format: rft_id\tfile_path
*
* @author Ryan Chute
*
*/
public class SimpleListResolver implements IReferentResolver {
  static Logger logger = Logger.getLogger(SimpleListResolver.class);
  private static final String PROP_IMGS_INDEX = "SimpleListResolver.imgIndexFile";
  private static final String PROP_REMOTE_CACHE = "SimpleListResolver.maxRemoteCacheSize";
  private static final int DEFAULT_REMOTE_CACHE_SIZE = 100;
  private static int maxRemoteCacheSize = DEFAULT_REMOTE_CACHE_SIZE;
  private static Map<String, ImageRecord> imgs;
  private static IReferentMigrator dim = new DjatokaImageMigrator();
  // Keep track of downloaded images, delete when maxCache is hit
  private static LinkedHashMap<String, String> remoteCacheMap;
 
  /**
   * Referent Identifier to be resolved from Identifier Resolver. The returned
   * ImageRecord need only contain the imageId and image file path.
   * @param rft identifier of the image to be resolved
   * @return ImageRecord instance containing resolvable metadata
   * @throws ResolverException
   */
  public ImageRecord getImageRecord(Referent rft) throws ResolverException {
        String id = ((URIrft.getDescriptors()[0]).toASCIIString();
        return getImageRecord(id);
  }
 
  /**
   * Referent Identifier to be resolved from Identifier Resolver. The returned
   * ImageRecord need only contain the imageId and image file path.
   * @param rftId identifier of the image to be resolved
   * @return ImageRecord instance containing resolvable metadata
   * @throws ResolverException
   */
  public ImageRecord getImageRecord(String rftId) throws ResolverException {
    ImageRecord ir = imgs.get(rftId);
    if (ir == null && isResolvableURI(rftId)) {
      try {
        URI uri = new URI(rftId);
        if (dim.getProcessingList().contains(uri.toString())) {
          int i = 0;
          Thread.sleep(1000);
          while (dim.getProcessingList().contains(uri) && i < (5 * 60)){
            Thread.sleep(1000);
            i++;
          }
          if (imgs.containsKey(rftId))
              return imgs.get(rftId);
        }
        File f = dim.convert(uri);
        ir = new ImageRecord(rftId, f.getAbsolutePath());
        // LRU cache will delete oldest file when max is reached,
        // will also remove object from imgs and remoteCacheMap
        remoteCacheMap.put(rftId, f.getAbsolutePath());
        if (f.length() > 0)
            imgs.put(rftId, ir);
        else
          throw new ResolverException("An error occurred processing file:" + uri.toURL().toString());
      } catch (Exception e) {
        logger.error(e,e);
        throw new ResolverException(e);
      }
    } else if (isResolvableURI(rftId) && !new File(ir.getImageFile()).exists()) {
        // Handle ImageRecord in cache, but file does not exist on the file system
        imgs.remove(rftId);
        remoteCacheMap.remove(rftId);
        return getImageRecord(rftId);
    }
    return ir;
  }
   
  private static boolean isResolvableURI(String rftId) {
    return (rftId.startsWith("http") || rftId.startsWith("file") || rftId.startsWith("ftp"));
  }
 
  /**
   * Returns list of most recently requested images in accessed order.
   * @param cnt limit list to top n ImageRecords
   * @return list of requested image records
   */
  public ArrayList<ImageRecord> getImageRecordList(int cnt) {
    if (cnt >= imgs.size())
      return new ArrayList<ImageRecord>(imgs.values());
    else {
        ArrayList<ImageRecord> l = new ArrayList<ImageRecord>();
        int i = 0;
        for (ImageRecord rec : imgs.values()) {
          if (rec != null && i < cnt) {
            l.add(rec);
            i++;
          } else
            return l;
        }
    }
    return null;
  }

  /**
   * Sets a Properties object that may be used by underlying implementation
   * @param props Properties object for use by implementation
   * @throws ResolverException
   */
  public void setProperties(Properties props) throws ResolverException {
    try {
      String prop = props.getProperty(PROP_IMGS_INDEX);
      if (prop != null) {
        URL url = Thread.currentThread().getContextClassLoader().getResource(props.getProperty(PROP_IMGS_INDEX));
          imgs = getRecordMap(url.getFile());
      } else
        throw new ResolverException(PROP_IMGS_INDEX + " is not defined.");
      // Initialize remote image cache management
      String mrcs = props.getProperty(PROP_REMOTE_CACHE);
      if (mrcs != null)
          maxRemoteCacheSize = Integer.parseInt(mrcs);
     
      remoteCacheMap = new LinkedHashMap<String, String>(16, .85f, true) {
        private static final long serialVersionUID = 1;

        protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
          logger.debug("remoteCacheSize: " + size());
          boolean d = size() > maxRemoteCacheSize;
          if (d) {
            File f = new File((String) eldest.getValue());
            logger.debug("deleting: " + eldest.getValue());
            if (f.exists())
              f.delete();
            remove(eldest.getKey());
            imgs.remove(eldest.getKey());
          }
          return false;
        };
      };
    } catch (Exception e) {
      logger.error(e,e);
      throw new ResolverException(e);
    }
  }

  public IReferentMigrator getReferentMigrator() {
    return dim;
  }
 
  public int getStatus(String rftId) {
    if (imgs.get(rftId) != null)
      return HttpServletResponse.SC_OK;
    else if (dim.getProcessingList().contains(rftId))
      return HttpServletResponse.SC_ACCEPTED;
    else
      return HttpServletResponse.SC_NOT_FOUND;
  }
 
  private static Map<String, ImageRecord> getRecordMap(String f) throws Exception {
    Map<String, ImageRecord> map = Collections.synchronizedMap(new LinkedHashMap<String, ImageRecord>(16, 0.75f, true));
    BufferedReader reader = new BufferedReader(new FileReader(f));
    String row = null;
    for (int line = 0; true; line++) {
      row = reader.readLine();
            if (row == null)
                break;
      String[] v = row.split("\t");
      if (v.length < 2)
        System.out.println("Invalid format for Record Map; expects tab delimited id\tfilepath");
      ImageRecord r = new ImageRecord(v[0], v[1]);
      map.put(v[0], r);
    }
    return map;
  }
}
TOP

Related Classes of gov.lanl.adore.djatoka.openurl.SimpleListResolver

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.