Package KFM.GUI.Templates

Source Code of KFM.GUI.Templates.Template

/*
*  This software and supporting documentation were developed by
*
*    Siemens Corporate Technology
*    Competence Center Knowledge Management and Business Transformation
*    D-81730 Munich, Germany
*
*    Authors (representing a really great team ;-) )
*            Stefan B. Augustin, Thorbj�rn Hansen, Manfred Langen
*
*  This software is Open Source under GNU General Public License (GPL).
*  Read the text of this license in LICENSE.TXT
*  or look at www.opensource.org/licenses/
*
*  Once more we emphasize, that:
*  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  WITHOUT ANY WARRANTY
*  REGARDING  THE  SOFTWARE,  ITS  PERFORMANCE OR
*  FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES OR
*  ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND
*  PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
*
*/


// Template

// ************ package ******************************************************
package KFM.GUI.Templates;

// ************ imports ******************************************************
import java.io.*;
import java.lang.String;
import java.util.Properties;

import KFM.Exceptions.ProgrammerException;
import KFM.*;
import KFM.Language;
import KFM.RegExp;
import KFM.log.*;


import com.oroinc.text.regex.MatchResult;       // Get rid of this when it is included in RegExp.

/** HTML Template which implements additional HTML elements that are executed on the server.
*
* <H2>Still to do</H2>
*
* <P>Since 2000-03-06, `write� and `writeToString� set `html=null�, hoping to reduce memory usage.
* Now only exactly one of `write� or `writeToString� may be called, and only once!</P>
*
* <P>Implement the observer. Each template must register at an observer so that the observer may call the
* template�s `clearCache�.</P>
*
* <P>When we extend this class�s functionality, we might need to register labels (`registerKfm� and
* `registerKfmIf�) and parse the template before modifying it (`parse�).</P>
*
* <H2>Supported element types</H2>
*
* <P>You can extend HTML with two kinds of element types: KfmIf and Kfm. Their BNF is as follows:
*
* <PRE>
*   KfmIf      := &lt;"KfmIf" Label            "&gt;" Content "&lt;/KfmIf&gt;"
*   Kfm        := "&lt;Kfm"   Label Attributes "&gt;" Content "&lt;/KfmIf&gt;"
* where
*   Label      := Attribute
*   Attributes := ( Attribute "=" Quote Value Quote )*
*   Quote      := "\"" | "'"
* </PRE>
*
* Note: Since 99-11-24, we can quote with double or single quotes. Contrary to the case in HTML
* a single quote is not allowed inside double quotes, nor the other way around. (This only
* concerns KFM labels, not ordinary HTML tags.)
*
* The first attribute is the label, without a value. Following values must have values.
* A value must be quoted and may not contain a quote nor a ">", use the "&...;" escape syntax.</P>
*
* <P>IMPORTANT NOTE: Currently, the element types KfmIf and Kfm may not be nested!</P>
*
* <H2>Usage</H2>
*
* <P>First create a template. Every time you want to display the template, call `startWithLanguage. The
* first time you call `startWithLanguage� for any language, the template is loaded from file and cached.
* After that, the template is fetched from the cache. `startWithLanguage� will also copy the template into
* the working buffer.</P>
*
* <P>To evaluate the KfmIf elements in the working buffer, use `replaceKfmIf�. To evaluate the Kfm elements
* in the working buffer use `getKfmParam� to get the parameter values and `replaceKfm� to replace the
* element by the text you have calculated.</P>
*
* <P>Before 2000-03-06: You may use `toString� or `write� at any time to get the current working buffer as
* string or to write it to a stream. Since 2000-03-06, `write� and `writeToString� set `html=null�, hoping
* to reduce memory usage. Now only exactly one of `write� or `writeToString� may be called, and only
* once!</P>
*
* <A NAME="debug-behaviour"><H2>Debug behaviour</H2></A>
*
* <P>In debug mode, the `replace*� methods mark evaluated Kfm- and KfmIf-commands with comments, for
* example
*   <CODE>&lt;KFM A B="b"&gt;Old content&lt;/KFM&gt;</CODE>
* is replaced by
*   <CODE>&lt;!--KFM A B="b"--&gt;New content&lt;!--/KFM--&gt;</CODE>.</P>
* <P>In debug mode, The `check� method marks all left-over Kfm- and KfmIf-commands in red.</P>
*
* <H2>Definitions for HTML</H2>
*
* <P>See <A HREF="http://www.w3.org/TR/REC-html40/intro/sgmltut.html#h-3.2">SGML constructs used in
* HTML</A> from the W3Cs document for HTML for correct definitions of words. A summary follws.</P>
*
* <P>In the example <CODE>&lt;NAME ATTR="VALUE"&gt;CONTENT&lt;/NAME&gt;</CODE> we have the following:</P>
*
* <DL>
* <DT> element name<DD> <CODE>NAME</CODE>
* <DT> element type<DD> the type of the element, like types/classes/signatures in programming languages
*                       (which attributes it accepts etc.)
* <DT> element     <DD> <CODE>&lt;NAME ATTR="VALUE"&gt;CONTENT&lt;/NAME&gt;</CODE>
* <DT> start tag   <DD> <CODE>&lt;NAME ATTR="VALUE"&gt;</CODE>
* <DT> end tag     <DD> <CODE>&lt;/NAME&gt;</CODE>
* <DT> attribute   <DD> <CODE>ATTR</CODE>
* <DT> value (of attribute <CODE>ATTR</CODE>)
*                  <DD> <CODE>VALUE</CODE> (without the quotes)
* <DT> content     <DD> <CODE>CONTENT</CODE>
* </DL>
*
* <P>Convention: A Kfm element with label CMD is a Kfm-command CMD, a KfmIf element with label IF is a
* KfmIf-command IF.</P>
*
* <H2>Related classes</H2>
*
* @see IText
* see IText           -- Internationalized Text.
*
* @see ComplexTemplate
* see ComplexTemplate -- Powerful Template with complex interface.
*
* <pre>
* ====================
* History:
*    creation date: 99.02.26
* --------------------
* Changes:
*    <none>
* </pre>
*
* @version 1.0 (99.02.27)
*
*/
public class Template {

    //
    // Constants
    //

    /**
     * File extension of a template.
     */
    public static final String templateExtension = ".kfmt.htm";

    //
    // Variables
    //

    /**
     * current language.
     *
     */
    protected Language currentLanguage;

    /**
     * Name prefix.
     *
     * E.g. "NewProposal" for a template file
     *   "NewProposal." + Language + templateExtension
     * for example "NewProposal.German.kfmt.htm".
     */
    protected String namePrefix;

    /**
     * Directory that contains files with prefix `namePrefix�.
     */
    protected String dir;

    /**
     * Working buffer (text that to be output by `write� or `toString�).
     *
     * Note: The type should be something that handles replacement more efficiently than a `String�. But the
     * only candidate we know is `StringBuffer�, which does not allow replacement.
     */
    protected String html;

    /**
     * If this template has already been loaded for a language, it is cached here.
     *
     * Use `Language.toString()� for keys, the property is the template as a string.
     */
    protected Properties cache; // languagename -> template

    /**
     * Record debug behaviour vs release behaviour.
     *
     * See <A HREF="#debug-behaviour">debug behaviour</A> in header.
     */
    protected boolean debug = false;

    /**
     * Is true iff `markCommandsLeft(true)� is running.
     *
     * Means that found Kfm- and KfmIf-commands should be marked, that is made visible and red (for debugging).
     */
    protected boolean domark = false;

    /** Log file. */
    protected KFMLog mLog = null;

    //
    // Methods
    //

    /**
     * Prepare a template without loading it.
     *
     * @param theNamePrefix  E.g. "NewProposal" for a template file
     *                      "NewProposal." + Language + templateExtension
     *                      for example "NewProposal.German.kfmt.htm".
     */
    public Template(/* TemplateObserver observer,*/ String theDir, String theNamePrefix)
    {
        namePrefix = theNamePrefix;
        dir = theDir;
        cache = new Properties();
    }

    /**
     * Prepare a template without loading it. This constructor supporting new log concept.
     *
     * @param theNamePrefix  E.g. "NewProposal" for a template file
     *                      "NewProposal." + Language + templateExtension
     *                      for example "NewProposal.German.kfmt.htm".
     */
    public Template(/* TemplateObserver observer,*/ String theDir, String theNamePrefix, KFMLog aLog)
    {
        this(theDir, theNamePrefix);
        mLog = aLog;
    }


    /**
     * Clear cache with templates in different languages.
     */
    public void clearCache () {
        cache.clear();
    }

    /** for subclasses to initialize when the template is started to be used. */
    public void init()
    {
        // @@@ nothing, all is done by startWithLanguage... please refactor
    }

    /**
     * Instantiate working buffer, if neccessary load language specific template from file and cache it.
     *
     * On success, writes the template into the working buffer `html�. On fail, the working buffer `html� is
     * not initialized. Note: In Java, a `String� is not modifyable. If you modify a `String� variable, you
     * get a new object and the old object is not modified. That means that you can modify `html� without
     * changing the contents in the cache.
     *
     * If the template is not found in the requested language, try to get it in German.
     *
     *@return  Whether the template was found.
     */
    public boolean startWithLanguage (Language language)
    {
        try {
            if(! cache.containsKey(language.toString())) {
                String templateFileName = dir + "/" + namePrefix + "." + language.toString() + templateExtension;
                if (mLog == null) {
                    KFMSystem.log.info("Template::StartWithLanguage: Try to load file \""
                                 + templateFileName + "\" and put it into the cache.");
                } else {
                    mLog.info("Template::StartWithLanguage: Try to load file \""
                              + templateFileName + "\" and put it into the cache.");
                }

                //
                // * Read from file.
                //
                // @@@ Should be in a convenience function somewhere.
                BufferedReader in = new BufferedReader(new FileReader(templateFileName));
                StringBuffer inBuf = new StringBuffer();
                String line;
                readline: while(true) {
                    line = in.readLine();
                    if(line == null) break readline;
                    inBuf.append(line);
                    inBuf.append('\n');
                }
                in.close();
                cache.put(language.toString(),
                          "<!-- START TEMPLATE FILE " + templateFileName + "\n -->"
                          + inBuf.toString()
                          + "<!-- END TEMPLATE FILE " + templateFileName + "\n -->");
            }
            html = cache.getProperty(language.toString());

            currentLanguage = language;

            init();

            return true /*success*/;
        } catch(FileNotFoundException e) {
            if(language.isGerman()) {
                if (mLog == null) {
                    KFMSystem.log.info("Template::StartWithLanguage: "
                                    + "Couldn't load file in requested language German.");
                } else {
                    mLog.info("Template::StartWithLanguage: "
                                    + "Couldn't load file in requested language German.");
                }
                // @@@ This is stupid. We should rethrow `FileNotFoundException�.
                return false /*fail*/;
            } else {
                if (mLog == null) {
                    KFMSystem.log.info("Template::StartWithLanguage: Couldn't load file "
                                 + "in requested language, trying German ('de' and 'german').");
                } else {
                    mLog.info("Template::StartWithLanguage: Couldn't load file "
                                 + "in requested language, trying German ('de' and 'german').");
                }
                if(startWithLanguage(new Language("de"))) {
                    return true;
                } else if(startWithLanguage(new Language("german"))) {
                    return true;
                } else {
                    if (mLog == null) {
                        KFMSystem.log.info("Template::StartWithLanguage: "
                                     + "Couldn't load file in requested German.");
                    } else {
                        mLog.info("Template::StartWithLanguage: "
                                     + "Couldn't load file in requested German.");
                    }
                    // @@@ This is stupid. We should rethrow `FileNotFoundException�.
                    return false /*fail*/;
                }
            }
        } catch(IOException e) {
            if (mLog == null) {
                KFMSystem.log.error("Template::StartWithLanguage: IO-Error", e);
            } else {
                mLog.error("Template::StartWithLanguage: IO-Error", e);
            }
            return false /*fail*/;
        }
    }

    /** Write working buffer to an OutputStream, and delete working buffer.
     *
     * We choose OutputStream because it is the parent class of ServletOutputStream.
     *
     * <P>Since 2000-03-06, `write� and `writeToString� set `html=null�, hoping to reduce memory usage.
     * Now only exactly one of `write� or `writeToString� may be called, and only once!</P>
     */
    public void write(OutputStream out) {
        privateCheckHtml();

        PrintWriter pwout = new PrintWriter(out);
        pwout.print(html);
        pwout.flush();
        html = null;
    }

    /**
     * @see write(OutputStream out)
     */
    public void write(PrintWriter aWriter) {
        privateCheckHtml();

        aWriter.print(html);
        aWriter.flush();
        html = null;
    }

    /** Return working buffer as string, and delete working buffer.
     *
     * <P>Since 2000-03-06, `write� and `writeToString� set `html=null�, hoping to reduce memory usage.
     * Now only exactly one of `write� or `writeToString� may be called, and only once!</P>
     *
     * This used to be called `toString�, but that was not a good name,
     * because `toString� should not modify the object at all.
     */
    public String writeToString() {
        privateCheckHtml();

        String tRet = html;
        html = null;
        return tRet;
    }

    /** Return working buffer as string.
     *
     * @deprecated May produce a memory leak, because `html� (which can get really big) might not be deleted.
     * You may still use it for debugging, though.
     */
    public String toString() {
        if (mLog == null) {
            KFMSystem.log.info("Warning: Deprecated method Template::toString called!");
        } else {
            mLog.info("Warning: Deprecated method Template::toString called!");
        }
        privateCheckHtml();
        return html;
    }

    /**
     * Helper that constructs a regexp for `<elemname label [params]>� with optional spaces.
     *
     *@param elemname  Element name, e.g. "Kfm", "KfmIf".
     *@param label     Case insensitive label, e.g. "Date" in "<Kfm Date>". May be a regexp. Must not
     *                 contain whitespace.
     *
     * Note: If you have to insert parenthesises here, use the `(?:...)� notation of Perl5 that means that
     * the parenthesises do not define a match group. If you do not do that, you will have to change the
     * references to match groups in every regexp that uses `cmdPattern�.
     */
    protected static String cmdPattern(String elemname, String label) {
        return "\\<\\s*" + elemname + "\\s+" + label +
            "(?:\\>|\\s+[^>]*\\>)";
    }

    /**
     * Evaluate all occurences of a KfmIf-command.
     *
     * Replace all elements of a KfmIf-command `label�, that is `<KfmIf label [params]>text</KfmIf>�, by
     * `text� or empty string, depending on `keep�.
     *
     *@param label  Case insensitive label, e.g. "Date" in "<Kfm Date>". May be a regexp. Must not contain
     *              whitespace.
     *@return       whether a replacement was performed.
     *
     * For debug behaviour, see <A HREF="#debug-behaviour">debug behaviour</A> in header.
     * For mark behaviour, see ???.
     */
    public boolean replaceAllKfmIf (String label, boolean keep)
    {
        privateCheckHtml();
        boolean replacementOccured = false;
        while(true) {
            // Note: endtagM must be *after* starttagM.
            MatchResult starttagM = RegExp.match(cmdPattern("KfmIf", label), html);
            if(starttagM == null) {
                return replacementOccured;
            }

            int offset = starttagM.endOffset(0);
            String html2 = html.substring(offset);
            MatchResult endtagM = RegExp.match("\\</KfmIf\\s*\\>", html2);
            if(endtagM == null) {
                return replacementOccured;
            }
            replacementOccured = true;
            String replacement = (keep ? html.substring(starttagM.endOffset(0), endtagM.beginOffset(0) + offset) : "" );
            if(domark) {
                //D KFMSystem.log.detail("replaceAllKfmIf: mark!");
                replacement = markTag(starttagM.group(0)) + replacement + markTag(endtagM.group(0));
            }
            if(debug) {
                replacement = commentifyTag(starttagM.group(0)) + replacement + commentifyTag(endtagM.group(0));
            }
            //D KFMSystem.log.detail("Replace of Command KfmIf " + label + ": "
            //D                + html.substring(starttagM.endOffset(0), endtagM.beginOffset(0))
            //D                + " -> " + replacement);
            html = html.substring(0, starttagM.beginOffset(0))
                + replacement
                + html2.substring(endtagM.endOffset(0));
        }
    }

    /**
     * Get a param of first occurence of a Kfm-command.
     *
     * Search for start tag of first Kfm-command `label�, that is `<Kfm label [params] param="value"
     * [params]>� and return `value�. Return empty string when not found.
     *
     *@param label     Case insensitive label, e.g. "Date" in "<Kfm Date>". May be a regexp. Must not
     *                 contain whitespace.
     */
    public String getKfmParam (String label, String param)
    {
        privateCheckHtml();
        //D KFMSystem.log.detail("get: " + label + " " + param);
        MatchResult starttagM = RegExp.match(cmdPattern("Kfm", label), html);
        if(starttagM == null) {
            //D KFMSystem.log.detail("label not found.");
            return "";
        }
        MatchResult valueM = RegExp.match(
            "\\s" + param + "\\s*=\\s*"
            // This will allow something like "...', and does *not* allow embedded ">".
            // Note that "group(1)" does not contain the quotes.
            // + "[\"']([^>\"']*)[\"']"
            // This will allow "...'..." and '..."...' and *does* allow embedded ">".
            // Note that "group(1)" now contains the quotes.
             + "((?:\"[^\"]*\")|(?:'[^']*'))"
            , starttagM.group(0));
        if(valueM == null) {
            //D KFMSystem.log.detail("param not found.");
            return "";
        }
        // Now we must strip the quotes.
        // return valueM.group(1);
        String t = valueM.group(1);
        t = t.replace('�', '>');
        return t.substring(1, t.length()-1);
    }

    /**
     * Evaluate first occurence of a Kfm-command.
     *
     * Replace element of first Kfm-command `label�, that is `<Kfm label [params]>text</Kfm>�, by `replace�.
     *
     * For debug behaviour, see <A HREF="#debug-behaviour">debug behaviour</A> in header.
     * For mark behaviour, see ???.
     *
     *@param label    Case insensitive label, e.g. "Date" in "<Kfm Date>". May be a regexp. Must not contain
     *                whitespace.
     *@param replace  Hack: iff null, keep the current content.
     *
     *@return  whether a replacement was performed.
     */
    public boolean replaceKfm (String label, String replace)
    {
        if(replace == null) {
            // Legacy behaviour.
            return replaceKfm(label, true, "", "");
        } else {
            return replaceKfm(label, false, replace, "");
        }
    }

    /**
     * Evaluate first occurence of a Kfm-command.
     *
     * Replace element of first Kfm-command `label�, that is `<Kfm label [params]>text</Kfm>�, by `replace�.
     *
     * For debug behaviour, see <A HREF="#debug-behaviour">debug behaviour</A> in header.
     * For mark behaviour, see ???.
     *
     *@param label    Case insensitive label, e.g. "Date" in "<Kfm Date>". May be a regexp. Must not contain
     *                whitespace.
     *@param aKeep    Keep the content?
     *@param aBefore  Before the content.
     *@param aAfter   After the content
     *
     *@return  whether a replacement was performed.
     */
    public boolean replaceKfm (String label, boolean aKeep, String aBefore, String aAfter)
    {
        privateCheckHtml();
        // This regexp ensures that start tag is before end tag.
        MatchResult elementM = null;
        String p = "";
        try {
            p = "(" + cmdPattern("Kfm", label) + ")"            /*group 1: start tag*/
    // This seems very suspect (WARNING: it can cause StackOverflow Errors!):
    //            + "((?:.|\\n)*?)"                             /*group 2: content*/
    // lets try: .*?
                + "(.*?)"                                       /*group 2: content replaced*/
                + "(" + "\\</Kfm\\s*\\>" + ")";                 /*group 3: end tag */
            elementM = RegExp.match(p, html, false, true);
        } catch(Error e) {
            mLog.error(
                "Template::replace,RegExp.match caused Error: " + e + "\n"
                + "Arguments: p = '" + p + "'\n"
                + "html = '" + html + "'");
            return false;
        }
        final int starttagI = 1;
        final int contentI  = 2;
        final int endtagI   = 3;

        if(elementM == null) return false;
        String replacement = aBefore + (aKeep ? elementM.group(contentI) : "") + aAfter;
        if(domark) {
            //D KFMSystem.log.detail("replaceKfm: mark!");
            replacement = markTag(elementM.group(starttagI))
                + replacement + markTag(elementM.group(endtagI));
        }
        if(debug) {
            replacement = commentifyTag(elementM.group(starttagI))
                + replacement + commentifyTag(elementM.group(endtagI));
        }
        html = html.substring(0, elementM.beginOffset(0))
            + replacement
            + html.substring(elementM.endOffset(0));
        //D KFMSystem.log.detail("Replace of Command Kfm " + label + ": " + elementM.group(0) + " -> " + replacement);
        return true;
    }

    /**
     * Evaluate all occurences of a Kfm-command.
     *
     * Replace all elements of a Kfm-command `label�, that is `<Kfm label [params]>text</Kfm>�, by `replace�.
     * Only useful for Kfm-commands where you do not need to process parameters.
     *
     * For debug behaviour, see <A HREF="#debug-behaviour">debug behaviour</A> in header.
     * For mark behaviour, see ???.
     *
     *@param label    Case insensitive label, e.g. "Date" in "<Kfm Date>". May be a regexp. Must not contain
     *                whitespace.
     *@param replace  Hack: iff null, keep the current content.
     *
     *@return         whether a replacement was performed.
     */
    public boolean replaceAllKfm (String label, String replace)
    {
        if(replaceKfm(label, replace)) {
            while(replaceKfm(label, replace)) {}
            return true;
        } else {
            return false;
        }
    }

    /**
     * Evaluate all occurences of a Kfm-command.
     *
     * Replace all elements of a Kfm-command `label�, that is `<Kfm label [params]>text</Kfm>�, by `replace�.
     * Only useful for Kfm-commands where you do not need to process parameters.
     *
     * For debug behaviour, see <A HREF="#debug-behaviour">debug behaviour</A> in header.
     * For mark behaviour, see ???.
     *
     *@param label    Case insensitive label, e.g. "Date" in "<Kfm Date>". May be a regexp. Must not contain
     *                whitespace.
     *@param aKeep    Keep the content?
     *@param aBefore  Before the content.
     *@param aAfter   After the content
     *
     *@return         whether a replacement was performed.
     */
    public boolean replaceAllKfm (String label, boolean aKeep, String aBefore, String aAfter)
    {
        if(replaceKfm(label, aKeep, aBefore, aAfter)) {
            while(replaceKfm(label, aKeep, aBefore, aAfter)) {}
            return true;
        } else {
            return false;
        }
    }

    /**
     * In a subclass `S�, define a method `execute� that does all replacements. This function can be called by all
     * subclasses of `S�. I do not think we can give `execute� a definite signature.
     */

    //
    // Debugging functionality
    //

    private void privateCheckHtml()
    {
        if(html == null) {
            throw new ProgrammerException(
                "Class Template: html is null. "
                + "Either you used `write� and `writeToString� more than once, "
                + " or you forgot to call startWithLanguage for '" + dir + "/" + namePrefix);
        }
    }

    /**
     * Set template to debug behaviour or release behaviour.
     *
     * See <A HREF="#debug-behaviour">debug behaviour</A> in header.
     */
    public void setDebug(boolean theDebug)
    {
        debug = theDebug;
    }

    /**
     * Check whether there are Kfm- or KfmIf-commands left.
     */
    public boolean checkCommandsLeft ()
    {
        return markCommandsLeft(false /*do not mark*/);
    }

    /**
     * Check whether there are Kfm- or KfmIf-commands left and always mark them.
     *
     * @see markCommandsLeft
     * see markCommandsLeft(boolean)
     */
    public boolean markCommandsLeft ()
    {
        return markCommandsLeft(true /*do mark*/);
    }

    /**
     * Check whether there are Kfm- or KfmIf-commands left and optionally mark them.
     *
     *@param mark  True iff the Kfm- or KfmIf-commands left should be marked.
     *             Otherwise just compute the return value.
     *
     *@return      True iff there are Kfm- or KfmIf-commands left.
     */
    public boolean markCommandsLeft (boolean mark)
    {
        try {
            boolean replacementOccured;
            domark = mark;
            // Note: "\\S+" matches any label, \\S is non-whitespace.
            replacementOccured = replaceAllKfmIf("\\S+", true /*keep content*/);
            replacementOccured |= replaceAllKfm("\\S+", null /*keep content*/);
            return replacementOccured;
        } finally {
            domark = false;
        }
    }

    /**
     * Make a tag visible and red (for debugging).
     */
    protected String markTag (String tag)
    {
        return "<FONT COLOR=red>" + Converter.quoteHtmlTags(tag) + "</FONT>";
    }

    /**
     * Put a tag into comments (for debugging).
     */
    protected String commentifyTag (String tag)
    {
        return "<!--" + Converter.quoteHtmlTags(tag) + "-->";
    }

    //
    // Usage sample.
    //

    /**
     * Sample of usage.
     */
    public static void main (String args[])
         throws FileNotFoundException, IOException
    {
        Template t = new Template("o:/KFM/java/src/KFM/GUI/Templates/", "sample-template");
        t.setDebug(true);

        //D KFMSystem.log.detail("Lese ein.");
        t.startWithLanguage(Language.German);

        //
        // * Execute substitutions.
        //

        //D KFMSystem.log.detail("Ersetze.");

        t.replaceAllKfmIf("IdeaExists", true);
        t.replaceAllKfmIf("NoIdeaExists", false);

        t.replaceAllKfm("Title", "xxx");
        t.replaceAllKfm("Clients", "yyy");

        // A loop like this will only work correctly when the HTML code is wellformed and follows our restrictions.
        String x, y;
        do {
            x = t.getKfmParam("Point", "x");
            y = t.getKfmParam("Point", "y");
        } while(t.replaceKfm("Point", "(" + x + ", " + y + ")"));

        t.markCommandsLeft();                               // Should find the `<Kfm InsertFormTag>�.

        //D KFMSystem.log.detail("Gebe aus.");
        t.write(System.out);

        //D KFMSystem.log.detail();
        //D KFMSystem.log.detail("Fertig");
    }

    // Test `main� on this file:

    // <!-- sample-template.German.kfmt.html -- >
    //
    // <KfmIf IdeaExists>
    //   <P>Ich bin heute ideenreich.</P>
    // </KfmIf>
    //
    // <KfmIf NoIdeaExists>
    //   <P>Ich bin heute ideenlos.</P>
    // </KfmIf>
    //
    // <P>Ein allgemeiner Punkt ist <Kfm Point x="a" y="b"></Kfm>.
    //    Ein falscher Punkt ist <Kfm Point x="0" y="1" z="2"></Kfm>.
    //    Ein richtiger Punkt ist <Kfm Point y="-y" x="-x"></Kfm>.
    // </P>
    //
    // <Kfm InsertFormTag></Kfm> <!-- Expands to <FORM>. Not handled in this example. -->
    //   <TABLE>
    //     <TR><TD>�berschrift des bilateralen Vorschlags</TD>
    //         <TD><Kfm Title></Kfm></TD></TR>
    //     <TR><TD>Wer sind die potentiellen Kunden?</TD>
    //         <TD><Kfm Clients></Kfm></TD></TR>
    //   </TABLE>
    // </FORM>

}
TOP

Related Classes of KFM.GUI.Templates.Template

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.