Code example for File

Methods: getCanonicalPathlastModifiedlength

0
import java.util.Iterator; 
import java.util.Map; 
import java.util.StringTokenizer; 
 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.pentaho.reporting.libraries.base.config.Configuration; 
import org.pentaho.reporting.libraries.base.util.ObjectUtilities; 
import org.pentaho.reporting.libraries.base.util.StringUtils; 
import org.pentaho.reporting.libraries.fonts.LibFontBoot; 
import org.pentaho.reporting.libraries.fonts.encoding.EncodingRegistry; 
import org.pentaho.reporting.libraries.resourceloader.ResourceData; 
import org.pentaho.reporting.libraries.resourceloader.ResourceKey; 
import org.pentaho.reporting.libraries.resourceloader.ResourceManager; 
 
/** 
 * Creation-Date: 21.07.2007, 17:01:15 
 * 
 * @author Thomas Morgner 
 * @noinspection HardCodedStringLiteral 
 */ 
public abstract class AbstractFontFileRegistry implements FontRegistry 
{ 
  private static final Log logger = LogFactory.getLog(AbstractFontFileRegistry.class);
 
  private HashMap<String, FontFileRecord> seenFiles;
  private HashMap<String, DefaultFontFamily> fontFamilies;
  private HashMap<String, DefaultFontFamily> alternateFamilyNames;
  private HashMap<String, DefaultFontFamily> fullFontNames;
 
  protected AbstractFontFileRegistry() 
  { 
    seenFiles = new HashMap<String, FontFileRecord>();
    this.fontFamilies = new HashMap<String, DefaultFontFamily>();
    this.alternateFamilyNames = new HashMap<String, DefaultFontFamily>();
    this.fullFontNames = new HashMap<String, DefaultFontFamily>();
  } 
 
  protected HashMap<String, FontFileRecord> getSeenFiles()
  { 
    return seenFiles;
  } 
 
  protected abstract FileFilter getFileFilter();
 
  public void initialize() 
  { 
    registerDefaultFontPath(); 
    final Configuration configuration = LibFontBoot.getInstance().getGlobalConfig();
    final Iterator extraDirIt =
        configuration.findPropertyKeys("org.pentaho.reporting.libraries.fonts.extra-font-dirs.");
    while (extraDirIt.hasNext())
    { 
      final String extraDirKey = (String) extraDirIt.next();
      final String extraDir = configuration.getConfigProperty(extraDirKey);
      final File extraDirFile = new File(extraDir);
      try 
      { 
        if (extraDirFile.isDirectory())
        { 
          registerFontPath(extraDirFile, getDefaultEncoding());
        } 
      } 
      catch (Exception e)
      { 
        logger.warn("Extra font path " + extraDir + " could not be fully registered.", e);
      } 
    } 
  } 
 
  protected String getDefaultEncoding()
  { 
    return LibFontBoot.getInstance().getGlobalConfig().getConfigProperty 
        ("org.pentaho.reporting.libraries.fonts.itext.FontEncoding", EncodingRegistry.getPlatformDefaultEncoding()); 
  } 
 
  /** 
   * Register os-specific font paths to the PDF-FontFactory. For unix-like operating systems, X11 is searched in 
   * /usr/X11R6 and the default truetype fontpath is added. For windows the system font path is added (%windir%/fonts) 
   */ 
  public void registerDefaultFontPath() 
  { 
    final String encoding = getDefaultEncoding();
    loadFromCache(encoding);
 
    final String osname = safeSystemGetProperty("os.name", "<protected by system security>");
    final String jrepath = safeSystemGetProperty("java.home", ".");
    final String fs = safeSystemGetProperty("file.separator", File.separator);
 
    logger.debug("Running on operating system: " + osname);
    logger.debug("Character encoding used as default: " + encoding);
 
    if (StringUtils.startsWithIgnoreCase(osname, "mac os x"))
    { 
      final String userhome = safeSystemGetProperty("user.home", ".");
      logger.debug("Detected MacOS.");
      registerFontPath(new File(userhome + "/Library/Fonts"), encoding);
      registerFontPath(new File("/Library/Fonts"), encoding);
      registerFontPath(new File("/Network/Library/Fonts"), encoding);
      registerFontPath(new File("/System/Library/Fonts"), encoding);
    } 
    else if (StringUtils.startsWithIgnoreCase(osname, "windows"))
    { 
      registerWindowsFontPath(encoding);
    } 
    else 
    { 
      logger.debug("Assuming unix like file structures");
      // Assume X11 is installed in the default location. 
      registerFontPath(new File("/usr/X11R6/lib/X11/fonts"), encoding);
      registerFontPath(new File("/usr/share/fonts"), encoding);
    } 
    registerFontPath(new File(jrepath, "lib" + fs + "fonts"), encoding);
 
    storeToCache(encoding);
    logger.info("Completed font registration.");
  } 
 
  protected void registerPrimaryName(final String name, final DefaultFontFamily family)
  { 
    this.fontFamilies.put(name, family);
  } 
 
  protected void registerAlternativeName(final String name, final DefaultFontFamily family)
  { 
    this.alternateFamilyNames.put(name, family);
  } 
 
  protected void registerFullName(final String name, final DefaultFontFamily family)
  { 
    this.fullFontNames.put(name, family);
  } 
 
  protected DefaultFontFamily createFamily(final String name)
  { 
    final DefaultFontFamily fontFamily = this.fontFamilies.get(name);
    if (fontFamily != null)
    { 
      return fontFamily;
    } 
 
    final DefaultFontFamily createdFamily = new DefaultFontFamily(name);
    this.fontFamilies.put(name, createdFamily);
    return createdFamily;
  } 
 
  public String[] getRegisteredFamilies()
  { 
    return fontFamilies.keySet().toArray(new String[fontFamilies.size()]);
  } 
 
  public String[] getAllRegisteredFamilies()
  { 
    return alternateFamilyNames.keySet().toArray(new String[alternateFamilyNames.size()]);
  } 
 
  public FontFamily getFontFamily(final String name)
  { 
    final FontFamily primary = this.fontFamilies.get(name);
    if (primary != null)
    { 
      return primary;
    } 
    final FontFamily secondary = this.alternateFamilyNames.get(name);
    if (secondary != null)
    { 
      return secondary;
    } 
    return this.fullFontNames.get(name);
  } 
 
  protected void loadFromCache(final String encoding)
  { 
    final String fileName = getCacheFileName();
    if (fileName == null)
    { 
      return; 
    } 
    loadFromCache(encoding, fileName);
  } 
 
  protected void populateFromCache(final HashMap<String, DefaultFontFamily> cachedFontFamilies,
                                   final HashMap<String, DefaultFontFamily> cachedFullFontNames,
                                   final HashMap<String, DefaultFontFamily> cachedAlternateNames)
  { 
    this.fontFamilies.putAll(cachedFontFamilies);
    this.fullFontNames.putAll(cachedFullFontNames);
    this.alternateFamilyNames.putAll(cachedAlternateNames);
  } 
 
  protected void loadFromCache(final String encoding, final String filename)
  { 
    final ResourceManager resourceManager = new ResourceManager();
    final File location = createStorageLocation();
    if (location == null)
    { 
      return; 
    } 
    final File ttfCache = new File(location, filename);
    try 
    { 
      final ResourceKey resourceKey = resourceManager.createKey(ttfCache);
      final ResourceData data = resourceManager.load(resourceKey);
      final InputStream stream = data.getResourceAsStream(resourceManager);
 
      final HashMap<String, FontFileRecord> cachedSeenFiles;
      final HashMap<String, DefaultFontFamily> cachedFontFamilies;
      final HashMap<String, DefaultFontFamily> cachedFullFontNames;
      final HashMap<String, DefaultFontFamily> cachedAlternateNames;
 
      try 
      { 
        final ObjectInputStream oin = new ObjectInputStream(stream);
        final Object[] cache = (Object[]) oin.readObject();
        if (cache.length != 5)
        { 
          return; 
        } 
        if (ObjectUtilities.equal(encoding, cache[0]) == false)
        { 
          return; 
        } 
        cachedSeenFiles = (HashMap<String, FontFileRecord>) cache[1];
        cachedFontFamilies = (HashMap<String, DefaultFontFamily>) cache[2];
        cachedFullFontNames = (HashMap<String, DefaultFontFamily>) cache[3];
        cachedAlternateNames = (HashMap<String, DefaultFontFamily>) cache[4];
      } 
      finally 
      { 
        stream.close();
      } 
 
      // next; check the font-cache for validity. We cannot cleanly remove 
      // entries from the cache once they become invalid, so we have to rebuild 
      // the cache from scratch, if it is invalid. 
      // 
      // This should not matter that much, as font installations do not happen 
      // every day. 
      if (isCacheValid(cachedSeenFiles))
      { 
        this.getSeenFiles().putAll(cachedSeenFiles);
        populateFromCache(cachedFontFamilies, cachedFullFontNames, cachedAlternateNames);
      } 
    } 
    catch (final ClassNotFoundException cnfe)
    { 
      // ignore the exception. 
      logger.debug("Failed to restore the cache: Cache was created by a different version of LibFonts");
    } 
    catch (Exception e)
    { 
      logger.debug("Non-Fatal: Failed to restore the cache. The cache will be rebuilt.", e);
    } 
  } 
 
  protected String getCacheFileName()
  { 
    return null; 
  } 
 
  protected void storeToCache(final String encoding)
  { 
    final String cacheFileName = getCacheFileName();
    if (cacheFileName == null)
    { 
      return; 
    } 
 
    final File location = createStorageLocation();
    if (location == null)
    { 
      return; 
    } 
    location.mkdirs();
    if (location.exists() == false || location.isDirectory() == false)
    { 
      return; 
    } 
 
    final File ttfCache = new File(location, cacheFileName);
    try 
    { 
      final FileOutputStream fout = new FileOutputStream(ttfCache);
      try 
      { 
        final Object[] map = new Object[5];
        map[0] = encoding;
        map[1] = getSeenFiles();
        map[2] = fontFamilies;
        map[3] = fullFontNames;
        map[4] = alternateFamilyNames;
 
        final ObjectOutputStream objectOut = new ObjectOutputStream(new BufferedOutputStream(fout));
        objectOut.writeObject(map);
        objectOut.close();
      } 
      finally 
      { 
        try 
        { 
          fout.close();
        } 
        catch (IOException e)
        { 
          // ignore .. 
          logger.debug("Failed to store cached font data", e);
        } 
      } 
    } 
    catch (IOException e)
    { 
      // should not happen 
      logger.debug("Failed to store cached font data", e);
    } 
  } 
 
  /** 
   * Registers the default windows font path. Once a font was found in the old seenFiles map and confirmed, that this 
   * font still exists, it gets copied into the confirmedFiles map. 
   * 
   * @param encoding the default font encoding. 
   */ 
  private void registerWindowsFontPath(final String encoding)
  { 
    logger.debug("Found 'Windows' in the OS name, assuming DOS/Win32 structures");
    // Assume windows 
    // If you are not using windows, ignore this. This just checks if a windows system 
    // directory exist and includes a font dir. 
 
    String fontPath = null;
    final String windirs = safeSystemGetProperty("java.library.path", null);
    final String fs = safeSystemGetProperty("file.separator", File.separator);
 
    if (windirs != null)
    { 
      final StringTokenizer strtok = new StringTokenizer
          (windirs, safeSystemGetProperty("path.separator", File.pathSeparator));
      while (strtok.hasMoreTokens())
      { 
        final String token = strtok.nextToken();
 
        if (StringUtils.endsWithIgnoreCase(token, "System32"))
        { 
          // found windows folder ;-) 
          final int lastBackslash = token.lastIndexOf(fs);
          if (lastBackslash != -1)
          { 
            fontPath = token.substring(0, lastBackslash) + fs + "Fonts";
            break; 
          } 
          // try with forward slashs. Some systems may use the unix-semantics instead. 
          // (Windows accepts both characters as path-separators for historical reasons) 
          final int lastSlash = token.lastIndexOf('/');
          if (lastSlash != -1)
          { 
            fontPath = token.substring(0, lastSlash) + lastSlash + "Fonts";
            break; 
          } 
        } 
      } 
    } 
    logger.debug("Fonts located in \"" + fontPath + '\"');
    if (fontPath != null)
    { 
      final File file = new File(fontPath);
      registerFontPath(file, encoding);
    } 
  } 
 
  /** 
   * Register all fonts (*.ttf files) in the given path. 
   * 
   * @param file     the directory that contains the font files. 
   * @param encoding the encoding for the given font. 
   */ 
  public void registerFontPath(final File file, final String encoding)
  { 
    if (file.exists() && file.isDirectory() && file.canRead())
    { 
      final File[] files = file.listFiles(getFileFilter());
      final int fileCount = files.length;
      for (int i = 0; i < fileCount; i++)
      { 
        final File currentFile = files[i];
        if (currentFile.isDirectory())
        { 
          registerFontPath(currentFile, encoding);
        } 
        else 
        { 
          if (isCached(currentFile) == false)
          { 
            registerFontFile(currentFile, encoding);
          } 
        } 
      } 
    } 
  } 
 
 
  protected boolean isCached(final File file)
  { 
    try 
    { 
      final FontFileRecord stored = seenFiles.get(file.getCanonicalPath());
      if (stored == null)
      { 
        return false; 
      }