jaroslav@123: /** jaroslav@123: * HTML via Java(tm) Language Bindings jaroslav@123: * Copyright (C) 2013 Jaroslav Tulach jaroslav@123: * jaroslav@123: * This program is free software: you can redistribute it and/or modify jaroslav@123: * it under the terms of the GNU General Public License as published by jaroslav@123: * the Free Software Foundation, version 2 of the License. jaroslav@123: * jaroslav@123: * This program is distributed in the hope that it will be useful, jaroslav@123: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@123: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@123: * GNU General Public License for more details. apidesign.org jaroslav@123: * designates this particular file as subject to the jaroslav@123: * "Classpath" exception as provided by apidesign.org jaroslav@123: * in the License file that accompanied this code. jaroslav@123: * jaroslav@123: * You should have received a copy of the GNU General Public License jaroslav@123: * along with this program. Look for COPYING file in the top folder. jaroslav@123: * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException jaroslav@123: */ jaroslav@123: package org.apidesign.html.boot.spi; jaroslav@123: jaroslav@322: import java.io.Closeable; jaroslav@163: import java.io.Reader; jaroslav@123: import java.net.URL; jaroslav@322: import net.java.html.js.JavaScriptBody; jaroslav@309: import org.apidesign.html.boot.impl.FnContext; jaroslav@123: jaroslav@289: /** Represents single JavaScript function that can be invoked. jaroslav@289: * Created via {@link Presenter#defineFn(java.lang.String, java.lang.String...)}. jaroslav@123: * jaroslav@123: * @author Jaroslav Tulach jaroslav@123: */ jaroslav@123: public abstract class Fn { jaroslav@288: private final Presenter presenter; jaroslav@288: jaroslav@289: /** jaroslav@289: * @deprecated Ineffective as of 0.6. jaroslav@289: * Provide a presenter via {@link #Fn(org.apidesign.html.boot.spi.Fn.Presenter)} jaroslav@289: * constructor jaroslav@289: */ jaroslav@289: @Deprecated jaroslav@289: protected Fn() { jaroslav@289: this(null); jaroslav@289: } jaroslav@289: jaroslav@289: /** Creates new function object and associates it with given presenter. jaroslav@289: * jaroslav@289: * @param presenter the browser presenter associated with this function jaroslav@289: * @since 0.6 jaroslav@289: */ jaroslav@288: protected Fn(Presenter presenter) { jaroslav@288: this.presenter = presenter; jaroslav@288: } jaroslav@289: jaroslav@289: /** True, if currently active presenter is the same as presenter this jaroslav@289: * function has been created for via {@link #Fn(org.apidesign.html.boot.spi.Fn.Presenter)}. jaroslav@289: * jaroslav@289: * @return true, if proper presenter is used jaroslav@289: */ jaroslav@288: public final boolean isValid() { jaroslav@309: return FnContext.currentPresenter() == presenter; jaroslav@288: } jaroslav@288: jaroslav@323: /** Helper method to check if the provided instance is valid function. jaroslav@323: * Checks if the parameter is non-null and if so, does {@link #isValid()} jaroslav@323: * check. jaroslav@323: * jaroslav@323: * @param fnOrNull function or null jaroslav@323: * @return true if the parameter is non-null and valid jaroslav@323: * @since 0.7 jaroslav@323: */ jaroslav@323: public static boolean isValid(Fn fnOrNull) { jaroslav@323: return fnOrNull != null && fnOrNull.isValid(); jaroslav@323: } jaroslav@323: jaroslav@323: /** Helper method to find current presenter and ask it to define new jaroslav@323: * function by calling {@link Presenter#defineFn(java.lang.String, java.lang.String...)}. jaroslav@323: * jaroslav@323: * @param caller the class who wishes to define the function jaroslav@323: * @param code the body of the function (can reference this and names variables) jaroslav@323: * @param names names of individual parameters jaroslav@323: * @return the function object that can be {@link Fn#invoke(java.lang.Object, java.lang.Object...) invoked} jaroslav@323: * @since 0.7 jaroslav@323: */ jaroslav@323: public static Fn define(Class caller, String code, String... names) { jaroslav@323: return FnContext.currentPresenter().defineFn(code, names); jaroslav@323: } jaroslav@323: jaroslav@322: /** The currently active presenter. jaroslav@322: * jaroslav@322: * @return the currently active presenter or null jaroslav@322: * @since 0.7 jaroslav@322: */ jaroslav@322: public static Presenter activePresenter() { jaroslav@322: return FnContext.currentPresenter(); jaroslav@322: } jaroslav@322: jaroslav@322: /** Activates given presenter. Used by the code generated by jaroslav@322: * {@link JavaScriptBody} annotation: jaroslav@322: *
jaroslav@322:      * try ({@link Closeable} c = Fn.activate(presenter)) {
jaroslav@322:      *   doCallsInPresenterContext();
jaroslav@322:      * }
jaroslav@322:      * 
jaroslav@322: * jaroslav@322: * @param p the presenter that should be active until closable is closed jaroslav@322: * @return the closable to close jaroslav@322: * @since 0.7 jaroslav@322: */ jaroslav@322: public static Closeable activate(Presenter p) { jaroslav@322: return FnContext.activate(p); jaroslav@322: } jaroslav@322: jaroslav@289: /** Invokes the defined function with specified this and jaroslav@289: * appropriate arguments. jaroslav@289: * jaroslav@289: * @param thiz the meaning of this inside of the JavaScript jaroslav@289: * function - can be null jaroslav@289: * @param args arguments for the function jaroslav@289: * @return return value from the function jaroslav@289: * @throws Exception if something goes wrong, as exception may be thrown jaroslav@289: */ jaroslav@289: public abstract Object invoke(Object thiz, Object... args) throws Exception; jaroslav@289: jaroslav@289: /** The representation of a presenter - usually a browser window. jaroslav@315: * Should be provided by a library included in the application and registered jaroslav@315: * in META-INF/services, for example with jaroslav@315: * @ServiceProvider(service = Fn.Presenter.class) annotation. jaroslav@289: */ jaroslav@127: public interface Presenter { jaroslav@289: /** Creates new function with given parameter names and provided body. jaroslav@289: * jaroslav@289: * @param code the body of the function. Can refer to variables named jaroslav@289: * as names jaroslav@289: * @param names names of parameters of the function - these will be jaroslav@289: * available when the code body executes jaroslav@289: * jaroslav@289: * @return function that can be later invoked jaroslav@289: */ jaroslav@127: public Fn defineFn(String code, String... names); jaroslav@289: jaroslav@289: /** Opens the browser, loads provided page and when the jaroslav@289: * page is ready, it calls back to the provider runnable. jaroslav@289: * jaroslav@289: * @param page the URL for the page to display jaroslav@289: * @param onPageLoad callback when the page is ready jaroslav@289: */ jaroslav@128: public void displayPage(URL page, Runnable onPageLoad); jaroslav@289: jaroslav@289: /** Loads a script into the browser JavaScript interpreter and jaroslav@289: * executes it. jaroslav@289: * @param code the script to execute jaroslav@289: * @throws Exception if something goes wrong, throw an exception jaroslav@289: */ jaroslav@163: public void loadScript(Reader code) throws Exception; jaroslav@123: } jaroslav@123: }