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.annotation.Annotation;
019import java.lang.management.*;
020import java.lang.reflect.InvocationTargetException;
021import java.lang.reflect.Method;
022import java.math.BigDecimal;
023import java.math.MathContext;
024import java.sql.Statement;
025import java.util.*;
026import java.util.regex.Pattern;
027
028// Only in Java5 and above
029
030/**
031 * Implementation of {@link UtilCompatible} which runs in
032 * JDK 1.5.
033 *
034 * <p>Prior to JDK 1.5, this class should never be loaded. Applications should
035 * instantiate this class via {@link Class#forName(String)} or better, use
036 * methods in {@link mondrian.olap.Util}, and not instantiate it at all.
037 *
038 * @author jhyde
039 * @since Feb 5, 2007
040 */
041public class UtilCompatibleJdk15 implements UtilCompatible {
042    private static final Logger LOGGER = Logger.getLogger(Util.class);
043
044    /**
045     * This generates a BigDecimal with a precision reflecting
046     * the precision of the input double.
047     *
048     * @param d input double
049     * @return BigDecimal
050     */
051    public BigDecimal makeBigDecimalFromDouble(double d) {
052        return new BigDecimal(d, MathContext.DECIMAL64);
053    }
054
055    public String quotePattern(String s) {
056        return Pattern.quote(s);
057    }
058
059    @SuppressWarnings("unchecked")
060    public <T> T getAnnotation(
061        Method method, String annotationClassName, T defaultValue)
062    {
063        try {
064            Class<? extends Annotation> annotationClass =
065                (Class<? extends Annotation>)
066                    Class.forName(annotationClassName);
067            if (method.isAnnotationPresent(annotationClass)) {
068                final Annotation annotation =
069                    method.getAnnotation(annotationClass);
070                final Method method1 =
071                    annotation.getClass().getMethod("value");
072                return (T) method1.invoke(annotation);
073            }
074        } catch (IllegalAccessException e) {
075            return defaultValue;
076        } catch (InvocationTargetException e) {
077            return defaultValue;
078        } catch (NoSuchMethodException e) {
079            return defaultValue;
080        } catch (ClassNotFoundException e) {
081            return defaultValue;
082        }
083        return defaultValue;
084    }
085
086    public String generateUuidString() {
087        return UUID.randomUUID().toString();
088    }
089
090    public <T> T compileScript(
091        Class<T> iface,
092        String script,
093        String engineName)
094    {
095        throw new UnsupportedOperationException(
096            "Scripting not supported until Java 1.6");
097    }
098
099    public <T> void threadLocalRemove(ThreadLocal<T> threadLocal) {
100        threadLocal.remove();
101    }
102
103    public Util.MemoryInfo getMemoryInfo() {
104        return new Util.MemoryInfo() {
105            protected final MemoryPoolMXBean TENURED_POOL =
106                findTenuredGenPool();
107
108            public Util.MemoryInfo.Usage get() {
109                final MemoryUsage memoryUsage = TENURED_POOL.getUsage();
110                return new Usage() {
111                    public long getUsed() {
112                        return memoryUsage.getUsed();
113                    }
114
115                    public long getCommitted() {
116                        return memoryUsage.getCommitted();
117                    }
118
119                    public long getMax() {
120                        return memoryUsage.getMax();
121                    }
122                };
123            }
124        };
125    }
126
127    public Timer newTimer(String name, boolean isDaemon) {
128        return new Timer(name, isDaemon);
129    }
130
131    private static MemoryPoolMXBean findTenuredGenPool() {
132        for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
133            if (pool.getType() == MemoryType.HEAP) {
134                return pool;
135            }
136        }
137        throw new AssertionError("Could not find tenured space");
138    }
139
140    public void cancelStatement(Statement stmt) {
141        try {
142            stmt.cancel();
143        } catch (Exception e) {
144            // We can't call stmt.isClosed(); the method doesn't exist until
145            // JDK 1.6. So, mask out the error.
146            if (e.getMessage().equals(
147                    "org.apache.commons.dbcp.DelegatingStatement is closed."))
148            {
149                return;
150            }
151            if (LOGGER.isDebugEnabled()) {
152                LOGGER.debug(
153                    MondrianResource.instance()
154                        .ExecutionStatementCleanupException
155                            .ex(e.getMessage(), e),
156                    e);
157            }
158        }
159    }
160
161    public <T> Set<T> newIdentityHashSet() {
162        return Util.newIdentityHashSetFake();
163    }
164
165    public <T extends Comparable<T>> int binarySearch(
166        T[] ts, int start, int end, T t)
167    {
168        final int i = Collections.binarySearch(
169            Arrays.asList(ts).subList(start, end), t,
170            RolapUtil.ROLAP_COMPARATOR);
171        return (i < 0) ? (i - start) : (i + start);
172    }
173}
174
175// End UtilCompatibleJdk15.java