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) 2011-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.sql.Statement;
019import java.util.*;
020
021import javax.script.*;
022
023// Only in Java6 and above
024
025/**
026 * Implementation of {@link mondrian.util.UtilCompatible} that runs in
027 * JDK 1.6.
028 *
029 * <p>Prior to JDK 1.6, this class should never be loaded. Applications should
030 * instantiate this class via {@link Class#forName(String)} or better, use
031 * methods in {@link mondrian.olap.Util}, and not instantiate it at all.
032 *
033 * @author jhyde
034 */
035public class UtilCompatibleJdk16 extends UtilCompatibleJdk15 {
036    private static final Logger LOGGER =
037        Logger.getLogger(Util.class);
038
039    public <T> T compileScript(
040        Class<T> iface,
041        String script,
042        String engineName)
043    {
044        ScriptEngineManager factory = new ScriptEngineManager();
045        ScriptEngine engine = factory.getEngineByName(engineName);
046        try {
047            engine.eval(script);
048            Invocable inv = (Invocable) engine;
049            return inv.getInterface(iface);
050        } catch (ScriptException e) {
051            throw Util.newError(
052                e,
053                "Error while compiling script to implement " + iface + " SPI");
054        }
055    }
056
057    @Override
058    public void cancelStatement(Statement stmt) {
059        try {
060            // A call to statement.isClosed() would be great here, but in
061            // reality, some drivers will block on this check and the
062            // cancellation will never happen.  This is due to the
063            // non-thread-safe nature of JDBC and driver implementations. If a
064            // thread is currently using the statement, calls to isClosed() are
065            // synchronized internally and won't return until the query
066            // completes.
067            stmt.cancel();
068        } catch (Exception e) {
069            // We crush this one. A lot of drivers will complain if cancel() is
070            // called on a closed statement, but a call to isClosed() isn't
071            // thread safe and might block. See above.
072            if (LOGGER.isTraceEnabled()) {
073                LOGGER.trace(
074                    MondrianResource.instance()
075                        .ExecutionStatementCleanupException
076                            .ex(e.getMessage(), e),
077                    e);
078            }
079        }
080    }
081
082    @Override
083    public <T> Set<T> newIdentityHashSet() {
084        return Collections.newSetFromMap(
085            new IdentityHashMap<T, Boolean>());
086    }
087
088    public <T extends Comparable<T>> int binarySearch(
089        T[] ts, int start, int end, T t)
090    {
091        return Arrays.binarySearch(
092            ts, start, end, t,
093            RolapUtil.ROLAP_COMPARATOR);
094    }
095}
096
097// End UtilCompatibleJdk16.java