Package org.pentaho.reporting.designer.core.welcome

Source Code of org.pentaho.reporting.designer.core.welcome.SamplesTreeBuilder$DirectoryNode

/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program 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.
*
* Copyright (c) 2009 Pentaho Corporation.  All rights reserved.
*/

package org.pentaho.reporting.designer.core.welcome;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.designer.core.Messages;
import org.pentaho.reporting.designer.core.settings.SettingsUtil;
import org.pentaho.reporting.libraries.base.util.FilesystemFilter;
import org.pentaho.reporting.libraries.base.util.StringUtils;
import org.pentaho.reporting.libraries.resourceloader.ResourceData;
import org.pentaho.reporting.libraries.resourceloader.ResourceKey;
import org.pentaho.reporting.libraries.resourceloader.ResourceManager;

/**
* Todo: Document Me
*
* @author Thomas Morgner
*/
public class SamplesTreeBuilder
{
  private static class DirectoryNode extends DefaultMutableTreeNode
  {
    /**
     * Creates a tree node with no parent, no children, but which allows
     * children, and initializes it with the specified user object.
     *
     * @param userObject an Object provided by the user that constitutes
     *                   the node's data
     */
    private DirectoryNode(final Object userObject)
    {
      super(userObject);
    }

    /**
     * Returns true if this node has no children.  To distinguish between
     * nodes that have no children and nodes that <i>cannot</i> have
     * children (e.g. to distinguish files from empty directories), use this
     * method in conjunction with <code>getAllowsChildren</code>
     *
     * @return true if this node has no children
     * @see #getAllowsChildren
     */
    public boolean isLeaf()
    {
      return false;
    }
  }


  private static class DirectoryFileFilter implements FileFilter
  {
    private DirectoryFileFilter()
    {
    }

    public boolean accept(final File file)
    {
      if (file.getName().length() > 0 && file.getName().charAt(0) == '.')
      {
        return false;
      }
      return file.isDirectory();
    }
  }

  /**
   * HyperLink that opens a fiel as a new report, could be combined with the RecentDocButton
   *
   * @author OEM
   */
  public static class SampleNode extends DefaultMutableTreeNode
  {
    private String fileName;

    public SampleNode(final String lbl, final String file)
    {
      super(file);
      fileName = lbl;
    }

    public String toString()
    {
      return fileName;
    }
  }

  private static final Log logger = LogFactory.getLog(SamplesTreeBuilder.class);
  private static DefaultTreeModel sampleTreeModel;
  private static final DirectoryFileFilter DIRECTORY_FILTER = new DirectoryFileFilter();
  private static final FilesystemFilter REPORT_FILES_FILTER =
      new FilesystemFilter(new String[]{".report", ".prpt"}, "", false);// NON-NLS

  private SamplesTreeBuilder()
  {
  }

  public static synchronized TreeModel getSampleTreeModel()
  {
    if (sampleTreeModel == null)
    {
      sampleTreeModel = createModel();
    }
    return sampleTreeModel;
  }

  private static DefaultTreeModel createModel()
  {
    final DefaultMutableTreeNode root = new DefaultMutableTreeNode(Messages.getString("WelcomePane.samples"));// NON-NLS
    final DefaultTreeModel model = new DefaultTreeModel(root);

    try
    {
      final ResourceManager resourceManager = new ResourceManager();
      resourceManager.registerDefaults();

      final HashMap cache = loadFromCache(resourceManager);

      final File installationDirectory = SettingsUtil.computeInstallationDirectory();
      if (installationDirectory != null)
      {
        final File configTemplateDir = new File(installationDirectory, "samples");// NON-NLS
        if (configTemplateDir.exists() && configTemplateDir.isDirectory())
        {
          processDirectory(root, configTemplateDir, cache, resourceManager);
        }
      }

      storeToCache(cache);
    }
    catch (Exception e)
    {
      return model;
    }
    return model;
  }

  /**
   * Creates a list of SampleReports located in the /samples directory.
   */
  private static void processDirectory(final DefaultMutableTreeNode root,
                                       final File dir,
                                       final HashMap cachedEntries,
                                       final ResourceManager resourceManager)
  {
    try
    {
      final File[] dirs = dir.listFiles(DIRECTORY_FILTER);
      if (dirs == null)
      {
        return;
      }
      for (final File f : dirs)
      {
        final DefaultMutableTreeNode dirNode = new DirectoryNode(f.getName());
        root.add(dirNode);
        processDirectory(dirNode, f, cachedEntries, resourceManager);
      }

      //Now add sample files
      final File[] samplesArray = dir.listFiles(REPORT_FILES_FILTER);
      if (samplesArray == null)
      {
        return;
      }

      Arrays.sort(samplesArray);
      for (final File f : samplesArray)
      {
        final SampleReport entryFromCache = (SampleReport) cachedEntries.get(f.getAbsolutePath());
        if (entryFromCache == null)
        {
          final SampleReport tempRpt = new SampleReport(f, resourceManager);
          if (StringUtils.isEmpty(tempRpt.getReportName()) == false)
          {
            final SampleNode sample = new SampleNode(tempRpt.getReportName(), tempRpt.getFileName());
            root.add(sample);
          }
          cachedEntries.put(f.getAbsolutePath(), tempRpt);
        }
        else
        {
          if (StringUtils.isEmpty(entryFromCache.getReportName()) == false)
          {
            final SampleNode sample = new SampleNode(entryFromCache.getReportName(), entryFromCache.getFileName());
            root.add(sample);
          }
        }
      }

    }
    catch (Exception se)
    {
      logger.error("Cannot access Application directory", se);// NON-NLS
    }
  }

  protected static HashMap loadFromCache(final ResourceManager resourceManager)
  {

    final File location = createStorageLocation();
    if (location == null)
    {
      return new HashMap();
    }
    final File ttfCache = new File(location, "samples-cache.ser");// NON-NLS
    try
    {
      final ResourceKey resourceKey = resourceManager.createKey(ttfCache);
      final ResourceData data = resourceManager.load(resourceKey);
      final InputStream stream = data.getResourceAsStream(resourceManager);

      final HashMap cachedSeenFiles;

      try
      {
        final ObjectInputStream oin = new ObjectInputStream(stream);
        final Object[] cache = (Object[]) oin.readObject();
        if (cache.length != 1)
        {
          return new HashMap();
        }
        cachedSeenFiles = (HashMap) cache[0];
      }
      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))
      {
        return cachedSeenFiles;
      }
    }
    catch (final ClassNotFoundException cnfe)
    {
      // ignore the exception.
      logger.debug("Failed to restore the cache: Cache was created by a different version of ReportDesigner");// NON-NLS
    }
    catch (Exception e)
    {
      logger.debug("Non-Fatal: Failed to restore the cache. The cache will be rebuilt.", e);// NON-NLS
    }

    return new HashMap();
  }

  protected static void storeToCache(final HashMap seenFiles)
  {
    final File location = createStorageLocation();
    if (location == null)
    {
      return;
    }
    location.mkdirs();
    if (location.exists() == false || location.isDirectory() == false)
    {
      return;
    }

    final File ttfCache = new File(location, "samples-cache.ser");// NON-NLS
    try
    {
      final FileOutputStream fout = new FileOutputStream(ttfCache);
      try
      {
        final Object[] map = new Object[1];
        map[0] = seenFiles;

        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 samples data", e);// NON-NLS
        }
      }
    }
    catch (IOException e)
    {
      // should not happen
      logger.debug("Failed to store cached samples data", e);// NON-NLS
    }
  }

  protected static File createStorageLocation()
  {
    final String homeDirectory = safeSystemGetProperty("user.home", null);// NON-NLS
    if (homeDirectory == null)
    {
      return null;
    }
    final File homeFile = new File(homeDirectory);
    if (homeFile.isDirectory() == false)
    {
      return null;
    }
    return new File(homeFile, ".pentaho/caches/prd-samples");// NON-NLS
  }


  protected static String safeSystemGetProperty(final String name,
                                                final String defaultValue)
  {
    try
    {
      return System.getProperty(name, defaultValue);
    }
    catch (SecurityException se)
    {
      return defaultValue;
    }
  }


  protected static boolean isCacheValid(final HashMap cachedSeenFiles)
  {
    final Iterator iterator = cachedSeenFiles.entrySet().iterator();
    while (iterator.hasNext())
    {
      final Map.Entry entry = (Map.Entry) iterator.next();
      final String fullFileName = (String) entry.getKey();
      final SampleReport fontFileRecord = (SampleReport) entry.getValue();
      final File fontFile = new File(fullFileName);
      if (fontFile.isFile() == false || fontFile.exists() == false)
      {
        return false;
      }
      if (fontFile.length() != fontFileRecord.getFileSize())
      {
        return false;
      }
      if (fontFile.lastModified() != fontFileRecord.getLastAccessTime())
      {
        return false;
      }
    }
    return true;
  }

}
TOP

Related Classes of org.pentaho.reporting.designer.core.welcome.SamplesTreeBuilder$DirectoryNode

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.