001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2007-2013 Pentaho
008// All Rights Reserved.
009*/
010package mondrian.util;
011
012import mondrian.olap.Util;
013import mondrian.resource.MondrianResource;
014import mondrian.rolap.RolapUtil;
015
016import org.apache.log4j.Logger;
017
018import java.lang.reflect.Method;
019import java.math.BigDecimal;
020import java.sql.Statement;
021import java.util.*;
022
023/**
024 * Implementation of {@link UtilCompatible} which runs in
025 * JDK 1.4.
026 *
027 * <p>The code uses JDK 1.5 constructs such as generics and for-each loops,
028 * but retroweaver can convert these. It does not use
029 * <code>java.util.EnumSet</code>, which is important, because retroweaver has
030 * trouble with this.
031 *
032 * @author jhyde
033 * @since Feb 5, 2007
034 */
035public class UtilCompatibleJdk14 implements UtilCompatible {
036    private static final Logger LOGGER = Logger.getLogger(Util.class);
037    private static String previousUuid = "";
038    private static final String UUID_BASE =
039        Long.toHexString(new Random().nextLong());
040
041    /**
042     * This generates a BigDecimal that can have a precision that does
043     * not reflect the precision of the input double.
044     *
045     * @param d input double
046     * @return BigDecimal
047     */
048    public BigDecimal makeBigDecimalFromDouble(double d) {
049        return new BigDecimal(d);
050    }
051
052    public String quotePattern(String s) {
053        int slashEIndex = s.indexOf("\\E");
054        if (slashEIndex == -1) {
055            return "\\Q" + s + "\\E";
056        }
057        StringBuilder sb = new StringBuilder(s.length() * 2);
058        sb.append("\\Q");
059        int current = 0;
060        while ((slashEIndex = s.indexOf("\\E", current)) != -1) {
061            sb.append(s.substring(current, slashEIndex));
062            current = slashEIndex + 2;
063            sb.append("\\E\\\\E\\Q");
064        }
065        sb.append(s.substring(current, s.length()));
066        sb.append("\\E");
067        return sb.toString();
068    }
069
070    public <T> T getAnnotation(
071        Method method, String annotationClassName, T defaultValue)
072    {
073        return defaultValue;
074    }
075
076    public String generateUuidString() {
077        return generateUuidStringStatic();
078    }
079
080    public static synchronized String generateUuidStringStatic() {
081        while (true) {
082            String uuid =
083                UUID_BASE
084                + Long.toHexString(System.currentTimeMillis());
085            if (!uuid.equals(previousUuid)) {
086                previousUuid = uuid;
087                return uuid;
088            }
089            try {
090                Thread.sleep(1);
091            } catch (InterruptedException e) {
092                throw new RuntimeException(e);
093            }
094        }
095    }
096
097    public <T> T compileScript(
098        Class<T> iface,
099        String script,
100        String engineName)
101    {
102        throw new UnsupportedOperationException(
103            "Scripting not supported until Java 1.6");
104    }
105
106    public <T> void threadLocalRemove(ThreadLocal<T> threadLocal) {
107        // nothing: ThreadLocal.remove() does not exist until JDK 1.5
108    }
109
110    public Util.MemoryInfo getMemoryInfo() {
111        return new Util.MemoryInfo() {
112            public Usage get() {
113                return new Usage() {
114                    public long getUsed() {
115                        return 0;
116                    }
117
118                    public long getCommitted() {
119                        return 0;
120                    }
121
122                    public long getMax() {
123                        return 0;
124                    }
125                };
126            }
127        };
128    }
129
130    public Timer newTimer(String name, boolean isDaemon) {
131        return new Timer(isDaemon);
132    }
133
134    public void cancelStatement(Statement stmt) {
135        try {
136            stmt.cancel();
137        } catch (Exception e) {
138            // We can't call stmt.isClosed(); the method doesn't exist until
139            // JDK 1.6. So, mask out the error.
140            if (e.getMessage().equals(
141                    "org.apache.commons.dbcp.DelegatingStatement is closed."))
142            {
143                return;
144            }
145            if (LOGGER.isDebugEnabled()) {
146                LOGGER.debug(
147                    MondrianResource.instance()
148                        .ExecutionStatementCleanupException
149                            .ex(e.getMessage(), e),
150                    e);
151            }
152        }
153    }
154
155    public <T> Set<T> newIdentityHashSet() {
156        return Util.newIdentityHashSetFake();
157    }
158
159    public <T extends Comparable<T>> int binarySearch(
160        T[] ts, int start, int end, T t)
161    {
162        return Collections.binarySearch(
163            Arrays.asList(ts).subList(start, end), t,
164            RolapUtil.ROLAP_COMPARATOR);
165    }
166}
167
168// End UtilCompatibleJdk14.java