Package KFM.preprocessor

Source Code of KFM.preprocessor.AbstractPreprocessor

/*
*  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.
*
*/


//  PropertiesProcessor

// ************ package ******************************************************
package KFM.preprocessor;

// ************ imports ******************************************************
import KFM.HTML.HtmlLoader2;
import java.util.*;
import java.io.*;
import KFM.DirNavigator.*;
import KFM.File.FileUtils;
import KFM.Converter;

/** The AbstractPreprocessor class is the base class for all preprocessors.
* <p> It provides basic functionality for the process of processing jsp-files.
* Usage:<br>
* If you want to write a new Preprocessor, subclass from AbstractPreprocessor and
* provide your own functionality by implementing the abstract methods.<br>
* If you don't want to traverse recursively, call the method setRecursiveMode with
* 'false'. The main method is 'traverse', calling this method will do the whole work for you.
*
*
* @see KFM.preprocessor.PropertiesProcessor
* @see Template-Pattern
*/

public abstract class AbstractPreprocessor implements FileWorker
{
// ************ attributes ******************************************************

    private static boolean mTomcat = true;

    private String mUrl = null; //url to the jsp file
    private String cAlias = null; //the alias of the directory for the tomcat engine
    private String cAliasDirectory = null; //config subdirectory
    public final static String cSeparator = "/"; //file separator
    public final static String cHttpParamMarker = "-Param"; //the prefix of an command line argument that
    //indicates an http parameter
    private boolean mTraverseRecursively = true; //indicates if traversing is done recursively
    private boolean mCommentsOn = false; // indicates if the preprocessed files should have the comments included or not
    //or only for the current directory
    // ************ constants concerning file paths and aliases *************************
    // Note: Think about placing them into config file !!!

    private static File cTempDir;
    public static final String cFilter = ".jsp";
    protected int mErrors = 0;

    // contains mapping "original file name" -> (File) "temporary file"
    private Hashtable mTempFileHash = new Hashtable();

    /**
    * Constructor.
    * @param aServerName the name of the server the tomcat engine runs on
    * @param aServerPort the port number of the tomcat engine
    * @param aTomcatAlias the alias of the current directory of the tomcat engine
    * @param the directory name the tomcat alias refers to.
    */
    public AbstractPreprocessor(
        String aServerName,
        String aServerPort,
        String aTomcatAlias,
        String aAliasDirectory,
        File aTempDir)
    {
        cAlias = aTomcatAlias;
        cAliasDirectory = aAliasDirectory;
        mUrl = "http://" + aServerName + ":" + aServerPort;
        cTempDir = aTempDir;
    }
// ************ abstract methods ******************************************************

    /**
    * Provides the http parameter in properties format the jsp files needs.
    */
    protected abstract Properties getHttpParams();

    /**
    * Implementing this method gives the user the possibility to create
    * his own functionality of computing the path of the new file.
    */
    protected abstract String computeNewFilePath(
        File aFile);

    /**
    * Implementing this method provides a way of filtering the content of the preprocessed file.<br>
    * Here you are given the possibility of changing the file's content.
    *
    * @param aContent the file's content
    * @return the filtered file's content
    */
    protected abstract String filterContent(
        String aContent);




// ************ protected methods ******************************************************

    /**
    * Returns the tomcat alias of the current directory.
    */
    protected String getTomcatAlias()
    {
        return cAlias;
    }

    /**
    * Returns the directory name the tomcat alias refers to.
    */
    protected String getAliasDirectory()
    {
        return cAliasDirectory;
    }



    /**
    * A value of 'false' causes a preprocessing only in the current directory,
    * a value of 'true' causes a recursive traversing starting in the current directory.<br>
    * <b>The default is 'true' (traversing recursively</b>
    */
    protected void setRecursiveMode(boolean aRecursive)
    {
        mTraverseRecursively = aRecursive;
    }

// ************ public methods ******************************************************

    public void workFile(File aFile)
    {
        workFile(aFile, true);
    }

    /**
    * Builds the url to the properties file with all mandantory http - parameters.
    * Executes the file through the HtmlLoader. Stores the result in the users properties directory
    * and cuts the jsp ending.
    */
    public void workFile (File aFile, boolean aDeleteTemp)
    {
        String tPath = aFile.getAbsolutePath();
        //makes the path unix conform
        File tempFile = null;

        String tKey = tPath;

        try{
            long tWorkStart = System.currentTimeMillis();
            if (tPath.endsWith(".jsp")) //only for jsp files
            {
                File tFile = (File) mTempFileHash.get(tKey);
                if(tFile != null) {
                    tPath = tFile.getAbsolutePath();
                    System.out.println("[reusing copy] "+tPath);
                } else {
                    if (mCommentsOn)
                    {
                        tempFile = replaceComments(aFile);
                        tPath = tempFile.getAbsolutePath();
                        System.out.println("replace comments in "+tPath);
                    }
                    else
                    {
                        boolean tooLong = aFile.toString().length() > 50;
                        if(tooLong && mTomcat) {
                            tempFile = createTempFile(aFile);
                            tPath = tempFile.getAbsolutePath();
                            System.out.println("copied to "+tPath);
                        }
                    }
                }

                String tUrl = computeWorkUrl(tPath);
                //append the http parameter to the properties file
                tUrl += getParamString();

                HtmlLoader2 tLoader = new HtmlLoader2(); //because the htmlloader has a memory lead
                //initialize it new for each work file
                //process through jsp engine the file
                tLoader.load(tUrl, 0);
                if (tLoader.getStatusCode() != 200){
                    mErrors ++;
                    printConnectionError(tLoader);
                }
                else
                {
                    //get the content

                    String tContent = tLoader.getContent();

                    String[] tErrorStrings = {
                        "<h1>Error: 500</h1>",
                        "<h1>500 Servlet Exception</h1>"
                    };
                    int tIndex = -1;
                    for(int i = 0; i < tErrorStrings.length; i++) {
                        tIndex = tContent.indexOf(tErrorStrings[i]);
                        if(tIndex != -1) {
                            break;
                        }
                    }
                    if(tIndex != -1) {
                        System.out.println("Error occured on the server side. Please see the tomcat console!");
                        System.out.println(tContent.substring(tIndex));
                        System.out.println("!!!! The file " + aFile.getAbsolutePath() + " will not be stored !!!!");
                        mErrors ++;
                        return;
                    }

                    String tFileContent = filterContent(tContent);

                    //make the file path to the users config directory
                    String tNewFilePath = computeNewFilePath(aFile);

                    storeFile (tFileContent, tNewFilePath);
                    tContent = null;

                }
            }
        }
        catch (java.net.MalformedURLException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (IllegalArgumentException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(tempFile != null) {
                if(aDeleteTemp) {
                    tempFile.delete();
                } else {
                    mTempFileHash.put(tKey, tempFile);
                }
            }
        }
    }

    public void deleteTempFiles()
    {
        Enumeration tEnum = mTempFileHash.keys();
        while(tEnum.hasMoreElements())
        {
            String tKey = (String) tEnum.nextElement();
            File tFile = (File) mTempFileHash.get(tKey);
            tFile.delete();
        }
    }

    public int getErrors()
    {
        return mErrors;
    }

    /**
    * Main method. Traverses the directory tree and processes each jsp-file.
    *
    * @param aStartDir absolute path to the start directory
    */
    public void traverse(String aStartDir)
    {
         DirNavigator tNavigator = new DirNavigator(aStartDir, this);
         if (!mTraverseRecursively)
            tNavigator.unsetRecursively();
         tNavigator.traverse();
         System.out.println(mErrors + " errors occurred on the server side!");
    }

    /**
     * If aCommentsOn is true, then the preprocessed files will have all comments included.
     * The default is false.
     * @param aCommentsOn
     */
    public void setCommentsOn(boolean aCommentsOn)
    {
        mCommentsOn = aCommentsOn;
    }

    /**
    * Initialize the http properties from command line arguments.
    * Here http parameter are marked with '-Param'.
    *
    * @return only the http parameters out of the command line arguments.
    */
    public static Properties initHttpProps(
        Properties aProps)
    {
        Enumeration tKeys =  aProps.keys();
        Properties tProps = new Properties();

        while (tKeys.hasMoreElements())
        {
            String tKey = (String) tKeys.nextElement();
            if (tKey.startsWith(cHttpParamMarker))
            {
                String tValue = aProps.getProperty(tKey);
                tKey = tKey.substring(cHttpParamMarker.length(), tKey.length());
                tProps.put (tKey, tValue);
            }
        }

        return tProps;
    }


// ************ helper methods ******************************************************

    /**
    * Returns the http parameter string.
    */
    protected String getParamString()
    {
        StringBuffer tSb = new StringBuffer();
        String tRetStr = null;

        Properties tParams = getHttpParams();
        Enumeration tEnum = tParams.keys();

        while (tEnum.hasMoreElements())
        {
            String tKey = (String)tEnum.nextElement();
            String tValue = tParams.getProperty(tKey);
            tSb.append(tKey + "=" + tValue);
            if (tEnum.hasMoreElements())
            {
                tSb.append("&");
            }
        }

        tRetStr = tSb.toString();
        if ((tRetStr != null) && (tRetStr.length() > 0))
        {
            tRetStr = "?" + tRetStr;
        }
        return tRetStr;
    }

    /**
     * Replaces all jsp comments in a file with html/js- comments. This is to leave the comments
     * in the target file for debugging. Also all spaces will be left.
     *
     * @param aFile file that has to be converted from jsp comments
     * @return a new temp file with replaced comments (stored in o:/KFM = our jsp-temp directory).
     */
    protected static File replaceComments(File aFile)
    {
        String cJspCommentStart = "<%--"; // begin of a jsp comment
        String cJspCommentEnd = "--%>"; // end of a jsp comment
        String cHtmlCommentStart = "<!-- "; // begin of a html comment to replace
        String cHtmlCommentEnd =  " -->"; // end of a html comment to replace
        String cJsCommentStart = "/* "; // begin of a html comment to replace
        String cJsCommentEnd =  " */"; // end of a html comment to replace

        String cInclude = "<%@ include"; // marks a file to be included

        BufferedReader tReader = null; // reads the content of the source file
        BufferedWriter tWriter = null; // writes the content of the target file

        File tFile = aFile;
        String tPath = aFile.getAbsolutePath();

        boolean tIsJsFile = false;
        if (tPath.toUpperCase().endsWith("JS.JSP"))
            tIsJsFile = true;
        try
        {
            tReader = new BufferedReader(new FileReader(aFile));
            String tFileName = aFile.getName();

            // Creates the new temp file
            tFile = new File ("/home/sipdev/KFM/" + tFileName);
            tWriter = new BufferedWriter(new FileWriter(tFile));
            String tStr = null;

            int tScriptIndex = -1;
            String tCommentStr = "";

            // read the content of the file
            while ((tStr = tReader.readLine()) != null)
            {
                // check the current line if there are comments or includes
                int tIndex = 0; // index in the current string to start searching
                int tMin = tStr.length(); // next occurrence of comment or include
                                          // = minimum of tStartIndex, tEndIndex and tIncludeIndex
                int tStartIndex = 0; // next occurrence of jsp start comment
                int tEndIndex = 0; // next occurrence of jsp end comment
                int tIncludeIndex = 0; // next occurrence of include

                // A html file can contain javascript sequences.
                // In such a sequence the comments should be escaped by js-comments.

                if (tScriptIndex != -1)
                {
                    // start javascript was found a number of lines before, now find if there is a end javascript.
                    if (tStr.toUpperCase().indexOf("</SCRIPT>") != -1)
                        tScriptIndex = -1; // js at end
                        tIsJsFile = false;
                }
                else
                {
                    tScriptIndex = tStr.toUpperCase().indexOf("<SCRIPT");
                     // start javascript found in this line, now find if there is a end javascript tag in this line.
                    if (tStr.toUpperCase().indexOf("</SCRIPT>") != -1)
                    {
                        tScriptIndex = -1; // js at end
                        tIsJsFile = false;
                    }
                }

                // inside a js comment
                if (tScriptIndex != -1)
                {
                    tIsJsFile = true;
                }

                String tTempStr = ""; // holds the content of a comment to write out
                boolean tCommentIsWorked = false; // indicator if a comment is written out in this loop
                while (tIndex != -1) // while comments or includes are found
                {
                    tMin = tStr.length();
                    // jsp start comment found
                    if ((tStartIndex = tStr.indexOf(cJspCommentStart, tIndex)) != -1)
                    {
                        // check if to set the minimum
                        if (tStartIndex  < tMin)
                            tMin = tStartIndex;
                    }

                    // jsp end comment found
                    if ((tEndIndex = tStr.indexOf(cJspCommentEnd, tIndex)) != -1)
                    {
                        // check if to set the minimum
                        if (tEndIndex  < tMin)
                            tMin = tEndIndex;
                    }

                    // jsp include found
                    if ((tIncludeIndex = tStr.indexOf(cInclude, tIndex)) != -1)
                    {
                        // check if to set the minimum
                        if (tIncludeIndex  < tMin)
                            tMin = tIncludeIndex;
                    }

                    if (tIncludeIndex == -1 && tEndIndex == -1 && tStartIndex == -1)
                    {
                        break; // no more strings found to replace, so handle next line
                    }

                    if (tMin == tStartIndex)
                    {
                        tCommentStr += tStr; // Append only the start line
                        tCommentIsWorked = false;
                    }
                    else if (tMin == tEndIndex)
                    {
                        // End of comment reached.
                        // tCommentStr contains the piece of code surrounded by comments.
                        // First check if there are jsp tags inside.
                        // In this case don't replace the comments because then the
                        // tags will be processed.
                        //
                        // Otherwise replace the start and end comments by html or js comments.
                        if (tStr.indexOf(cJspCommentStart) == -1)
                            tCommentStr += tStr; // Append string only because the start index is not appended.
                                                 // Else it will be appended twice.
                        tCommentIsWorked = true;
                        if (tCommentStr.indexOf("<sip:") != -1)
                        {
                            tWriter.write(tCommentStr); // write the comment as it is because it includes Jsp-Tags
                            tWriter.newLine();
                            tCommentStr = ""; // Initialize for next iteration
                        }
                        else
                        {
                            {
                                tStartIndex = tCommentStr.indexOf(cJspCommentStart);
                                // handle start comments
                                String tEnd = "";

                                // extract end of line
                                if (tStartIndex + cJspCommentStart.length() < tCommentStr.length())
                                    tEnd = tCommentStr.substring(tStartIndex + cJspCommentStart.length(), tCommentStr.length());
                                tTempStr = tCommentStr.substring(0, tStartIndex);

                                if (tIsJsFile)
                                    tTempStr += cJsCommentStart;
                                else tTempStr += cHtmlCommentStart;
                                // append end of line
                                tTempStr += tEnd;
                            }
                            {
                                tEndIndex = tCommentStr.indexOf(cJspCommentEnd);
                                // handle end comments
                                String tEnd = "";
                                // extract end of line
                                if (tEndIndex + cJspCommentEnd.length() < tTempStr.length())
                                    tEnd = tTempStr.substring(tEndIndex + cJspCommentEnd.length() + 1, tTempStr.length());
                                tTempStr = tTempStr.substring(0, tEndIndex);
                                if (tIsJsFile)
                                    tTempStr += cJsCommentEnd;
                                else tTempStr += cHtmlCommentEnd;
                                // append end of line
                                tTempStr += tEnd;
                            }
                        }

                        tWriter.write(tTempStr);
                        tWriter.newLine();
                        tCommentStr = "";
                    }
                    else if (tMin == tIncludeIndex)
                    {
                         // handle includes
                         // before each include a comment marking the start of the include will be inserted
                         // and after each include a comment marking the end of the include
                         //
                         // Because there is no other code in a include line, we break out of the while loop to
                         // handle the next line.
                         String tSrc = tStr;
                         String tmpStr =  tStr.substring(tIncludeIndex + cInclude.length(), tStr.length());
                         tmpStr = tmpStr.substring(0, tmpStr.indexOf("%>"));

                         if (tIsJsFile)
                            tStr = cJsCommentStart;
                         else tStr = cHtmlCommentStart;

                         tStr += " Start include "
                            + tmpStr;

                         if (tIsJsFile)
                            tStr += cJsCommentEnd;
                         else tStr += cHtmlCommentEnd;

                         tStr += "\n"
                            + tSrc
                            + "\n";

                         if (tIsJsFile)
                            tStr += cJsCommentStart;
                         else tStr += cHtmlCommentStart;
                         tStr +=  " End include "
                            + tmpStr;

                        if (tIsJsFile)
                            tStr += cJsCommentEnd;
                        else tStr += cHtmlCommentEnd;
                        break;
                    }

                    // comment found, increase index
                    if (tMin != tStr.length())
                        tIndex = tMin + 1;
                    else tIndex = -1;
                }

                if (tCommentIsWorked) // Comment is ready. Reeinititialize tCommentStr.
                {
                    tCommentStr = "";
                    tCommentIsWorked = false; // next iteration
                }
                else if (tCommentStr.length() == 0) // Not inside a comment, write out
                {
                    tWriter.write(tStr)// write content
                    tWriter.newLine();
                }
                else if (tCommentStr.length() > 0 && tStr.toUpperCase().indexOf(cJspCommentStart) == -1)
                {
                    // The string doesn't contain a start tag so append the string
                    // because it is inside a comment.
                    tCommentStr += tStr + "\n";
                }
           }
            tReader.close();
            tWriter.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try{
                if (tReader != null)
                    tReader.close();
                if (tWriter != null)
                    tWriter.close();
            }
            catch (IOException e)
            {
                // ignore
            }
        }
        return tFile;
    }


    /**
    * Stores the new file content in a new file.
    *
    * @param aContent the new file's content
    * @param aNewFilePath the absolute path of the new file
    */
    private void storeFile(
        String aContent,
        String aNewFilePath)
        throws IOException
    {
        int tIndex;
        aNewFilePath = aNewFilePath.replace('\\', '/');
        if ((tIndex = aNewFilePath.indexOf(".jsp")) != -1)
            aNewFilePath = aNewFilePath.substring(0, tIndex);
        //first create directory
        File tDir = new File(aNewFilePath.substring(0, aNewFilePath.lastIndexOf("/")));
        if (!tDir.exists())
            tDir.mkdirs();
        File tNewFile = new File (aNewFilePath);
        if (tNewFile.exists())
            tNewFile.delete();
        StringTokenizer tTokenizer = new StringTokenizer(aContent, "\n");
        BufferedWriter tWriter = null;
        try{
        tWriter = new BufferedWriter (new FileWriter(tNewFile));
        while (tTokenizer.hasMoreTokens())
        {
            String tNext = tTokenizer.nextToken();

            // if comments on write all newlines and spaces out, else eliminate them
            if (!mCommentsOn)
            {
                tNext = tNext.trim();
            }
            tWriter.write(tNext);
            tWriter.newLine();
        }
        }
        finally
        {
            if (tWriter != null)
            {
                try{
                    tWriter.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }

            }
        }
    }

    /**
    * Builds the url for the tomcat alias to the current file without
    * http parameters
    *
    * @param aAbsolutePath the absolute path to the current file.
    */
    private String computeWorkUrl(String aAbsolutePath)
    {

        //build the jsp alias for the tomcat engine
        aAbsolutePath = aAbsolutePath.replace('\\', '/');
        int index = aAbsolutePath.indexOf(cAliasDirectory);
        if (index  != -1)
        {
            aAbsolutePath = aAbsolutePath.substring(index + cAliasDirectory.length(), aAbsolutePath.length());
            aAbsolutePath = cAlias + aAbsolutePath;
        }
        else {
            //default
            String tFileName = aAbsolutePath.substring(aAbsolutePath.lastIndexOf("/"), aAbsolutePath.length());
            aAbsolutePath = "temp" + tFileName;
        }
        /* @@@ JD: No checking for Tomcat Aliases or not. Temp Alias is Default. Anything else is not
               considered currently. I don't see a quick way to implement a checking. Posponed.
        else
        {
            throw new IllegalArgumentException ("Your path " + aAbsolutePath
            + " don't match to the alias directory " + cAliasDirectory + " for tomcat !");
        }
        */
        String tUrl = mUrl + cSeparator + aAbsolutePath;
        return tUrl;
    }

    /**
    * Prints an error message to standard out if the processing caused an error.
    */
    private void printConnectionError(HtmlLoader2 aLoader)
    {
        //indicates an error on server side. The file will not be saved and the user will be informed!
        System.out.println("ERROR occured on server side. The file will not be stored:");
        System.out.println(aLoader.getContent());
    }

      /**
    * Creates a temporary file if the filename is bigger than 26 characters.
    * In this case tomcat would throw an error.
    * The same behaviour occures if the path name is too big. Therefore the temporary file
    * will be stored in the /KFM/ directory.
    *
    * @return File null if no tempfile was necessary
    */
    private File createTempFile(File aFile)
        throws IOException
    {
        File tTempFile = new File(cTempDir, System.currentTimeMillis() + ".jsp");
        FileUtils.copy(aFile, tTempFile);
        return tTempFile;
    }

    /**
     * @param boolean aTomcat true, if you are using tomcat, false otherwise
     */
    public static void setTomcat(boolean aTomcat)
    {
        mTomcat = aTomcat;
    }



}
TOP

Related Classes of KFM.preprocessor.AbstractPreprocessor

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.