Package ognl.helperfunction

Source Code of ognl.helperfunction.WOHelperFunctionDeclarationParser

package ognl.helperfunction;

import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import com.webobjects.appserver.WOAssociation;
import com.webobjects.appserver._private.WOConstantValueAssociation;
import com.webobjects.appserver._private.WODeclaration;
import com.webobjects.appserver._private.WOShared;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSLog;
import com.webobjects.foundation.NSMutableDictionary;
import com.webobjects.foundation._NSStringUtilities;

public class WOHelperFunctionDeclarationParser {
  public static Logger log = Logger.getLogger(WOHelperFunctionDeclarationParser.class);

  private NSMutableDictionary _quotedStrings;
  private static final int STATE_OUTSIDE = 0;
  private static final int STATE_INSIDE_COMMENT = 2;
  private static final String ESCAPED_QUOTE_STRING = "_WO_ESCAPED_QUOTE_";
  private static final String QUOTED_STRING_KEY = "_WODP_";

  static {
    WOHelperFunctionDeclarationParser.log.setLevel(Level.WARN);
  }

  public WOHelperFunctionDeclarationParser() {
    _quotedStrings = new NSMutableDictionary();
  }

  public static NSMutableDictionary declarationsWithString(String declarationStr) throws WOHelperFunctionDeclarationFormatException {
    WOHelperFunctionDeclarationParser declarationParser = new WOHelperFunctionDeclarationParser();
    NSMutableDictionary declarations = declarationParser.parseDeclarations(declarationStr);
    return declarations;
  }

  @Override
  public String toString() {
    return "<WOHelperFunctionDeclarationParser quotedStrings = " + _quotedStrings.toString() + ">";
  }

  public NSMutableDictionary parseDeclarations(String declarationStr) throws WOHelperFunctionDeclarationFormatException {
    String strWithoutComments = _removeOldStyleCommentsFromString(declarationStr);
    strWithoutComments = _removeNewStyleCommentsAndQuotedStringsFromString(strWithoutComments);
    NSMutableDictionary declarations = parseDeclarationsWithoutComments(strWithoutComments);
    return declarations;
  }

  private String _removeOldStyleCommentsFromString(String str) {
    StringBuilder stringbuffer = new StringBuilder(100);
    StringBuilder stringbuffer1 = new StringBuilder(100);
    StringTokenizer tokenizer = new StringTokenizer(str, "/", true);
    int state = WOHelperFunctionDeclarationParser.STATE_OUTSIDE;
    try {
      do {
        if (!tokenizer.hasMoreTokens()) {
          break;
        }
        String token = tokenizer.nextToken();
        switch (state) {
        case STATE_OUTSIDE:
          if (token.equals("/")) {
            token = tokenizer.nextToken();
            if (token.startsWith("*")) {
              state = WOHelperFunctionDeclarationParser.STATE_INSIDE_COMMENT;
              stringbuffer1.append('/');
              stringbuffer1.append(token);
            }
            else {
              stringbuffer.append('/');
              stringbuffer.append(token);
            }
          }
          else {
            stringbuffer.append(token);
          }
          break;

        case STATE_INSIDE_COMMENT:
          stringbuffer1.append(token);
          String s2 = stringbuffer1.toString();
          if (s2.endsWith("*/") && !s2.equals("/*/")) {
            state = WOHelperFunctionDeclarationParser.STATE_OUTSIDE;
          }
          break;
        }
      }
      while (true);
    }
    catch (NoSuchElementException e) {
      log.debug("Parsing failed.", e);
    }
    return stringbuffer.toString();
  }

  private String _removeNewStyleCommentsAndQuotedStringsFromString(String declarationsStr) {
    String escapedQuoteStr = _NSStringUtilities.replaceAllInstancesOfString(declarationsStr, "\\\"", WOHelperFunctionDeclarationParser.ESCAPED_QUOTE_STRING);
    StringBuilder declarationWithoutCommentsBuffer = new StringBuilder(100);
    StringTokenizer tokenizer = new StringTokenizer(escapedQuoteStr, "/\"", true);
    try {
      while (tokenizer.hasMoreTokens()) {
        String token = tokenizer.nextToken("/\"");
        if (token.equals("/")) {
          token = tokenizer.nextToken("\n");
          if (token.startsWith("/")) {
            token = _NSStringUtilities.replaceAllInstancesOfString(token, WOHelperFunctionDeclarationParser.ESCAPED_QUOTE_STRING, "\\\"");
            declarationWithoutCommentsBuffer.append('\n');
            tokenizer.nextToken();
          }
          else {
            declarationWithoutCommentsBuffer.append('/');
            declarationWithoutCommentsBuffer.append(token);
          }
        }
        else if (token.equals("\"")) {
          token = tokenizer.nextToken("\"");
          if (token.equals("\"")) {
            token = "";
          }
          else {
            tokenizer.nextToken();
          }
          String quotedStringKey = WOHelperFunctionDeclarationParser.QUOTED_STRING_KEY + _quotedStrings.count();
          if (NSLog.debugLoggingAllowedForLevelAndGroups(3, 0x0L)) {
            NSLog.debug.appendln("Found a quoted string: " + quotedStringKey + "='" + token + "';");
          }
          token = _NSStringUtilities.replaceAllInstancesOfString(token, WOHelperFunctionDeclarationParser.ESCAPED_QUOTE_STRING, "\"");
          _quotedStrings.setObjectForKey(token, quotedStringKey);
          declarationWithoutCommentsBuffer.append(quotedStringKey);
        }
        else {
          declarationWithoutCommentsBuffer.append(token);
        }
      }
    }
    catch (NoSuchElementException e) {
      log.debug("Parsing failed.", e);
    }
    return declarationWithoutCommentsBuffer.toString();
  }

  private NSMutableDictionary parseDeclarationsWithoutComments(String declarationWithoutComment) throws WOHelperFunctionDeclarationFormatException {
    NSMutableDictionary declarations = new NSMutableDictionary();
    NSMutableDictionary rawDeclarations = _rawDeclarationsWithoutComment(declarationWithoutComment);
    String tagName;
    WODeclaration declaration;
    Enumeration rawDeclarationHeaderEnum = rawDeclarations.keyEnumerator();
    while (rawDeclarationHeaderEnum.hasMoreElements()) {
      String declarationHeader = (String) rawDeclarationHeaderEnum.nextElement();
      String declarationBody = (String) rawDeclarations.objectForKey(declarationHeader);
      int colonIndex = declarationHeader.indexOf(':');
      if (colonIndex < 0) {
        throw new WOHelperFunctionDeclarationFormatException("<WOHelperFunctionDeclarationParser> Missing ':' for declaration:\n" + declarationHeader + " " + declarationBody);
      }
      tagName = declarationHeader.substring(0, colonIndex).trim();
      if (tagName.length() == 0) {
        throw new WOHelperFunctionDeclarationFormatException("<WOHelperFunctionDeclarationParser> Missing tag name for declaration:\n" + declarationHeader + " " + declarationBody);
      }
      if (declarations.objectForKey(tagName) != null) {
        throw new WOHelperFunctionDeclarationFormatException("<WOHelperFunctionDeclarationParser> Duplicate tag name '" + tagName + "' in declaration:\n" + declarationBody);
      }
      String type = declarationHeader.substring(colonIndex + 1).trim();
      if (type.length() == 0) {
        throw new WOHelperFunctionDeclarationFormatException("<WOHelperFunctionDeclarationParser> Missing element name for declaration:\n" + declarationHeader + " " + declarationBody);
      }
      NSMutableDictionary associations = _associationsForDictionaryString(declarationHeader, declarationBody);
      declaration = WOHelperFunctionParser.createDeclaration(tagName, type, associations);
      declarations.setObjectForKey(declaration, tagName);
    }

    return declarations;
  }

  private NSMutableDictionary _associationsForDictionaryString(String declarationHeader, String declarationBody) throws WOHelperFunctionDeclarationFormatException {
    NSMutableDictionary associations = new NSMutableDictionary();
    String trimmedDeclarationBody = declarationBody.trim();
    if (!trimmedDeclarationBody.startsWith("{") && !trimmedDeclarationBody.endsWith("}")) {
      throw new WOHelperFunctionDeclarationFormatException("<WOHelperFunctionDeclarationParser> Internal inconsistency : invalid dictionary for declaration:\n" + declarationHeader + " " + declarationBody);
    }
    int declarationBodyLength = trimmedDeclarationBody.length();
    if (declarationBodyLength <= 2) {
      return associations;
    }
    trimmedDeclarationBody = trimmedDeclarationBody.substring(1, declarationBodyLength - 1).trim();
    NSArray bindings = NSArray.componentsSeparatedByString(trimmedDeclarationBody, ";");
    Enumeration bindingsEnum = bindings.objectEnumerator();
    do {
      if (!bindingsEnum.hasMoreElements()) {
        break;
      }
      String binding = ((String) bindingsEnum.nextElement()).trim();
      if (binding.length() != 0) {
        int equalsIndex = binding.indexOf('=');
        if (equalsIndex < 0) {
          throw new WOHelperFunctionDeclarationFormatException("<WOHelperFunctionDeclarationParser> Invalid line. No equal in line:\n" + binding + "\nfor declaration:\n" + declarationHeader + " " + declarationBody);
        }
        String key = binding.substring(0, equalsIndex).trim();
        if (key.length() == 0) {
          throw new WOHelperFunctionDeclarationFormatException("<WOHelperFunctionDeclarationParser> Missing binding in line:\n" + binding + "\nfor declaration:\n" + declarationHeader + " " + declarationBody);
        }
        String value = binding.substring(equalsIndex + 1).trim();
        if (value.length() == 0) {
          throw new WOHelperFunctionDeclarationFormatException("<WOHelperFunctionDeclarationParser> Missing value in line:\n" + binding + "\nfor declaration:\n" + declarationHeader + " " + declarationBody);
        }
        WOAssociation association = WOHelperFunctionDeclarationParser._associationWithKey(value, _quotedStrings);
        Object quotedString = _quotedStrings.objectForKey(key);
        if (quotedString != null) {
          associations.setObjectForKey(association, quotedString);
        }
        else {
          associations.setObjectForKey(association, key);
        }
      }
    }
    while (true);
    // if (log.isDebugEnabled()) {
    // log.debug("Parsed '" + s + "' declarations:\n" + nsmutabledictionary
    // + "\n--------");
    // }
    return associations;
  }

  public static WOAssociation _associationWithKey(String associationValue, NSDictionary quotedStrings) {
    WOAssociation association = null;
    if (associationValue != null && associationValue.startsWith("~")) {
      int associationValueLength = associationValue.length();
      StringBuilder ognlValue = new StringBuilder();
      int lastIndex = 0;
      int index = 0;
      while ((index = associationValue.indexOf(WOHelperFunctionDeclarationParser.QUOTED_STRING_KEY, lastIndex)) != -1) {
        ognlValue.append(associationValue.substring(lastIndex, index));
        int wodpValueStartIndex = index + WOHelperFunctionDeclarationParser.QUOTED_STRING_KEY.length();
        int wodpValueEndIndex = wodpValueStartIndex;
        for (; wodpValueEndIndex < associationValueLength && Character.isDigit(associationValue.charAt(wodpValueEndIndex)); wodpValueEndIndex++) {
          // do nothing
        }
        String wodpKey = WOHelperFunctionDeclarationParser.QUOTED_STRING_KEY + associationValue.substring(wodpValueStartIndex, wodpValueEndIndex);
        String quotedString = (String) quotedStrings.objectForKey(wodpKey);
        if (quotedString != null) {
          quotedString = quotedString.replaceAll("\\\"", "\\\\\"");
          ognlValue.append("\"");
          ognlValue.append(quotedString);
          ognlValue.append("\"");
        }
        lastIndex = wodpValueEndIndex;
      }
      ognlValue.append(associationValue.substring(lastIndex));
      associationValue = ognlValue.toString();
      association = WOHelperFunctionAssociation.associationWithValue(associationValue);
    }
    else {
      String quotedString = (String) quotedStrings.objectForKey(associationValue);
      // MS: WO 5.4 converts \n to an actual newline. I don't know if WO 5.3 does, too, but let's go ahead and be compatible with them as long as nobody is yelling.
      if (quotedString != null) {
        int backslashIndex = quotedString.indexOf('\\');
        if (backslashIndex != -1) {
          StringBuilder sb = new StringBuilder(quotedString);
          int length = sb.length();
          for (int i = backslashIndex; i < length; i ++) {
            char ch = sb.charAt(i);
            if (ch == '\\' && i < length) {
              char nextCh = sb.charAt(i + 1);
              if (nextCh == 'n') {
                sb.replace(i, i + 2, "\n");
              }
              else if (nextCh == 'r') {
                sb.replace(i, i + 2, "\r");
              }
              else if (nextCh == 't') {
                sb.replace(i, i + 2, "\t");
              }
              else {
                sb.replace(i, i + 2, String.valueOf(nextCh));
              }
              length --;
            }
          }
          quotedString = sb.toString();
        }
        association = WOHelperFunctionAssociation.associationWithValue(quotedString);
      }
      else if (_NSStringUtilities.isNumber(associationValue)) {
        Integer integer = WOShared.unsignedIntNumber(Integer.parseInt(associationValue));
        association = WOHelperFunctionAssociation.associationWithValue(integer);
      }
      else if ("true".equalsIgnoreCase(associationValue) || "yes".equalsIgnoreCase(associationValue)) {
        association = WOConstantValueAssociation.TRUE;
      }
      else if ("false".equalsIgnoreCase(associationValue) || "no".equalsIgnoreCase(associationValue) || "nil".equalsIgnoreCase(associationValue) || "null".equalsIgnoreCase(associationValue)) {
        association = WOConstantValueAssociation.FALSE;
      }
      else {
        association = WOHelperFunctionAssociation.associationWithKeyPath(associationValue);
      }
    }
    return association;
  }

  private NSMutableDictionary _rawDeclarationsWithoutComment(String declarationStr) {
    NSMutableDictionary declarations = new NSMutableDictionary();
    StringBuilder declarationWithoutCommentBuffer = new StringBuilder(100);
    StringTokenizer tokenizer = new StringTokenizer(declarationStr, "{", true);
    try {
      while (tokenizer.hasMoreTokens()) {
        String token = tokenizer.nextToken("{");
        if (token.equals("{")) {
          token = tokenizer.nextToken("}");
          if (token.equals("}")) {
            token = "";
          }
          else {
            tokenizer.nextToken();
          }
          String declarationWithoutComment = declarationWithoutCommentBuffer.toString();
          if (declarationWithoutComment.startsWith(";")) {
            declarationWithoutComment = declarationWithoutComment.substring(1);
          }
          declarations.setObjectForKey("{" + token + "}", declarationWithoutComment.trim());
          declarationWithoutCommentBuffer.setLength(0);
        }
        else {
          declarationWithoutCommentBuffer.append(token);
        }
      }
    }
    catch (NoSuchElementException e) {
      log.debug("Failed to parse.", e);
    }
    return declarations;
  }
}
TOP

Related Classes of ognl.helperfunction.WOHelperFunctionDeclarationParser

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.