Package org.freeplane.features.export.mindmapmode

Source Code of org.freeplane.features.export.mindmapmode.XsltExportEngineFactory

package org.freeplane.features.export.mindmapmode;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.freeplane.core.resources.ResourceController;
import org.freeplane.core.ui.ExampleFileFilter;
import org.freeplane.core.ui.components.UITools;
import org.freeplane.core.util.LogUtils;
import org.freeplane.core.util.TextUtils;

class XsltExportEngineFactory {
  final private static String EXPORT_FILTER_PATTERN = "^.*MINDMAPEXPORTFILTER\\s+(\\S+)\\s+(.*)(?:\\s+-->)?$";
  /** A pattern which is "MINDMAPEXPORTFILTER ext1;ext2;... File format description" */
  final private static String FILE_NAME_PATTERN = "mm2([\\w]+)\\.xsl";
  final private static Pattern COMPILED_EXPORT_FILTER_PATTERN = Pattern.compile(EXPORT_FILTER_PATTERN);
  final private static Pattern COMPILED_FILE_NAME_PATTERN = Pattern.compile(FILE_NAME_PATTERN);
  /** Maximum number of lines we read in each XSLT files for performance reasons */
  final private static int MAX_READ_LINES = 5;
  private ExportController controller;

  /** This method populates the {@link #filterMap} and the {@link #fileFilters} field. */
  void gatherXsltScripts(ExportController controller) {
    try{
      this.controller = controller;
    // look for user xslt scripts first
    gatherXsltScripts(getXsltUserDirectory());
    // use system xslt scripts as a fallback
    gatherXsltScripts(getXsltSysDirectory());
    }
    finally{
      this.controller = null;
    }
  }

  /**
   * A simple help function to get the directory where to search for XSLT
   * export files distributed with Freeplane.
   * @return The system directory where XSLT export files are supposed to be.
   */
  File getXsltSysDirectory() {
    return new File(ResourceController.getResourceController().getResourceBaseDir(), "xslt");
  }

  /**
   * A simple help function to get the directory where to search for XSLT
   * export files written by the user.
   * @return The user directory where XSLT export files are supposed to be.
   */
  File getXsltUserDirectory() {
    return new File(ResourceController.getResourceController().getFreeplaneUserDirectory(), "xslt");
  }

  /**
   * This methods checks all readable files ending in '.xsl' from a given directory,
   * and passes them to the method {@link #extractFilterFromFile}.
   * @param xsltdir the directory where XSLT files are to be searched for
   */
  private void gatherXsltScripts(final File xsltdir) {
    if (!(xsltdir.isDirectory() && xsltdir.canRead())) {
      return;
    }
    // we list the files using an anonymous filter class that accepts only files
    // readable by the user and with name ending in .xsl
    final File xsltFiles[] = xsltdir.listFiles(new java.io.FileFilter() {
      public boolean accept(final File pathname) {
        return (pathname.isFile() && pathname.canRead() && pathname.getPath().toLowerCase().endsWith(".xsl"));
      }
    });
    // we compile the pattern for performance reasons.
    // then for each found file, we check and extract a potentially present filter
    for (int i = 0; i < xsltFiles.length; i++) {
      extractFilterFromFile(xsltFiles[i]);
    }
  }

  /**
   * The function checks if the pattern matches with one of the lines in the file.
   * @param xsltFile the file to open and search a line matching the pattern.
   */
  private void extractFilterFromFile(final File xsltFile) {
    BufferedReader xsl = null;
    try {
      xsl = new BufferedReader(new FileReader(xsltFile));
      String line;
      int l = 0;
      boolean keyFound = false;
      // ...we open it and check if it contains the right marker
      while ((line = xsl.readLine()) != null && l < MAX_READ_LINES) {
        final Matcher m = COMPILED_EXPORT_FILTER_PATTERN.matcher(line);
        if (m.matches()) { // if it does
          keyFound = true;
          final String[] extensions = m.group(1).split("\\s*;\\s*");
          String description = m.group(2).trim();
          if(description.startsWith("%")){
            description = TextUtils.getText(description.substring(1));
          }
          addXsltFile(extensions, description, xsltFile);
          // we want to allow for more than one filter line per XSLT file
          // so we don't exit once we've found one and even account for
          // the fact that we might trespass the MAX_READ_LINES limit
          l--;
        }
        l++;
      }
      if (keyFound) {
        return;
      }
      final Matcher m = COMPILED_FILE_NAME_PATTERN.matcher(xsltFile.getName());
      if (m.matches()) { // if it does
        final String extension = m.group(1);
        final String description = TextUtils.format("exported_file", extension);
        addXsltFile(new String[] { extension }, description, xsltFile);
      }
    }
    catch (final IOException e) {
      LogUtils.warn(e);
      UITools.errorMessage(TextUtils.getText("export_failed"));
    }
    finally {
      if (xsl != null) {
        try {
          xsl.close();
        }
        catch (final IOException e) {
          LogUtils.severe(e);
        }
      }
    }
  }

  private void addXsltFile(final String[] extensions, String description, final File xsltFile) {
    final ExampleFileFilter filter = new ExampleFileFilter(extensions, TextUtils.getOptionalTranslation(description));
    final XsltExportEngine exporter = new XsltExportEngine(xsltFile);
    controller.addExportEngine(filter, exporter);
  }

}
TOP

Related Classes of org.freeplane.features.export.mindmapmode.XsltExportEngineFactory

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.