protected boolean hasRedundantParentheses(String s, String operator1, String operator2) {

    String[] parts = StringUtil.split(s, operator1);

    if (parts.length < 3) {
      return false;
    }

    for (int i = 1; i < (parts.length - 1); i++) {
      String part = parts[i];

      if (part.contains(operator2) || part.contains("!(")) {
        continue;
      }

      int closeParenthesesCount = StringUtil.count(part, StringPool.CLOSE_PARENTHESIS);
      int openParenthesesCount = StringUtil.count(part, StringPool.OPEN_PARENTHESIS);

      if (Math.abs(closeParenthesesCount - openParenthesesCount) == 1) {
        return true;
      }
    }

    return false;
  }
  protected void checkStringBundler(String line, String fileName, int lineCount) {

    if ((!line.startsWith("sb.append(") && !line.contains("SB.append(")) || !line.endsWith(");")) {

      return;
    }

    int pos = line.indexOf(".append(");

    line = line.substring(pos + 8, line.length() - 2);

    line = stripQuotes(line, CharPool.QUOTE);

    if (!line.contains(" + ")) {
      return;
    }

    String[] lineParts = StringUtil.split(line, " + ");

    for (String linePart : lineParts) {
      int closeParenthesesCount = StringUtil.count(linePart, StringPool.CLOSE_PARENTHESIS);
      int openParenthesesCount = StringUtil.count(linePart, StringPool.OPEN_PARENTHESIS);

      if (closeParenthesesCount != openParenthesesCount) {
        return;
      }

      if (Validator.isNumber(linePart)) {
        return;
      }
    }

    processErrorMessage(fileName, "plus: " + fileName + " " + lineCount);
  }
Example #3
0
  @Override
  public void visitToken(DetailAST detailAST) {
    List<DetailAST> methodCallASTList =
        DetailASTUtil.getAllChildTokens(detailAST, TokenTypes.METHOD_CALL, true);

    for (DetailAST methodCallAST : methodCallASTList) {
      List<DetailAST> childMethodCallASTList =
          DetailASTUtil.getAllChildTokens(methodCallAST, TokenTypes.METHOD_CALL, true);

      // Only check the method that is first in the chain

      if (!childMethodCallASTList.isEmpty()) {
        continue;
      }

      String chainedMethodNames = _getChainedMethodNames(methodCallAST);

      if (!chainedMethodNames.contains(StringPool.PERIOD)) {
        continue;
      }

      _checkMethodName(chainedMethodNames, "getClass", methodCallAST, detailAST);

      if (StringUtil.count(chainedMethodNames, StringPool.PERIOD) == 1) {
        continue;
      }

      if (chainedMethodNames.contains("concat.concat.concat")) {
        log(methodCallAST.getLineNo(), MSG_AVOID_TOO_MANY_CONCAT);

        continue;
      }

      if (!chainedMethodNames.contains("concat.concat")
          && !chainedMethodNames.matches(_chainingAllowedFormat)) {

        log(
            methodCallAST.getLineNo(),
            MSG_AVOID_CHAINING_MULTIPLE,
            DetailASTUtil.getMethodName(methodCallAST));
      }
    }
  }
  @Override
  protected void doUpgrade() throws Exception {
    Connection con = null;
    PreparedStatement ps = null;
    ResultSet rs = null;

    try {
      con = DataAccess.getConnection();

      ps = con.prepareStatement(_GET_LAYOUT);

      rs = ps.executeQuery();

      while (rs.next()) {
        long plid = rs.getLong("plid");
        String typeSettings = rs.getString("typeSettings");

        String newTypeSettings = typeSettings;

        Matcher matcher = _pattern.matcher(typeSettings);

        while (matcher.find()) {
          String nestedColumnIds = matcher.group();

          int underlineCount = StringUtil.count(nestedColumnIds, StringPool.UNDERLINE);

          if (underlineCount == _UNDERLINE_COUNT) {
            String newNestedColumnIds = nestedColumnIds.replaceAll(_pattern.pattern(), "_$1_$2");

            newTypeSettings = newTypeSettings.replaceAll(nestedColumnIds, newNestedColumnIds);
          }
        }

        if (!newTypeSettings.equals(typeSettings)) {
          updateLayout(plid, newTypeSettings);
        }
      }
    } finally {
      DataAccess.cleanUp(con, ps, rs);
    }
  }
  protected void checkIfClauseParentheses(String ifClause, String fileName, int lineCount) {

    int quoteCount = StringUtil.count(ifClause, StringPool.QUOTE);

    if ((quoteCount % 2) == 1) {
      return;
    }

    ifClause = stripQuotes(ifClause, CharPool.QUOTE);

    ifClause = stripQuotes(ifClause, CharPool.APOSTROPHE);

    if (ifClause.contains(StringPool.DOUBLE_SLASH)
        || ifClause.contains("/*")
        || ifClause.contains("*/")) {

      return;
    }

    if (hasRedundantParentheses(ifClause, "||", "&&")
        || hasRedundantParentheses(ifClause, "&&", "||")) {

      processErrorMessage(fileName, "redundant parentheses: " + fileName + " " + lineCount);
    }

    ifClause = stripRedundantParentheses(ifClause);

    int level = 0;
    int max = StringUtil.count(ifClause, StringPool.OPEN_PARENTHESIS);
    int previousParenthesisPos = -1;

    int[] levels = new int[max];

    for (int i = 0; i < ifClause.length(); i++) {
      char c = ifClause.charAt(i);

      if ((c == CharPool.OPEN_PARENTHESIS) || (c == CharPool.CLOSE_PARENTHESIS)) {

        if (previousParenthesisPos != -1) {
          String s = ifClause.substring(previousParenthesisPos + 1, i);

          if (hasMissingParentheses(s)) {
            processErrorMessage(fileName, "missing parentheses: " + fileName + " " + lineCount);
          }
        }

        previousParenthesisPos = i;

        if (c == CharPool.OPEN_PARENTHESIS) {
          levels[level] = i;

          level += 1;
        } else {
          int posOpenParenthesis = levels[level - 1];

          if (level > 1) {
            char nextChar = ifClause.charAt(i + 1);
            char previousChar = ifClause.charAt(posOpenParenthesis - 1);

            if (!Character.isLetterOrDigit(nextChar)
                && (nextChar != CharPool.PERIOD)
                && !Character.isLetterOrDigit(previousChar)) {

              String s = ifClause.substring(posOpenParenthesis + 1, i);

              if (hasRedundantParentheses(s)) {
                processErrorMessage(
                    fileName, "redundant parentheses: " + fileName + " " + lineCount);
              }
            }

            if ((previousChar == CharPool.OPEN_PARENTHESIS)
                && (nextChar == CharPool.CLOSE_PARENTHESIS)) {

              processErrorMessage(fileName, "redundant parentheses: " + fileName + " " + lineCount);
            }
          }

          level -= 1;
        }
      }
    }
  }
  protected String sortAttributes(
      String fileName, String line, int lineCount, boolean allowApostropheDelimeter) {

    String s = line;

    int x = s.indexOf(StringPool.SPACE);

    if (x == -1) {
      return line;
    }

    s = s.substring(x + 1);

    String previousAttribute = null;
    String previousAttributeAndValue = null;

    boolean wrongOrder = false;

    for (x = 0; ; ) {
      x = s.indexOf(StringPool.EQUAL);

      if ((x == -1) || (s.length() <= (x + 1))) {
        return line;
      }

      String attribute = s.substring(0, x);

      if (!isAttributName(attribute)) {
        return line;
      }

      if (Validator.isNotNull(previousAttribute) && (previousAttribute.compareTo(attribute) > 0)) {

        wrongOrder = true;
      }

      s = s.substring(x + 1);

      char delimeter = s.charAt(0);

      if ((delimeter != CharPool.APOSTROPHE) && (delimeter != CharPool.QUOTE)) {

        if (delimeter != CharPool.AMPERSAND) {
          processErrorMessage(fileName, "delimeter: " + fileName + " " + lineCount);
        }

        return line;
      }

      s = s.substring(1);

      String value = null;

      int y = -1;

      while (true) {
        y = s.indexOf(delimeter, y + 1);

        if ((y == -1) || (s.length() <= (y + 1))) {
          return line;
        }

        value = s.substring(0, y);

        if (value.startsWith("<%")) {
          int endJavaCodeSignCount = StringUtil.count(value, "%>");
          int startJavaCodeSignCount = StringUtil.count(value, "<%");

          if (endJavaCodeSignCount == startJavaCodeSignCount) {
            break;
          }
        } else {
          int greaterThanCount = StringUtil.count(value, StringPool.GREATER_THAN);
          int lessThanCount = StringUtil.count(value, StringPool.LESS_THAN);

          if (greaterThanCount == lessThanCount) {
            break;
          }
        }
      }

      if (delimeter == CharPool.APOSTROPHE) {
        if (!value.contains(StringPool.QUOTE)) {
          line =
              StringUtil.replace(
                  line,
                  StringPool.APOSTROPHE + value + StringPool.APOSTROPHE,
                  StringPool.QUOTE + value + StringPool.QUOTE);

          return sortAttributes(fileName, line, lineCount, allowApostropheDelimeter);
        } else if (!allowApostropheDelimeter) {
          String newValue = StringUtil.replace(value, StringPool.QUOTE, "&quot;");

          line =
              StringUtil.replace(
                  line,
                  StringPool.APOSTROPHE + value + StringPool.APOSTROPHE,
                  StringPool.QUOTE + newValue + StringPool.QUOTE);

          return sortAttributes(fileName, line, lineCount, allowApostropheDelimeter);
        }
      }

      StringBundler sb = new StringBundler(5);

      sb.append(attribute);
      sb.append(StringPool.EQUAL);
      sb.append(delimeter);
      sb.append(value);
      sb.append(delimeter);

      String currentAttributeAndValue = sb.toString();

      if (wrongOrder) {
        if ((StringUtil.count(line, currentAttributeAndValue) == 1)
            && (StringUtil.count(line, previousAttributeAndValue) == 1)) {

          line = StringUtil.replaceFirst(line, previousAttributeAndValue, currentAttributeAndValue);

          line = StringUtil.replaceLast(line, currentAttributeAndValue, previousAttributeAndValue);

          return sortAttributes(fileName, line, lineCount, allowApostropheDelimeter);
        }

        return line;
      }

      s = s.substring(y + 1);

      if (s.startsWith(StringPool.GREATER_THAN)) {
        x = s.indexOf(StringPool.SPACE);

        if (x == -1) {
          return line;
        }

        s = s.substring(x + 1);

        previousAttribute = null;
        previousAttributeAndValue = null;
      } else {
        s = StringUtil.trimLeading(s);

        previousAttribute = attribute;
        previousAttributeAndValue = currentAttributeAndValue;
      }
    }
  }
  protected String formatJSP(String fileName, String absolutePath, String content)
      throws IOException {

    StringBundler sb = new StringBundler();

    UnsyncBufferedReader unsyncBufferedReader =
        new UnsyncBufferedReader(new UnsyncStringReader(content));

    int lineCount = 0;

    String line = null;

    String previousLine = StringPool.BLANK;

    String currentAttributeAndValue = null;
    String previousAttribute = null;
    String previousAttributeAndValue = null;

    boolean readAttributes = false;

    String currentException = null;
    String previousException = null;

    boolean hasUnsortedExceptions = false;

    boolean javaSource = false;

    while ((line = unsyncBufferedReader.readLine()) != null) {
      lineCount++;

      if (!fileName.contains("jsonw") || !fileName.endsWith("action.jsp")) {

        line = trimLine(line, false);
      }

      if (line.contains("<aui:button ") && line.contains("type=\"button\"")) {

        processErrorMessage(fileName, "aui:button " + fileName + " " + lineCount);
      }

      if (line.contains("debugger.")) {
        processErrorMessage(fileName, "debugger " + fileName + " " + lineCount);
      }

      String trimmedLine = StringUtil.trimLeading(line);
      String trimmedPreviousLine = StringUtil.trimLeading(previousLine);

      checkStringBundler(trimmedLine, fileName, lineCount);

      checkEmptyCollection(trimmedLine, fileName, lineCount);

      if (trimmedLine.equals("<%") || trimmedLine.equals("<%!")) {
        javaSource = true;
      } else if (trimmedLine.equals("%>")) {
        javaSource = false;
      }

      if (javaSource || trimmedLine.contains("<%= ")) {
        checkInefficientStringMethods(line, fileName, absolutePath, lineCount);
      }

      if (javaSource
          && portalSource
          && !isExcluded(_unusedVariablesExclusions, fileName, lineCount)
          && !_jspContents.isEmpty()
          && hasUnusedVariable(fileName, trimmedLine)) {

        processErrorMessage(fileName, "Unused variable: " + fileName + " " + lineCount);
      }

      if (!trimmedLine.equals("%>")
          && line.contains("%>")
          && !line.contains("--%>")
          && !line.contains(" %>")) {

        line = StringUtil.replace(line, "%>", " %>");
      }

      if (line.contains("<%=") && !line.contains("<%= ")) {
        line = StringUtil.replace(line, "<%=", "<%= ");
      }

      if (trimmedPreviousLine.equals("%>")
          && Validator.isNotNull(line)
          && !trimmedLine.equals("-->")) {

        sb.append("\n");
      } else if (Validator.isNotNull(previousLine)
          && !trimmedPreviousLine.equals("<!--")
          && trimmedLine.equals("<%")) {

        sb.append("\n");
      } else if (trimmedPreviousLine.equals("<%") && Validator.isNull(line)) {

        continue;
      } else if (trimmedPreviousLine.equals("<%") && trimmedLine.startsWith("//")) {

        sb.append("\n");
      } else if (Validator.isNull(previousLine) && trimmedLine.equals("%>") && (sb.index() > 2)) {

        String lineBeforePreviousLine = sb.stringAt(sb.index() - 3);

        if (!lineBeforePreviousLine.startsWith("//")) {
          sb.setIndex(sb.index() - 1);
        }
      }

      if ((trimmedLine.startsWith("if (")
              || trimmedLine.startsWith("else if (")
              || trimmedLine.startsWith("while ("))
          && trimmedLine.endsWith(") {")) {

        checkIfClauseParentheses(trimmedLine, fileName, lineCount);
      }

      if (readAttributes) {
        if (!trimmedLine.startsWith(StringPool.FORWARD_SLASH)
            && !trimmedLine.startsWith(StringPool.GREATER_THAN)) {

          int pos = trimmedLine.indexOf(StringPool.EQUAL);

          if (pos != -1) {
            String attribute = trimmedLine.substring(0, pos);

            if (!trimmedLine.endsWith(StringPool.APOSTROPHE)
                && !trimmedLine.endsWith(StringPool.GREATER_THAN)
                && !trimmedLine.endsWith(StringPool.QUOTE)) {

              processErrorMessage(fileName, "attribute: " + fileName + " " + lineCount);

              readAttributes = false;
            } else if (trimmedLine.endsWith(StringPool.APOSTROPHE)
                && !trimmedLine.contains(StringPool.QUOTE)) {

              line = StringUtil.replace(line, StringPool.APOSTROPHE, StringPool.QUOTE);

              readAttributes = false;
            } else if (Validator.isNotNull(previousAttribute)) {
              if (!isAttributName(attribute) && !attribute.startsWith(StringPool.LESS_THAN)) {

                processErrorMessage(fileName, "attribute: " + fileName + " " + lineCount);

                readAttributes = false;
              } else if (Validator.isNull(previousAttributeAndValue)
                  && (previousAttribute.compareTo(attribute) > 0)) {

                previousAttributeAndValue = previousLine;
                currentAttributeAndValue = line;
              }
            }

            if (!readAttributes) {
              previousAttribute = null;
              previousAttributeAndValue = null;
            } else {
              previousAttribute = attribute;
            }
          }
        } else {
          previousAttribute = null;

          readAttributes = false;
        }
      }

      if (!hasUnsortedExceptions) {
        int i = line.indexOf("<liferay-ui:error exception=\"<%=");

        if (i != -1) {
          currentException = line.substring(i + 33);

          if (Validator.isNotNull(previousException)
              && (previousException.compareTo(currentException) > 0)) {

            hasUnsortedExceptions = true;
          }
        }

        if (!hasUnsortedExceptions) {
          previousException = currentException;
          currentException = null;
        }
      }

      if (trimmedLine.startsWith(StringPool.LESS_THAN)
          && !trimmedLine.startsWith("<%")
          && !trimmedLine.startsWith("<!")) {

        if (!trimmedLine.contains(StringPool.GREATER_THAN)
            && !trimmedLine.contains(StringPool.SPACE)) {

          readAttributes = true;
        } else {
          line = sortAttributes(fileName, line, lineCount, true);
        }
      }

      if (!trimmedLine.contains(StringPool.DOUBLE_SLASH)
          && !trimmedLine.startsWith(StringPool.STAR)) {

        while (trimmedLine.contains(StringPool.TAB)) {
          line = StringUtil.replaceLast(line, StringPool.TAB, StringPool.SPACE);

          trimmedLine = StringUtil.replaceLast(trimmedLine, StringPool.TAB, StringPool.SPACE);
        }

        while (trimmedLine.contains(StringPool.DOUBLE_SPACE)
            && !trimmedLine.contains(StringPool.QUOTE + StringPool.DOUBLE_SPACE)
            && !fileName.endsWith(".vm")) {

          line = StringUtil.replaceLast(line, StringPool.DOUBLE_SPACE, StringPool.SPACE);

          trimmedLine =
              StringUtil.replaceLast(trimmedLine, StringPool.DOUBLE_SPACE, StringPool.SPACE);
        }
      }

      if (!fileName.endsWith("/touch.jsp")) {
        int x = line.indexOf("<%@ include file");

        if (x != -1) {
          x = line.indexOf(StringPool.QUOTE, x);

          int y = line.indexOf(StringPool.QUOTE, x + 1);

          if (y != -1) {
            String includeFileName = line.substring(x + 1, y);

            Matcher matcher = _jspIncludeFilePattern.matcher(includeFileName);

            if (!matcher.find()) {
              processErrorMessage(fileName, "include: " + fileName + " " + lineCount);
            }
          }
        }
      }

      line = replacePrimitiveWrapperInstantiation(fileName, line, lineCount);

      previousLine = line;

      sb.append(line);
      sb.append("\n");
    }

    unsyncBufferedReader.close();

    content = sb.toString();

    if (content.endsWith("\n")) {
      content = content.substring(0, content.length() - 1);
    }

    content = formatTaglibQuotes(fileName, content, StringPool.QUOTE);
    content = formatTaglibQuotes(fileName, content, StringPool.APOSTROPHE);

    if (Validator.isNotNull(previousAttributeAndValue)) {
      content =
          StringUtil.replaceFirst(
              content,
              previousAttributeAndValue + "\n" + currentAttributeAndValue,
              currentAttributeAndValue + "\n" + previousAttributeAndValue);
    }

    if (hasUnsortedExceptions) {
      if ((StringUtil.count(content, currentException) > 1)
          || (StringUtil.count(content, previousException) > 1)) {

        processErrorMessage(fileName, "unsorted exceptions: " + fileName);
      } else {
        content = StringUtil.replaceFirst(content, previousException, currentException);

        content = StringUtil.replaceLast(content, currentException, previousException);
      }
    }

    return content;
  }
/**
 * @author Wesley Gong
 * @author Bijan Vakili
 * @author Douglas Wong
 * @author Brian Wing Shun Chan
 */
public class UpgradeNestedPortlets extends UpgradeProcess {

  @Override
  protected void doUpgrade() throws Exception {
    Connection con = null;
    PreparedStatement ps = null;
    ResultSet rs = null;

    try {
      con = DataAccess.getConnection();

      ps = con.prepareStatement(_GET_LAYOUT);

      rs = ps.executeQuery();

      while (rs.next()) {
        long plid = rs.getLong("plid");
        String typeSettings = rs.getString("typeSettings");

        String newTypeSettings = typeSettings;

        Matcher matcher = _pattern.matcher(typeSettings);

        while (matcher.find()) {
          String nestedColumnIds = matcher.group();

          int underlineCount = StringUtil.count(nestedColumnIds, StringPool.UNDERLINE);

          if (underlineCount == _UNDERLINE_COUNT) {
            String newNestedColumnIds = nestedColumnIds.replaceAll(_pattern.pattern(), "_$1_$2");

            newTypeSettings = newTypeSettings.replaceAll(nestedColumnIds, newNestedColumnIds);
          }
        }

        if (!newTypeSettings.equals(typeSettings)) {
          updateLayout(plid, newTypeSettings);
        }
      }
    } finally {
      DataAccess.cleanUp(con, ps, rs);
    }
  }

  protected void updateLayout(long plid, String typeSettings) throws Exception {

    Connection con = null;
    PreparedStatement ps = null;

    try {
      con = DataAccess.getConnection();

      ps = con.prepareStatement("update Layout set typeSettings = ? where plid = " + plid);

      ps.setString(1, typeSettings);

      ps.executeUpdate();
    } finally {
      DataAccess.cleanUp(con, ps);
    }
  }

  private static final String _GET_LAYOUT =
      "select plid, typeSettings from Layout where typeSettings like "
          + "'%nested-column-ids="
          + PortletKeys.NESTED_PORTLETS
          + PortletConstants.INSTANCE_SEPARATOR
          + "%'";

  private static final int _UNDERLINE_COUNT =
      StringUtil.count(PortletConstants.INSTANCE_SEPARATOR, StringPool.UNDERLINE) + 1;

  private static Pattern _pattern =
      Pattern.compile(
          "("
              + PortletKeys.NESTED_PORTLETS
              + PortletConstants.INSTANCE_SEPARATOR
              + "[^_,\\s=]+_)([^_,\\s=]+)");
}