Package com.sun.star.help

Source Code of com.sun.star.help.HelpLinker

/*************************************************************************
*
*  OpenOffice.org - a multi-platform office productivity suite
*
*  $RCSfile: HelpLinker.java,v $
*
*  $Revision: 1.13 $
*
*  last change: $Author: kz $ $Date: 2006/01/05 14:45:47 $
*
*  The Contents of this file are made available subject to
*  the terms of GNU Lesser General Public License Version 2.1.
*
*
*    GNU Lesser General Public License Version 2.1
*    =============================================
*    Copyright 2005 by Sun Microsystems, Inc.
*    901 San Antonio Road, Palo Alto, CA 94303, USA
*
*    This library 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.
*
*    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., 59 Temple Place, Suite 330, Boston,
*    MA  02111-1307  USA
*
************************************************************************/

/**************************************************************************
                TODO
**************************************************************************

*************************************************************************/

package com.sun.star.help;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.StringTokenizer;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.zip.CRC32;

import com.sleepycat.db.Db;
import com.sleepycat.db.DbException;
import com.sleepycat.db.Dbt;
import com.sun.xmlsearch.util.PrefixTranslator;
import com.sun.xmlsearch.xml.indexer.XmlIndexBuilder;

class HelpLinker {

  public static int locCount = 0, totCount = 0;

  public static void main(String[] args) {
        HelpCompiler.initURLHandler();

    Hashtable additionalFiles = new Hashtable();
    HashSet helpFiles = new HashSet();
    String sourceRoot = null;
    String embeddStylesheet = null;
    String indexStylesheet = null;
    String outputFile = null;
    String module = null;
    String lang = null;
    String hid = null;
    if (args.length > 0 && args[0].startsWith("@")) {
//      try {
//        Thread.sleep(100000);
//      } catch (InterruptedException e1) {
//        // TODO Auto-generated catch block
//        e1.printStackTrace();
//      }
      try {
        String fName = args[0].substring(1);
        FileReader fileReader = new FileReader(fName);
        StringBuffer strBuf = new StringBuffer();
        int n = 0;
        char[] c = new char[1024];
        while ((n = fileReader.read(c, 0, 1024)) != -1)
          strBuf.append(c, 0, n);
        String str = strBuf.toString();
        StringTokenizer strTokenizer = new StringTokenizer(str);
        n = 0;
        String[] stringList = new String[strTokenizer.countTokens()];
        while (strTokenizer.hasMoreElements())
          stringList[n++] = strTokenizer.nextToken();
        args = stringList;
      } catch (Exception e) {
        e.printStackTrace();
        System.exit(1);
      }
    }
    int i = 0;

    while (i < args.length) {
      if (args[i].equals("-src")) {
        ++i;
        if (i >= args.length) {
          System.err.println("sourceroot missing");
          System.exit(1);
        }

        sourceRoot = args[i];
      } else if (args[i].equals("-sty")) {
        ++i;
        if (i >= args.length) {
          System.err.println("embeddingStylesheet missing");
          System.exit(1);
        }

        embeddStylesheet = args[i];
      } else if (args[i].equals("-idx")) {
        ++i;
        if (i >= args.length) {
          System.err.println("indexstylesheet missing");
          System.exit(1);
        }

        indexStylesheet = args[i];
      } else if (args[i].equals("-o")) {
        ++i;
        if (i >= args.length) {
          System.err.println("outputfilename missing");
          System.exit(1);
        }

        outputFile = args[i];
      } else if (args[i].equals("-mod")) {
        ++i;
        if (i >= args.length) {
          System.err.println("module name missing");
          System.exit(1);
        }

        module = args[i];
      } else if (args[i].equals("-lang")) {
        ++i;
        if (i >= args.length) {
          System.err.println("language name missing");
          System.exit(1);
        }

        lang = args[i];
      } else if (args[i].equals("-hid")) {
        ++i;
        if (i >= args.length) {
          System.err.println("hid list missing");
          System.exit(1);
        }

        hid = args[i];
      } else if (args[i].equals("-add")) {
        String addFile, addFileUnderPath;
        ++i;
        if (i >= args.length) {
          System.err.println("pathname missing");
          System.exit(1);
        }

        addFileUnderPath = args[i];
        ++i;
        if (i >= args.length) {
          System.err.println("pathname missing");
          System.exit(1);
        }
        addFile = args[i];
        if (addFileUnderPath.length() != 0 && addFile.length() != 0)
          additionalFiles.put(addFileUnderPath, addFile);
      } else {
        String adding = args[i];
        helpFiles.add(adding);
      }
      ++i;
    }

    if (indexStylesheet == null) {
      System.err.println("no index file given");
      System.exit(1);
    }
    if (embeddStylesheet == null) {
      System.err.println("no embedding resolving file given");
      System.exit(1);
    }
    if (sourceRoot == null) {
      System.err.println("no sourceroot given");
      System.exit(1);
    }
    if (outputFile == null) {
      System.err.println("no output file given");
      System.exit(1);
    }
    if (module == null) {
      System.err.println("module missing");
      System.exit(1);
    }
    if (lang == null) {
      System.err.println("language missing");
      System.exit(1);
    }
    if (hid == null) {
      System.err.println("hid list missing");
      System.exit(1);
    }

    try {
      new HelpLinker(
        sourceRoot,
        embeddStylesheet,
        indexStylesheet,
        outputFile,
        module,
        lang,
        hid,
        helpFiles,
        additionalFiles)
        .link();
      System.out.println(
        "number of local fetches: "
          + locCount);
      System.out.println(
        "total number of fetches: "
          + totCount);
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  private JarOutputStream jarOutputStream;
  private Hashtable additionalFiles;
  private HashSet helpFiles;
  private String sourceRoot, embeddStylesheet, indexStylesheet;
  private String outputFile;
  private String module;
  private String lang;
  private String hid;
  private Hashtable hidlistTranslation = new Hashtable();
  private HelpURLStreamHandlerFactory _urlHandler = null;

  private String indexDirParentName = null;
  private File indexDirFile = null;
  private boolean init = true;
  private XmlIndexBuilder xmlIndexBuilder = null;

  void initXMLIndexBuilder() throws Exception {
    // Create indexDirectory, if not existent
    File indexDirParentFile = File.createTempFile("temp", ".dir");
    indexDirParentName = indexDirParentFile.getAbsolutePath();

    indexDirParentFile.delete();
    indexDirParentFile.mkdir();
    String indexDirName =
      indexDirParentName + File.separator + module.toLowerCase() + ".idx";
    indexDirFile = new File(indexDirName);
    if (indexDirFile.exists() && indexDirFile.isFile())
      indexDirFile.delete();

    if (!indexDirFile.exists())
      indexDirFile.mkdir();

    xmlIndexBuilder = new XmlIndexBuilder(indexDirName);
    String[] translations = { "vnd.sun.star.help://", "#HLP#" };
    PrefixTranslator translator =
      PrefixTranslator.makePrefixTranslator(translations);
    xmlIndexBuilder.setPrefixTranslator(translator);

    String defaultXSL =
      "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
        + "<xsl:template match=\"*|/\"/>"
        + "</xsl:stylesheet>";
    createFileFromBytes("default.xsl", defaultXSL.getBytes("UTF8"));

    xmlIndexBuilder.clearIndex(); // Build index from scratch
    xmlIndexBuilder.setTransformLocation(indexDirParentName);
  }

  private void createFileFromBytes(String fileName, byte[] defaultXSL)
    throws IOException {
    File defaultXSLFile =
      new File(indexDirParentName + File.separator + fileName);
    defaultXSLFile.createNewFile();
    FileOutputStream fos = new FileOutputStream(defaultXSLFile);
    fos.write(defaultXSL);
    fos.close();
  }

  void closeXMLIndexBuilder() throws Exception {
    xmlIndexBuilder.close();
  }

  private static boolean removeTempDirectory(String dirName) {
    // recursively remove directory
    File dir = new File(dirName);
    File[] list = dir.listFiles();
    for (int i = 0; i < list.length; i++) {
      if (list[i].isDirectory()) {
        if (!removeTempDirectory(dirName
          + File.separator
          + list[i].getName()))
          return false;
      } else {
        if (!list[i].delete())
          return false;
      }
    }
    if (!dir.delete())
      return false;

    return true;
  }

  /**
   *
   */
  private void link() throws Exception {
       
    // Determine the outputstream
        String outputTmpFile = outputFile + ".tmp";
        File outTmpFile = new File(outputTmpFile);
        outTmpFile.createNewFile();
    FileOutputStream os = null;
    try {
      os = new FileOutputStream(outTmpFile);
    } catch (FileNotFoundException e) {
        }
       
    if (os == null)
      System.exit(1);

    try {
      jarOutputStream = new JarOutputStream(os);
    } catch (IOException e) {
      e.printStackTrace();
      System.exit(1);
    }

    // do the work here
    // continue with introduction of the overall process thing into the
    // here all hzip files will be worked on
    String appl = module.toLowerCase();
    if (appl.startsWith("s"))
      appl = appl.substring(1);

    File helpTextFile = File.createTempFile("helptext", ".ht");
    helpTextFile.deleteOnExit();
    String helpTextFileName = helpTextFile.getAbsolutePath();
    Db helpText = new Db(null, 0);
    helpText.open(null,helpTextFileName, null, Db.DB_BTREE, Db.DB_TRUNCATE, 0644);

    File dbBaseFile = File.createTempFile("database", "db");
    dbBaseFile.deleteOnExit();
    String dbBaseFileName = dbBaseFile.getAbsolutePath();
    Db dbBase = new Db(null, 0);
    dbBase.open(null,dbBaseFileName, null, Db.DB_BTREE, Db.DB_TRUNCATE, 0644);

    File keyWordFile = File.createTempFile("keybase", "key");
    keyWordFile.deleteOnExit();
    String keyWordFileName = keyWordFile.getAbsolutePath();
    Db keyWord = new Db(null, 0);
    keyWord.open(null,keyWordFileName, null, Db.DB_BTREE, Db.DB_TRUNCATE, 0644);
    HelpKeyword helpKeyword = new HelpKeyword();

    // now input the hid.lst and store it into a hashmap
    FileReader fileReader = new FileReader(hid);
    StringBuffer strBuf = new StringBuffer();
    int n = 0;
    char[] c = new char[1024];
    while ((n = fileReader.read(c, 0, 1024)) != -1)
      strBuf.append(c, 0, n);
    String str = strBuf.toString();
    StringTokenizer strTokenizer = new StringTokenizer(str);
    while (strTokenizer.hasMoreTokens()) {
      String key = strTokenizer.nextToken();
      String data = strTokenizer.nextToken();
      hidlistTranslation.put(
        key.toUpperCase().replace(':', '_'),
        data.trim());
    }

    // lastly, initialize the indexBuilder
    if (!helpFiles.isEmpty())
      initXMLIndexBuilder();

    // here we start our loop over the hzip files.
    Iterator iter = helpFiles.iterator();
    while (iter.hasNext()) {
      // process one file
      // streamTable contains the streams in the hzip file
      //Hashtable streamTable = new Hashtable();
      Hashtable streamTable1 = new Hashtable();

      String xhpFileName = (String) iter.next();
      if (!xhpFileName.endsWith(".xhp")) {
        // only work on .xhp - files
        System.err.println(
          "ERROR: input list entry '"
            + xhpFileName
            + "' has the wrong extension (only files with extension .xhp "
            + "are accepted)");
        continue;
      }

      HelpCompiler hc =
        new HelpCompiler(
          streamTable1,
          xhpFileName,
          sourceRoot + File.separator + lang + File.separator,
          embeddStylesheet,
          module,
          lang);
      try {
        boolean success = hc.compile();
        if (!success) {
          System.err.println(
            "\nERROR: compiling help particle '"
              + xhpFileName
              + "' for language '"
              + lang
              + "' failed!");
          System.exit(1);
        }
      } catch (UnsupportedEncodingException e) {
        System.err.println(
          "\nERROR: unsupported Encoding Exception'"
            + "': "
            + e.getMessage());
        System.exit(1);
      }

      // Read the document core data
      byte[] byStr = (byte[]) streamTable1.get("document/id");
      String documentBaseId = null;
      if (byStr != null) {
        documentBaseId = new String(byStr, "UTF8");
      } else {
        System.err.println("corrupt compileroutput");
        System.exit(1);
      }

      String documentPath =
        new String(
          ((byte[]) streamTable1.get("document/path")),
          "UTF8");

      if (documentPath.startsWith("/"))
        documentPath = documentPath.substring(1);
      String documentJarfile =
        new String(
          ((byte[]) streamTable1.get("document/module")),
          "UTF8")
          + ".jar";

      byte[] byteStream = (byte[]) streamTable1.get("document/title");

      String documentTitle = null;
      if (byteStream != null)
        documentTitle = new String(byteStream, "UTF8");
      else
        documentTitle = "<notitle>";

      byte[] fileB = documentPath.getBytes("UTF8");
      byte[] jarfileB = documentJarfile.getBytes("UTF8");
      byte[] titleB = documentTitle.getBytes("UTF8");
      // add once this as its own id.
      addBookmark(dbBase, documentPath, fileB, null, jarfileB, titleB);

      if (init) {
        FileInputStream indexXSLFile =
          new FileInputStream(indexStylesheet);
        int read = 0;
        byte[] bytes = new byte[2048];
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        while ((read = indexXSLFile.read(bytes, 0, 2048)) != -1)
          baos.write(bytes, 0, read);
        createFileFromBytes("index.xsl", baos.toByteArray());

        xmlIndexBuilder.init("index");
        init = false;
      }

      // first the database *.db
      // ByteArrayInputStream bais = null;
      // ObjectInputStream ois = null;

      Object baos = streamTable1.get(appl + "/hidlist");
      if (baos == null)
        baos = streamTable1.get("default/hidlist");
      if (baos != null) {
        HashSet hidlist = (HashSet) baos;

        // now iterate over all elements of the hidlist
        Iterator hidListIter = hidlist.iterator();
        while (hidListIter.hasNext()) {
          String hid = (String) hidListIter.next();

          byte[] anchorB = null;
          int index = hid.lastIndexOf('#');
          if (index != -1) {
            anchorB = hid.substring(1 + index).getBytes("UTF8");
            hid = hid.substring(0, index);
          }
          addBookmark(dbBase, hid, fileB, anchorB, jarfileB, titleB);
        }
      }

      // now the keywords
      baos = streamTable1.get(appl + "/keywords");
      if (baos == null)
        baos = streamTable1.get("default/keywords");
      if (baos != null) {
        Hashtable anchorToLL = (Hashtable) baos;
        Enumeration enumer = anchorToLL.keys();
        String fakedHid = URLEncoder.encode(documentPath);
        while (enumer.hasMoreElements()) {
          String anchor = (String) enumer.nextElement();
          addBookmark(
            dbBase,
            documentPath,
            fileB,
            anchor.getBytes("UTF8"),
            jarfileB,
            titleB);
          String totalId = fakedHid + "#" + anchor;
          // System.err.println(hzipFileName);
          LinkedList ll = (LinkedList) anchorToLL.get(anchor);
          Iterator llIter = ll.iterator();
          while (llIter.hasNext())
            helpKeyword.insert((String) llIter.next(), totalId);
        }
      }

      // and last the helptexts
      baos = streamTable1.get(appl + "/helptexts");
      if (baos == null)
        baos = streamTable1.get("default/helptexts");
      if (baos != null) {
        Hashtable helpTextHash = (Hashtable) baos;
        Enumeration helpTextIter = helpTextHash.keys();
        while (helpTextIter.hasMoreElements()) {
          String helpTextId = (String) helpTextIter.nextElement();
          String helpTextText = (String) helpTextHash.get(helpTextId);

          String tHid =
            (String) hidlistTranslation.get(
              helpTextId.toUpperCase().replace(':', '_'));
          if (tHid != null)
            helpTextId = tHid;
          helpTextId = URLEncoder.encode(helpTextId);
          Dbt keyDbt = new Dbt(helpTextId.getBytes("UTF8"));
          Dbt textDbt = new Dbt(helpTextText.getBytes("UTF8"));
          helpText.put(null, keyDbt, textDbt, 0);
        }
      }
      // now the indexing
      // and last the helptexts
      baos = (byte[]) streamTable1.get(appl + "/text");
      if (baos == null)
        baos = (byte[]) streamTable1.get("default/text");

      if (baos != null) {
        byte[] bytes = (byte[]) baos;

        HelpURLStreamHandlerFactory.setMode(bytes);
        xmlIndexBuilder.indexDocument(
          new URL(
            "vnd.sun.star.help://"
              + module.toLowerCase()
              + "/"
              + URLEncoder.encode(documentPath)),
          "");
      }
    } // while loop over hzip files ending

    helpText.close(0);
    dbBase.close(0);
    helpKeyword.dump(keyWord);
    keyWord.close(0);
    if (!helpFiles.isEmpty())
      closeXMLIndexBuilder();

    // now copy the databases into memory, so we will be able to add it to the outputfile
    String mod = module.toLowerCase();
    copyFileToJarfile(helpTextFileName, null, mod + ".ht");
    copyFileToJarfile(dbBaseFileName, null, mod + ".db");
    copyFileToJarfile(keyWordFileName, null, mod + ".key");

    // delete temporary files
    helpTextFile.delete();
    dbBaseFile.delete();
    keyWordFile.delete();

    if (indexDirFile != null) {
      File[] indexFiles = indexDirFile.listFiles();
      for (int k = 0; k < indexFiles.length; ++k)
        copyFileToJarfile(
          indexFiles[k].getAbsolutePath(),
          mod + ".idx",
          indexFiles[k].getName());
    }

    /////////////////////////////////////////////////////////////////////////
    // last, all files which should be copied into the jarFile
    /////////////////////////////////////////////////////////////////////////

    Enumeration enumer = additionalFiles.keys();
    while (enumer.hasMoreElements()) {
      String additionalFileKey = (String) enumer.nextElement();
      String additionalFileName =
        (String) additionalFiles.get(additionalFileKey);
      copyFileToJarfile(additionalFileName, null, additionalFileKey);
    }

    /////////////////////////////////////////////////////////////////////////
    /// close the zipfile
    ///////////////////////////////////////////////////////////////////////// 

    try {
      jarOutputStream.close();
    } catch (IOException e1) {
    }

    /////////////////////////////////////////////////////////////////////////
    /// rename to final name
    /////////////////////////////////////////////////////////////////////////
        File outFile = new File(outputFile);
        if ( outFile.exists() ) {
            if ( !outFile.delete() ) {
          System.err.println(
            "can't delete file '"
              + outputFile
              + "'");
          System.exit(1);
            }
        }
        if ( !outTmpFile.renameTo(outFile) ) {
      System.err.println(
        "can't rename file '"
          + outputTmpFile
          + "'");
      System.exit(1);
        }

        

    /////////////////////////////////////////////////////////////////////////
    /// remove temprary directory for index creation
    /////////////////////////////////////////////////////////////////////////

    if (!helpFiles.isEmpty()) {
      if (!removeTempDirectory(indexDirParentName)) {
        System.err.println(
          "can't remove temporary directory '"
            + indexDirParentName
            + "'");
        System.exit(1);
      }
    }

       
  }

  private void copyFileToJarfile(
    String fileName,
    String directory,
    String name)
    throws IOException {
    // now copy the databases into memory, so we will be able to add it to the outputfile
    int n = 0;
    FileInputStream filInputStream = new FileInputStream(fileName);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] b = new byte[1024];
    while ((n = filInputStream.read(b)) != -1)
      baos.write(b, 0, n);
    filInputStream.close();
    addEntryToJarFile(directory, name, baos.toByteArray());
  }

  private void addBookmark(
    Db dbBase,
    String hid,
    byte[] fileB,
    byte[] anchorB,
    byte[] jarfileB,
    byte[] titleB)
    throws DbException, UnsupportedEncodingException {

    String translatedHid =
      (String) hidlistTranslation.get(
        hid.toUpperCase().replace(':', '_'));
    if (translatedHid != null)
      hid = translatedHid;
    hid = URLEncoder.encode(hid);
    Dbt key = new Dbt(hid.getBytes("UTF8"));

    int fileLen = fileB.length;
    if (anchorB != null)
      fileLen += (1 + anchorB.length);
    int dataLen = 1 + fileLen + 1 + jarfileB.length + 1 + titleB.length;
    byte[] dataB = new byte[dataLen];
    int i = 0;
    dataB[i++] = (byte) fileLen;
    for (int j = 0; j < fileB.length; ++j)
      dataB[i++] = fileB[j];
    if (anchorB != null) {
      dataB[i++] = '#';
      for (int j = 0; j < anchorB.length; ++j)
        dataB[i++] = anchorB[j];
    }
    dataB[i++] = (byte) jarfileB.length;
    for (int j = 0; j < jarfileB.length; ++j)
      dataB[i++] = jarfileB[j];

    dataB[i++] = (byte) titleB.length;
    for (int j = 0; j < titleB.length; ++j)
      dataB[i++] = titleB[j];
    Dbt data = new Dbt(dataB);
    dbBase.put(null, key, data, 0);
  }

  private void addEntryToJarFile(
    String prefix,
    String entryName,
    byte[] bytesToAdd) {
    if (bytesToAdd == null)
      return;
    try {
      CRC32 crc = new CRC32();
      crc.update(bytesToAdd);
      JarEntry ze =
        new JarEntry(
          prefix != null ? prefix + "/" + entryName : entryName);
      ze.setCrc(crc.getValue());
      ze.setSize(bytesToAdd.length);
      ze.setMethod(JarEntry.DEFLATED);
      jarOutputStream.putNextEntry(ze);
      if (bytesToAdd.length > 0)
        jarOutputStream.write(bytesToAdd);
      jarOutputStream.closeEntry();
    } catch (IOException e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  /**
   * @param outputFile
   * @param module
   * @param lang
   * @param hid
   * @param helpFiles
   * @param additionalFiles
   */

  private HelpURLStreamHandlerFactory urlHandler = null;

  public HelpLinker(
    String sourceRoot,
    String embeddStylesheet,
    String indexStylesheet,
    String outputFile,
    String module,
    String lang,
    String hid,
    HashSet helpFiles,
    Hashtable additionalFiles) {

    this.sourceRoot = sourceRoot;
    this.embeddStylesheet = embeddStylesheet;
    this.indexStylesheet = indexStylesheet;
    this.outputFile = outputFile;
    this.module = module;
    this.lang = lang;
    this.hid = hid;
    this.helpFiles = helpFiles;
    this.additionalFiles = additionalFiles;
  }
}

// vnd.sun.star.help://swriter/52821?Language=en-US&System=UNIX
TOP

Related Classes of com.sun.star.help.HelpLinker

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.