Exemplo n.º 1
0
  /**
   * Perform the substitutions.
   *
   * @param exp a DSLR source line to be expanded
   * @param entries the appropriate DSL keys and values
   * @param line line number
   * @return the expanden line
   */
  private String substitute(String exp, List<DSLMappingEntry> entries, int line) {
    if (entries.size() == 0) {
      this.addError(new ExpanderException("No mapping entries for expanding: " + exp, line));
      return exp;
    }

    if (showSteps) {
      System.out.println("to expand: |" + exp + "|");
    }

    Map<String, String> key2value = new HashMap<String, String>();
    for (final DSLMappingEntry entry : entries) {
      Map<String, Integer> vars = entry.getVariables();
      String vp = entry.getValuePattern();
      Pattern kp = entry.getKeyPattern();
      Matcher m = kp.matcher(exp);
      int startPos = 0;
      boolean match = false;
      while (startPos < exp.length() && m.find(startPos)) {
        match = true;
        if (showSteps) {
          System.out.println("  matches: " + kp.toString());
        }
        // Replace the range of group 0.
        String target = m.group(0);
        if (!vars.keySet().isEmpty()) {
          // Build a pattern matching any variable enclosed in braces.
          StringBuilder sb = new StringBuilder();
          String del = "\\{(";
          for (String key : vars.keySet()) {
            sb.append(del).append(Pattern.quote(key));
            del = "|";
          }
          sb.append(")(?:!(uc|lc|ucfirst|num|.*))?\\}");
          Pattern allkeyPat = Pattern.compile(sb.toString());
          Matcher allkeyMat = allkeyPat.matcher(vp);

          // While the pattern matches, get the actual key and replace by '$' + index
          while (allkeyMat.find()) {
            String theKey = allkeyMat.group(1);
            String theFunc = allkeyMat.group(2);
            String theValue = m.group(vars.get(theKey));
            if (theFunc != null) {
              if ("uc".equals(theFunc)) {
                theValue = theValue.toUpperCase();
              } else if ("lc".equals(theFunc)) {
                theValue = theValue.toLowerCase();
              } else if ("ucfirst".equals(theFunc) && theValue.length() > 0) {
                theValue =
                    theValue.substring(0, 1).toUpperCase() + theValue.substring(1).toLowerCase();
              } else if (theFunc.startsWith("num")) {
                // kill all non-digits, but keep '-'
                String numStr = theValue.replaceAll("[^-\\d]+", "");
                try {
                  long numLong = Long.parseLong(numStr);
                  if (theValue.matches("^.*[.,]\\d\\d(?:\\D.*|$)")) {
                    numStr = Long.toString(numLong);
                    theValue =
                        numStr.substring(0, numStr.length() - 2)
                            + '.'
                            + numStr.substring(numStr.length() - 2);
                  } else {
                    theValue = Long.toString(numLong);
                  }
                } catch (NumberFormatException nfe) {
                  // silently ignore - keep the value as it is
                }
              } else {
                StringTokenizer strTok = new StringTokenizer(theFunc, "?/", true);
                boolean compare = true;
                int toks = strTok.countTokens();
                while (toks >= 4) {
                  String key = strTok.nextToken();
                  String qmk = strTok.nextToken(); // '?'
                  String val = strTok.nextToken(); // to use
                  String sep = strTok.nextToken(); // '/'
                  if (key.equals(theValue)) {
                    theValue = val;
                    break;
                  }
                  toks -= 4;
                  if (toks < 4) {
                    theValue = strTok.nextToken();
                    break;
                  }
                }
              }
            }
            vp = vp.substring(0, allkeyMat.start()) + theValue + vp.substring(allkeyMat.end());
            allkeyMat.reset(vp);
            key2value.put(theKey, theValue);
          }
        }

        // Try to find any matches from previous lines.
        Matcher varRefMat = varRefPat.matcher(vp);
        while (varRefMat.find()) {
          String theKey = varRefMat.group(1);
          for (int ientry = substitutions.size() - 1; ientry >= 0; ientry--) {
            String theValue = substitutions.get(ientry).get(theKey);
            if (theValue != null) {
              // replace it
              vp = vp.substring(0, varRefMat.start()) + theValue + vp.substring(varRefMat.end());
              varRefMat.reset(vp);
              break;
            }
          }
        }

        // add the new set of substitutions
        if (key2value.size() > 0) {
          substitutions.add(key2value);
        }

        // now replace the target
        exp = exp.substring(0, m.start()) + vp + exp.substring(m.end());
        if (match && showSteps) {
          System.out.println("   result: |" + exp + "|");
        }
        startPos = m.start() + vp.length();
        m.reset(exp);
      }
    }
    return exp;
  }