/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde licenses this file to you under the Apache License,
// Version 2.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
package net.hydromatic.optiq.runtime;

import net.hydromatic.linq4j.function.Function1;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Collection of hooks that can be set by observers and are executed at various
 * parts of the query preparation process.
 *
 * <p>For testing and debugging rather than for end-users.</p>
 */
public enum Hook {
    /** Called with the generated Java plan, just before it is compiled by
     * Janino. */
    JAVA_PLAN;

    private final List<Function1<Object, Object>> handlers =
        new CopyOnWriteArrayList<Function1<Object, Object>>();

    /** Adds a handler for this Hook.
     *
     * <p>Returns an {@link AutoCloseable} so that you can use the following
     * try-finally pattern to prevent leaks:</p>
     *
     * <blockquote><pre>
     *     final AutoCloseable closeable = Hook.FOO.add(HANDLER);
     *     try {
     *         ...
     *     } finally {
     *         closeable.close();
     *     }</pre>
     * </blockquote>
     */
    public Closeable add(final Function1<Object, Object> handler) {
        handlers.add(handler);
        return new Closeable() {
            public void close() {
                remove(handler);
            }
        };
    }

    /** Removes a handler from this Hook. */
    private boolean remove(Function1 handler) {
        return handlers.remove(handler);
    }

    /** Runs all handlers registered for this Hook, with the given argument. */
    public void run(Object arg) {
        for (Function1<Object, Object> handler : handlers) {
            handler.apply(arg);
        }
    }

    /** Removes a Hook after use. */
    public interface Closeable extends AutoCloseable {
        void close(); // override, removing "throws"
    }
}

// End Hook.java

@@ -1452,17 +1452,16 @@
 ns a
-n
  %7B@link 
 Auto
@@ -1456,20 +1456,21 @@
  %7B@link 
-Auto
+Hook.
 Closeabl
@@ -1604,20 +1604,21 @@
   final 
-Auto
+Hook.
 Closeabl
@@ -2424,16 +2424,196 @@
 ter use.
+%0A     *%0A     * %3Cp%3ENote: Although it would be convenient, this interface cannot extend%0A     * %7B@code AutoCloseable%7D while Optiq maintains compatibility with%0A     * JDK 1.6.%3C/p%3E%0A    
  */%0A    
@@ -2639,16 +2639,18 @@
 oseable 
+/*
 extends 
@@ -2662,16 +2662,18 @@
 loseable
+*/
  %7B%0A     

Fix for JDK 1.6. (AutoCloseable does not exist until JDK 1.7.)