private static String byteArrayToHex(byte[] bytes) {
   //        final StringBuilder sb = new StringBuilder(bytes.length * 2);
   final FastStringBuffer sb = new FastStringBuffer(bytes.length * 2);
   for (int i = 0; i < bytes.length; i++) {
     sb.append(HEXADECIMAL_DIGITS[(bytes[i] >> 4) & 0xf]);
     sb.append(HEXADECIMAL_DIGITS[bytes[i] & 0xf]);
   }
   return sb.toString();
 }
예제 #2
0
 /**
  * Format a number supplied as a integer
  *
  * @param value the integer value
  * @param fsb the FastStringBuffer to contain the result
  */
 private void formatInteger(NumericValue value, FastStringBuffer fsb) {
   fsb.append(value.getStringValueCS());
   int leadingZeroes = minWholePartSize - fsb.length();
   fsb.prependRepeated('0', leadingZeroes);
   if (minFractionPartSize != 0) {
     fsb.append('.');
     for (int i = 0; i < minFractionPartSize; i++) {
       fsb.append('0');
     }
   }
 }
예제 #3
0
    /**
     * Format a number supplied as a decimal
     *
     * @param dval the decimal value
     * @param fsb the FastStringBuffer to contain the result
     */
    private void formatDecimal(BigDecimal dval, FastStringBuffer fsb) {
      dval = dval.setScale(maxFractionPartSize, BigDecimal.ROUND_HALF_EVEN);
      DecimalValue.decimalToString(dval, fsb);

      int point = fsb.indexOf('.');
      int intDigits;
      if (point >= 0) {
        int zz = maxFractionPartSize - minFractionPartSize;
        while (zz > 0) {
          if (fsb.charAt(fsb.length() - 1) == '0') {
            fsb.setLength(fsb.length() - 1);
            zz--;
          } else {
            break;
          }
        }
        intDigits = point;
        if (fsb.charAt(fsb.length() - 1) == '.') {
          fsb.setLength(fsb.length() - 1);
        }
      } else {
        intDigits = fsb.length();
        if (minFractionPartSize > 0) {
          fsb.append('.');
          for (int i = 0; i < minFractionPartSize; i++) {
            fsb.append('0');
          }
        }
      }
      if (minWholePartSize == 0 && intDigits == 1 && fsb.charAt(0) == '0') {
        fsb.removeCharAt(0);
      } else {
        fsb.prependRepeated('0', minWholePartSize - intDigits);
      }
    }
예제 #4
0
    /**
     * Format a number using this sub-picture
     *
     * @param value the absolute value of the number to be formatted
     * @param dfs the decimal format symbols to be used
     * @param minusSign the representation of a minus sign to be used
     * @return the formatted number
     */
    public CharSequence format(NumericValue value, DecimalSymbols dfs, String minusSign) {

      // System.err.println("Formatting " + value);

      if (value.isNaN()) {
        return dfs.NaN; // changed by W3C Bugzilla 2712
      }

      if ((value instanceof DoubleValue || value instanceof FloatValue)
          && Double.isInfinite(value.getDoubleValue())) {
        return minusSign + prefix + dfs.infinity + suffix;
      }

      int multiplier = 1;
      if (isPercent) {
        multiplier = 100;
      } else if (isPerMille) {
        multiplier = 1000;
      }

      if (multiplier != 1) {
        try {
          // value = value.arithmetic(Token.MULT, new Int64Value(multiplier), null);
          value =
              (NumericValue)
                  ArithmeticExpression.compute(
                      value, Calculator.TIMES, new Int64Value(multiplier), null);
        } catch (XPathException e) {
          value = new DoubleValue(value.getDoubleValue() * multiplier);
        }
      }

      FastStringBuffer sb = new FastStringBuffer(20);
      if (value instanceof DoubleValue || value instanceof FloatValue) {
        BigDecimal dec = adjustToDecimal(value.getDoubleValue(), 2);
        formatDecimal(dec, sb);

        // formatDouble(value.getDoubleValue(), sb);

      } else if (value instanceof Int64Value || value instanceof BigIntegerValue) {
        formatInteger(value, sb);

      } else if (value instanceof DecimalValue) {
        //noinspection RedundantCast
        formatDecimal(((DecimalValue) value).getDecimalValue(), sb);
      }

      // System.err.println("Justified number: " + sb.toString());

      // Map the digits and decimal point to use the selected characters

      int[] ib = StringValue.expand(sb);
      int ibused = ib.length;
      int point = sb.indexOf('.');
      if (point == -1) {
        point = sb.length();
      } else {
        ib[point] = dfs.decimalSeparator;

        // If there is no fractional part, delete the decimal point
        if (maxFractionPartSize == 0) {
          ibused--;
        }
      }

      // Map the digits

      if (dfs.zeroDigit != '0') {
        int newZero = dfs.zeroDigit;
        for (int i = 0; i < ibused; i++) {
          int c = ib[i];
          if (c >= '0' && c <= '9') {
            ib[i] = (c - '0' + newZero);
          }
        }
      }

      // Add the whole-part grouping separators

      if (wholePartGroupingPositions != null) {
        if (wholePartGroupingPositions.length == 1) {
          // grouping separators are at regular positions
          int g = wholePartGroupingPositions[0];
          int p = point - g;
          while (p > 0) {
            ib = insert(ib, ibused++, dfs.groupingSeparator, p);
            // sb.insert(p, unicodeChar(dfs.groupingSeparator));
            p -= g;
          }
        } else {
          // grouping separators are at irregular positions
          for (int i = 0; i < wholePartGroupingPositions.length; i++) {
            int p = point - wholePartGroupingPositions[i];
            if (p > 0) {
              ib = insert(ib, ibused++, dfs.groupingSeparator, p);
              // sb.insert(p, unicodeChar(dfs.groupingSeparator));
            }
          }
        }
      }

      // Add the fractional-part grouping separators

      if (fractionalPartGroupingPositions != null) {
        // grouping separators are at irregular positions.
        for (int i = 0; i < fractionalPartGroupingPositions.length; i++) {
          int p = point + 1 + fractionalPartGroupingPositions[i] + i;
          if (p < ibused - 1) {
            ib = insert(ib, ibused++, dfs.groupingSeparator, p);
            // sb.insert(p, dfs.groupingSeparator);
          } else {
            break;
          }
        }
      }

      // System.err.println("Grouped number: " + sb.toString());

      // sb.insert(0, prefix);
      // sb.insert(0, minusSign);
      // sb.append(suffix);
      FastStringBuffer res =
          new FastStringBuffer(prefix.length() + minusSign.length() + suffix.length() + ibused);
      res.append(minusSign);
      res.append(prefix);
      res.append(StringValue.contract(ib, ibused));
      res.append(suffix);
      return res;
    }
예제 #5
0
 /**
  * Convert a double to a BigDecimal. In general there will be several BigDecimal values that are
  * equal to the supplied value, and the one we want to choose is the one with fewest non-zero
  * digits. The algorithm used is rather pragmatic: look for a string of zeroes or nines, try
  * rounding the number down or up as approriate, then convert the adjusted value to a double to
  * see if it's equal to the original: if not, use the original value unchanged.
  *
  * @param value the double to be converted
  * @param precision 2 for a double, 1 for a float
  * @return the result of conversion to a double
  */
 public static BigDecimal adjustToDecimal(double value, int precision) {
   final String zeros = (precision == 1 ? "00000" : "000000000");
   final String nines = (precision == 1 ? "99999" : "999999999");
   BigDecimal initial = new BigDecimal(value);
   BigDecimal trial = null;
   FastStringBuffer fsb = new FastStringBuffer(20);
   DecimalValue.decimalToString(initial, fsb);
   String s = fsb.toString();
   int start = (s.charAt(0) == '-' ? 1 : 0);
   int p = s.indexOf(".");
   int i = s.lastIndexOf(zeros);
   if (i > 0) {
     if (p < 0 || i < p) {
       // we're in the integer part
       // try replacing all following digits with zeros and seeing if we get the same double back
       FastStringBuffer sb = new FastStringBuffer(s.length());
       sb.append(s.substring(0, i));
       for (int n = i; n < s.length(); n++) {
         sb.append(s.charAt(n) == '.' ? '.' : '0');
       }
       trial = new BigDecimal(sb.toString());
     } else {
       // we're in the fractional part
       // try truncating the number before the zeros and seeing if we get the same double back
       trial = new BigDecimal(s.substring(0, i));
     }
   } else {
     i = s.indexOf(nines);
     if (i >= 0) {
       if (i == start) {
         // number starts with 99999... or -99999. Try rounding up to 100000.. or -100000...
         FastStringBuffer sb = new FastStringBuffer(s.length() + 1);
         if (start == 1) {
           sb.append('-');
         }
         sb.append('1');
         for (int n = start; n < s.length(); n++) {
           sb.append(s.charAt(n) == '.' ? '.' : '0');
         }
         trial = new BigDecimal(sb.toString());
       } else {
         // try rounding up
         while (i >= 0 && (s.charAt(i) == '9' || s.charAt(i) == '.')) {
           i--;
         }
         if (i < 0 || s.charAt(i) == '-') {
           return initial; // can't happen: we've already handled numbers starting 99999..
         } else if (p < 0 || i < p) {
           // we're in the integer part
           FastStringBuffer sb = new FastStringBuffer(s.length());
           sb.append(s.substring(0, i));
           sb.append((char) ((int) s.charAt(i) + 1));
           for (int n = i; n < s.length(); n++) {
             sb.append(s.charAt(n) == '.' ? '.' : '0');
           }
           trial = new BigDecimal(sb.toString());
         } else {
           // we're in the fractional part - can ignore following digits
           String s2 = s.substring(0, i) + (char) ((int) s.charAt(i) + 1);
           trial = new BigDecimal(s2);
         }
       }
     }
   }
   if (trial != null
       && (precision == 1 ? trial.floatValue() == value : trial.doubleValue() == value)) {
     return trial;
   } else {
     return initial;
   }
 }
예제 #6
0
  public static PooledXPathExpression getXPathExpression(
      PropertyContext propertyContext,
      List<Item> contextItems,
      int contextPosition,
      String xpathString,
      Map<String, String> prefixToURIMap,
      Map<String, ValueRepresentation> variableToValueMap,
      FunctionLibrary functionLibrary,
      String baseURI,
      boolean isAvt,
      boolean testNoCache,
      LocationData locationData) {

    try {
      // Find pool from cache
      final Long validity = (long) 0;
      final Cache cache = ObjectCache.instance(XPATH_CACHE_NAME, XPATH_CACHE_DEFAULT_SIZE);
      final FastStringBuffer cacheKeyString = new FastStringBuffer(xpathString);
      {
        if (functionLibrary != null) { // This is ok
          cacheKeyString.append('|');
          cacheKeyString.append(Integer.toString(functionLibrary.hashCode()));
        }
      }
      {
        // NOTE: Mike Kay confirms on 2007-07-04 that compilation depends on the namespace context,
        // so we need
        // to use it as part of the cache key.

        // TODO: PERF: It turns out that this takes a lot of time. Now that the namespace
        // information is computed statically, we can do better.
        if (DEBUG_TEST_KEY_OPTIMIZATION) {
          // PERF TEST ONLY
          cacheKeyString.append("|DUMMYNSVAR|");
        } else {

          if (prefixToURIMap != null) {
            final Map<String, String> sortedMap =
                (prefixToURIMap instanceof TreeMap)
                    ? prefixToURIMap
                    : new TreeMap<String, String>(
                        prefixToURIMap); // this should make sure we always get the keys in the same
                                         // order
            for (Map.Entry<String, String> currentEntry : sortedMap.entrySet()) {
              cacheKeyString.append('|');
              cacheKeyString.append(currentEntry.getKey());
              cacheKeyString.append('=');
              cacheKeyString.append(currentEntry.getValue());
            }
          }
        }
      }
      if (DEBUG_TEST_KEY_OPTIMIZATION) {
        // PERF TEST ONLY
        // NOP
      } else {

        if (variableToValueMap != null && variableToValueMap.size() > 0) {
          // There are some variables in scope. They must be part of the key
          // TODO: Put this in static state as this can be determined statically once and for all
          for (final String variableName : variableToValueMap.keySet()) {
            cacheKeyString.append('|');
            cacheKeyString.append(variableName);
          }
        }
      }
      {
        // Add this to the key as evaluating "name" as XPath or as AVT is very different!
        cacheKeyString.append('|');
        cacheKeyString.append(Boolean.toString(isAvt));
      }

      // TODO: Add baseURI to cache key (currently, baseURI is pretty much unused)

      final Set<String> variableNames =
          (variableToValueMap != null) ? variableToValueMap.keySet() : null;
      final PooledXPathExpression expr;
      if (testNoCache) {
        // For testing only: don't get expression from cache
        final Object o =
            new XFormsCachePoolableObjetFactory(
                    null,
                    xpathString,
                    prefixToURIMap,
                    variableNames,
                    functionLibrary,
                    baseURI,
                    isAvt,
                    false,
                    locationData)
                .makeObject();
        expr = (PooledXPathExpression) o;
      } else {
        // Get or create pool
        final InternalCacheKey cacheKey =
            new InternalCacheKey("XPath Expression2", cacheKeyString.toString());
        ObjectPool pool = (ObjectPool) cache.findValid(propertyContext, cacheKey, validity);
        if (pool == null) {
          pool =
              createXPathPool(
                  xpathString,
                  prefixToURIMap,
                  variableNames,
                  functionLibrary,
                  baseURI,
                  isAvt,
                  locationData);
          cache.add(propertyContext, cacheKey, validity, pool);
        }

        // Get object from pool
        final Object o = pool.borrowObject();
        expr = (PooledXPathExpression) o;
      }

      // Set context items and position
      expr.setContextItems(contextItems, contextPosition);

      // Set variables
      expr.setVariables(variableToValueMap);

      return expr;
    } catch (Exception e) {
      throw handleXPathException(e, xpathString, "preparing XPath expression", locationData);
    }
  }
예제 #7
0
  /** Evaluate as an expression. */
  public Item evaluateItem(XPathContext context) throws XPathException {
    if (isLazyConstruction()
        && (context.getConfiguration().areAllNodesUntyped()
            || (validation == Validation.PRESERVE && getSchemaType() == null))) {
      return new UnconstructedDocument(this, context);
    } else {
      Controller controller = context.getController();
      DocumentInfo root;
      if (textOnly) {
        CharSequence textValue;
        if (constantText != null) {
          textValue = constantText;
        } else {
          FastStringBuffer sb = new FastStringBuffer(100);
          SequenceIterator iter = content.iterate(context);
          while (true) {
            Item item = iter.next();
            if (item == null) break;
            sb.append(item.getStringValueCS());
          }
          textValue = sb.condense();
        }
        root = new TextFragmentValue(textValue, getBaseURI());
        ((TextFragmentValue) root).setConfiguration(controller.getConfiguration());
      } else {
        try {
          XPathContext c2 = context.newMinorContext();
          c2.setOrigin(this);

          Builder builder = controller.makeBuilder();
          // builder.setSizeParameters(treeSizeParameters);
          builder.setLineNumbering(controller.getConfiguration().isLineNumbering());

          // receiver.setSystemId(getBaseURI());
          builder.setBaseURI(getBaseURI());
          builder.setTiming(false);

          PipelineConfiguration pipe = controller.makePipelineConfiguration();
          pipe.setHostLanguage(getHostLanguage());
          // pipe.setBaseURI(baseURI);
          builder.setPipelineConfiguration(pipe);

          c2.changeOutputDestination(
              null, builder, false, getHostLanguage(), validation, getSchemaType());
          Receiver out = c2.getReceiver();
          out.open();
          out.startDocument(0);

          content.process(c2);

          out.endDocument();
          out.close();

          root = (DocumentInfo) builder.getCurrentRoot();
        } catch (XPathException e) {
          e.maybeSetLocation(this);
          e.maybeSetContext(context);
          throw e;
        }
      }
      return root;
    }
  }