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(); }
/** * 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; } }
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); } }