Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package org.apache.catalina.ssi;
 
 
 import static org.jboss.web.CatalinaMessages.MESSAGES;
 
 import java.io.Reader;
The entry point to SSI processing. This class does the actual parsing, delegating to the SSIMediator, SSICommand, and SSIExternalResolver as necessary[

Author(s):
Dan Sandberg
David Becker
Version:
$Id: SSIProcessor.java 1534 2010-08-18 12:40:08Z remy.maucherat@jboss.com $
 
 public class SSIProcessor {
    
The start pattern
 
     protected final static String COMMAND_START = "<!--#";
    
The end pattern
 
     protected final static String COMMAND_END = "-->";
     protected final static int BUFFER_SIZE = 4096;
     protected HashMap<String,SSICommandcommands =
         new HashMap<String,SSICommand>();
     protected int debug;
     protected final boolean allowExec;
 
 
     public SSIProcessor(SSIExternalResolver ssiExternalResolverint debug,
             boolean allowExec) {
         this. = ssiExternalResolver;
         this. = debug;
         this. = allowExec;
         addBuiltinCommands();
     }
 
 
     protected void addBuiltinCommands() {
         addCommand("config"new SSIConfig());
         addCommand("echo"new SSIEcho());
         if () {
             addCommand("exec"new SSIExec());
         }
         addCommand("include"new SSIInclude());
         addCommand("flastmod"new SSIFlastmod());
         addCommand("fsize"new SSIFsize());
         addCommand("printenv"new SSIPrintenv());
         addCommand("set"new SSISet());
         SSIConditional ssiConditional = new SSIConditional();
         addCommand("if"ssiConditional);
         addCommand("elif"ssiConditional);
         addCommand("endif"ssiConditional);
         addCommand("else"ssiConditional);
     }
 
 
     public void addCommand(String nameSSICommand command) {
         .put(namecommand);
     }


    
Process a file with server-side commands, reading from reader and writing the processed version to writer. NOTE: We really should be doing this in a streaming way rather than converting it to an array first.

Parameters:
reader the reader to read the file containing SSIs from
writer the writer to write the file with the SSIs processed.
Returns:
the most current modified date resulting from any SSI commands
Throws:
java.io.IOException when things go horribly awry. Should be unlikely since the SSICommand usually catches 'normal' IOExceptions.
 
    public long process(Reader readerlong lastModifiedDate,
            PrintWriter writerthrows IOException {
        SSIMediator ssiMediator = new SSIMediator(,
                lastModifiedDate);
        StringWriter stringWriter = new StringWriter();
        IOTools.flow(readerstringWriter);
        String fileContents = stringWriter.toString();
        stringWriter = null;
        int index = 0;
        boolean inside = false;
        StringBuilder command = new StringBuilder();
        try {
            while (index < fileContents.length()) {
                char c = fileContents.charAt(index);
                if (!inside) {
                    if (c == .charAt(0)
                            && charCmp(fileContentsindex)) {
                        inside = true;
                        index += .length();
                        command.setLength(0); //clear the command string
                    } else {
                        if (!ssiMediator.getConditionalState().) {
                            writer.write(c);
                        }
                        index++;
                    }
                } else {
                    if (c == .charAt(0)
                            && charCmp(fileContentsindex)) {
                        inside = false;
                        index += .length();
                        String strCmd = parseCmd(command);
                        if ( > 0) {
                            .log(
                                    "SSIProcessor.process -- processing command: "
                                            + strCmdnull);
                        }
                        String[] paramNames = parseParamNames(commandstrCmd
                                .length());
                        String[] paramValues = parseParamValues(command,
                                strCmd.length(), paramNames.length);
                        //We need to fetch this value each time, since it may
                        // change
                        // during the loop
                        String configErrMsg = ssiMediator.getConfigErrMsg();
                        SSICommand ssiCommand =
                            .get(strCmd.toLowerCase(.));
                        String errorMessage = null;
                        if (ssiCommand == null) {
                            errorMessage = .ssiUnknownCommand(strCmd);
                        } else if (paramValues == null) {
                            errorMessage = .ssiParsingErrorNoParameters(strCmd);
                        } else if (paramNames.length != paramValues.length) {
                            errorMessage = .ssiParsingErrorBadParameterCount(strCmd);
                        } else {
                            // don't process the command if we are processing
                            // conditional
                            // commands only and the
                            // command is not conditional
                            if (!ssiMediator.getConditionalState().
                                    || ssiCommand instanceof SSIConditional) {
                                long lmd = ssiCommand.process(ssiMediatorstrCmd,
                                               paramNamesparamValueswriter);
                                if (lmd > lastModifiedDate) {
                                    lastModifiedDate = lmd;
                                }                                    
                            }
                        }
                        if (errorMessage != null) {
                            .log(errorMessagenull);
                            writer.write(configErrMsg);
                        }
                    } else {
                        command.append(c);
                        index++;
                    }
                }
            }
        } catch (SSIStopProcessingException e) {
            //If we are here, then we have already stopped processing, so all
            // is good
        }
        return lastModifiedDate;
    }


    
Parse a StringBuilder and take out the param type token. Called from requestHandler

Parameters:
cmd a value of type 'StringBuilder'
Returns:
a value of type 'String[]'
    protected String[] parseParamNames(StringBuilder cmdint start) {
        int bIdx = start;
        int i = 0;
        int quotes = 0;
        boolean inside = false;
        StringBuilder retBuf = new StringBuilder();
        while (bIdx < cmd.length()) {
            if (!inside) {
                while (bIdx < cmd.length() && isSpace(cmd.charAt(bIdx)))
                    bIdx++;
                if (bIdx >= cmd.length()) break;
                inside = !inside;
            } else {
                while (bIdx < cmd.length() && cmd.charAt(bIdx) != '=') {
                    retBuf.append(cmd.charAt(bIdx));
                    bIdx++;
                }
                retBuf.append('=');
                inside = !inside;
                quotes = 0;
                boolean escaped = false;
                for (; bIdx < cmd.length() && quotes != 2; bIdx++) {
                    char c = cmd.charAt(bIdx);
                    // Need to skip escaped characters
                    if (c == '\\' && !escaped) {
                        escaped = true;
                        continue;
                    }
                    if (c == '"' && !escapedquotes++;
                    escaped = false;
                }
            }
        }
        StringTokenizer str = new StringTokenizer(retBuf.toString(), "=");
        String[] retString = new String[str.countTokens()];
        while (str.hasMoreTokens()) {
            retString[i++] = str.nextToken().trim();
        }
        return retString;
    }


    
Parse a StringBuilder and take out the param token. Called from requestHandler

Parameters:
cmd a value of type 'StringBuilder'
Returns:
a value of type 'String[]'
    protected String[] parseParamValues(StringBuilder cmdint startint count) {
        int valIndex = 0;
        boolean inside = false;
        String[] vals = new String[count];
        StringBuilder sb = new StringBuilder();
        char endQuote = 0;
        for (int bIdx = startbIdx < cmd.length(); bIdx++) {
            if (!inside) {
                while (bIdx < cmd.length() && !isQuote(cmd.charAt(bIdx)))
                    bIdx++;
                if (bIdx >= cmd.length()) break;
                inside = !inside;
                endQuote = cmd.charAt(bIdx);
            } else {
                boolean escaped = false;
                for (; bIdx < cmd.length(); bIdx++) {
                    char c = cmd.charAt(bIdx);
                    // Check for escapes
                    if (c == '\\' && !escaped) {
                        escaped = true;
                        continue;
                    }
                    // If we reach the other " then stop
                    if (c == endQuote && !escapedbreak;
                    // Since parsing of attributes and var
                    // substitution is done in separate places,
                    // we need to leave escape in the string
                    if (c == '$' && escapedsb.append('\\');
                    escaped = false;
                    sb.append(c);
                }
                // If we hit the end without seeing a quote
                // the signal an error
                if (bIdx == cmd.length()) return null;
                vals[valIndex++] = sb.toString();
                sb.delete(0, sb.length()); // clear the buffer
                inside = !inside;
            }
        }
        return vals;
    }


    
Parse a StringBuilder and take out the command token. Called from requestHandler

Parameters:
cmd a value of type 'StringBuilder'
Returns:
a value of type 'String', or null if there is none
    private String parseCmd(StringBuilder cmd) {
        int firstLetter = -1;
        int lastLetter = -1;
        for (int i = 0; i < cmd.length(); i++) {
            char c = cmd.charAt(i);
            if (Character.isLetter(c)) {
                if (firstLetter == -1) {
                    firstLetter = i;
                }
                lastLetter = i;
            } else if (isSpace(c)) {
                if (lastLetter > -1) {
                    break;
                }
            } else {
                break;
            }
        }
        String command = null;
        if (firstLetter != -1) {
            command = cmd.substring(firstLetterlastLetter + 1);
        }
        return command;
    }
    protected boolean charCmp(String bufint indexString command) {
        return buf.regionMatches(indexcommand, 0, command.length());
    }
    protected boolean isSpace(char c) {
        return c == ' ' || c == '\n' || c == '\t' || c == '\r';
    }
    
    protected boolean isQuote(char c) {
        return c == '\'' || c == '\"' || c == '`';
    }
New to GrepCode? Check out our FAQ X