util.java

来自「数据仓库展示程序」· Java 代码 · 共 1,344 行 · 第 1/4 页

JAVA
1,344
字号
/*
// $Id: //open/mondrian/src/main/mondrian/olap/Util.java#56 $
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// (C) Copyright 2001-2005 Kana Software, Inc. and others.
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
// jhyde, 6 August, 2001
*/

package mondrian.olap;

import org.apache.log4j.Logger;
import org.eigenbase.xom.XOMUtil;

import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

import mondrian.olap.fun.FunUtil;
import mondrian.resource.MondrianResource;
import mondrian.util.Format;

/**
 * Utility functions used throughout mondrian. All methods are static.
 *
 * @author jhyde
 * @since 6 August, 2001
 * @version $Id: //open/mondrian/src/main/mondrian/olap/Util.java#56 $
 **/
public class Util extends XOMUtil {

    public static final String nl = System.getProperty("line.separator");

    private static final Logger LOGGER = Logger.getLogger(Util.class);

    public static final Object nullValue = new NullCellValue();

    /**
     * Cumulative time spent accessing the database.
     */
    private static long databaseMillis = 0;

    /**
     * Random number generator to provide seed for other random number
     * generators.
     */
    private static final Random metaRandom =
            createRandom(MondrianProperties.instance().TestSeed.get());

    /**
     * Store of format-locales culled from various locales' instances of
     * {@link mondrian.resource.MondrianResource}.
     *
     * <p>Initializing it here should ensure that the callback is set before 
     * {@link mondrian.util.Format} is first used for the first time.
     */
    private static final Format.LocaleFormatFactory localeFormatFactory =
            createLocaleFormatFactory();

    /**
     * Creates a {@link Format.LocaleFormatFactory} which derives locale
     * information from {@link MondrianResource}, and registers it as the
     * default factory.
     */
    private static Format.LocaleFormatFactory createLocaleFormatFactory() {
        Format.LocaleFormatFactory factory = new Format.LocaleFormatFactory() {
            public Format.FormatLocale get(Locale locale) {
                MondrianResource res = MondrianResource.instance(locale);
                if (res == null ||
                        !res.getLocale().equals(locale)) {
                    return null;
                }
                char thousandSeparator = res.FormatThousandSeparator.str().charAt(0);
                char decimalPlaceholder = res.FormatDecimalPlaceholder.str().charAt(0);
                String dateSeparator = res.FormatDateSeparator.str();
                String timeSeparator = res.FormatTimeSeparator.str();
                String currencySymbol = res.FormatCurrencySymbol.str();
                String currencyFormat = res.FormatCurrencyFormat.str();
                String[] daysOfWeekShort = {
                    res.FormatShortDaysSun.str(),
                    res.FormatShortDaysMon.str(),
                    res.FormatShortDaysTue.str(),
                    res.FormatShortDaysWed.str(),
                    res.FormatShortDaysThu.str(),
                    res.FormatShortDaysFri.str(),
                    res.FormatShortDaysSat.str(),
                };
                String[] daysOfWeekLong = {
                    res.FormatLongDaysSunday.str(),
                    res.FormatLongDaysMonday.str(),
                    res.FormatLongDaysTuesday.str(),
                    res.FormatLongDaysWednesday.str(),
                    res.FormatLongDaysThursday.str(),
                    res.FormatLongDaysFriday.str(),
                    res.FormatLongDaysSaturday.str(),
                };
                String[] monthsShort = {
                    res.FormatShortMonthsJan.str(),
                    res.FormatShortMonthsFeb.str(),
                    res.FormatShortMonthsMar.str(),
                    res.FormatShortMonthsApr.str(),
                    res.FormatShortMonthsMay.str(),
                    res.FormatShortMonthsJun.str(),
                    res.FormatShortMonthsJul.str(),
                    res.FormatShortMonthsAug.str(),
                    res.FormatShortMonthsSep.str(),
                    res.FormatShortMonthsOct.str(),
                    res.FormatShortMonthsNov.str(),
                    res.FormatShortMonthsDec.str(),
                };
                String[] monthsLong = {
                    res.FormatLongMonthsJanuary.str(),
                    res.FormatLongMonthsFebruary.str(),
                    res.FormatLongMonthsMarch.str(),
                    res.FormatLongMonthsApril.str(),
                    res.FormatLongMonthsMay.str(),
                    res.FormatLongMonthsJune.str(),
                    res.FormatLongMonthsJuly.str(),
                    res.FormatLongMonthsAugust.str(),
                    res.FormatLongMonthsSeptember.str(),
                    res.FormatLongMonthsOctober.str(),
                    res.FormatLongMonthsNovember.str(),
                    res.FormatLongMonthsDecember.str(),
                };
                return Format.createLocale(
                        thousandSeparator, decimalPlaceholder, dateSeparator,
                        timeSeparator, currencySymbol, currencyFormat,
                        daysOfWeekShort, daysOfWeekLong, monthsShort,
                        monthsLong, locale);
            }
        };
        Format.setLocaleFormatFactory(factory);
        return factory;
    }

    /**
     * Encodes string for MDX (escapes ] as ]] inside a name).
     */
    public static String mdxEncodeString(String st) {
        StringBuffer retString = new StringBuffer(st.length() + 20);
        for (int i = 0; i < st.length(); i++) {
            char c = st.charAt(i);
            if ((c == ']') &&
                ((i+1) < st.length()) &&
                (st.charAt(i+1) != '.')) {

                retString.append(']'); //escaping character
            }
            retString.append(c);
        }
        return retString.toString();
    }


    /**
     * Converts a string into a double-quoted string.
     */
    public static String quoteForMdx(String val) {
        StringBuffer buf = new StringBuffer(val.length()+20);
        buf.append("\"");

        String s0 = replace(val, "\"", "\"\"");
        buf.append(s0);

        buf.append("\"");
        return buf.toString();
    }

    /**
     * Return string quoted in [...].  For example, "San Francisco" becomes
     * "[San Francisco]"; "a [bracketed] string" becomes
     * "[a [bracketed]] string]".
     */
    public static String quoteMdxIdentifier(String id) {
        StringBuffer buf = new StringBuffer(id.length() + 20);
        quoteMdxIdentifier(id, buf);
        return buf.toString();
    }

    public static void quoteMdxIdentifier(String id, StringBuffer buf) {
        buf.append('[');
        int start = buf.length();
        buf.append(id);
        replace(buf, start, "]", "]]");
        buf.append(']');
    }

    /**
     * Return identifiers quoted in [...].[...].  For example, {"Store", "USA",
     * "California"} becomes "[Store].[USA].[California]".
     **/
    public static String quoteMdxIdentifier(String[] ids) {
        StringBuffer sb = new StringBuffer(64);
        quoteMdxIdentifier(ids, sb);
        return sb.toString();
    }

    public static void quoteMdxIdentifier(String[] ids, StringBuffer sb) {
        for (int i = 0; i < ids.length; i++) {
            if (i > 0) {
                sb.append('.');
            }
            quoteMdxIdentifier(ids[i], sb);
        }
    }

    /**
     * Returns true if two objects are equal, or are both null.
     */
    public static boolean equals(Object s, Object t) {
        return (s == null) ? (t == null) : s.equals(t);
    }

    /**
     * Returns true if two strings are equal, or are both null.
     * Takes into account the {@link MondrianProperties#CaseSensitive case
     * sensitive option}.
     */
    public static boolean equals(String s, String t) {
        boolean caseSensitive = MondrianProperties.instance().CaseSensitive.get();
        return (s == null) ?
                (t == null) :
                (caseSensitive ? s.equals(t) : s.equalsIgnoreCase(t));
    }

    /**
     * Returns a string with every occurrence of a seek string replaced with
     * another.
     */
    public static String replace(String s, String find, String replace) {
        // let's be optimistic
        int found = s.indexOf(find);
        if (found == -1) {
            return s;
        }
        StringBuffer sb = new StringBuffer(s.length() + 20);
        int start = 0;
        char[] chars = s.toCharArray();
        final int step = find.length();
        if (step == 0) {
            // Special case where find is "".
            sb.append(s);
            replace(sb, 0, find, replace);
        } else {
            for (;;) {
                sb.append(chars, start, found-start);
                if (found == s.length()) {
                    break;
                }
                sb.append(replace);
                start = found + step;
                found = s.indexOf(find, start);
                if (found == -1) {
                    found = s.length();
                }
            }
        }
        return sb.toString();
    }

    /**
     * Replaces all occurrences of a string in a buffer with another.
     *
     * @param buf String buffer to act on
     * @param start
     * @param find String to find
     * @param replace String to replace it with
     * @return The string buffer
     */
    public static StringBuffer replace(
            StringBuffer buf,
            int start,
            String find, String replace) {

        // Search and replace from the end towards the start, to avoid O(n ^ 2)
        // copying if the string occurs very commonly.
        int findLength = find.length();
        if (findLength == 0) {
            // Special case where the seek string is empty.
            for (int j = buf.length(); j >= 0; --j) {
                buf.insert(j, replace);
            }
            return buf;
        }
        int k = buf.length();
        while (k > 0) {
            int i = buf.lastIndexOf(find, k);
            if (i < start) {
                break;
            }
            buf.replace(i, i + find.length(), replace);
            // Step back far enough to ensure that the beginning of the section
            // we just replaced does not cause a match.
            k = i - findLength;
        }
        return buf;
    }

    public static String[] explode(String s) {
        List list = new ArrayList();
        int i = 0;
        while (i < s.length()) {
            if (s.charAt(i) != '[') {
                throw MondrianResource.instance().MdxInvalidMember.ex(s);
            }
            // s may contain extra ']' characters, so look for a ']' followed
            // by a '.'
            int j = s.indexOf("].", i);
            if (j == -1) {
                j = s.lastIndexOf(']');
            }
            if (j <= i) {
                throw MondrianResource.instance().MdxInvalidMember.ex(s);
            }
            String sub = s.substring(i + 1, j);
            sub = replace(sub, "]]", "]");
            list.add(sub);
            if (j + 1 < s.length()) {
                if (s.charAt(j + 1) != '.') {
                    throw MondrianResource.instance().MdxInvalidMember.ex(s);
                }
            }
            i = j +  2;
        }
        String[] names = (String[]) list.toArray(new String[list.size()]);
        return names;
    }

    /**
     * Converts an array of name parts {"part1", "part2"} into a single string

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?