alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (AppleScriptEngine.java)

This example Java source code file (AppleScriptEngine.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

applescriptengine, bindings, filewriter, hashmap, ioexception, object, reader, scriptcontext, scriptenginefactory, scriptexception, securitymanager, simplescriptcontext, string, trace, util

The AppleScriptEngine.java Java example source code

/*
 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package apple.applescript;

import java.io.*;
import java.nio.file.Files;
import java.util.*;
import java.util.Map.Entry;

import javax.script.*;

/**
 * AppleScriptEngine implements JSR 223 for AppleScript on Mac OS X
 */
public class AppleScriptEngine implements ScriptEngine {
    private static native void initNative();

    private static native long createContextFrom(final Object object);
    private static native Object createObjectFrom(final long context);
    private static native void disposeContext(final long context);

    private static native long evalScript(final String script, long contextptr);
    private static native long evalScriptFromURL(final String filename, long contextptr);

    static {
        System.loadLibrary("AppleScriptEngine");
        initNative();
        TRACE("<static-init>");
    }

    static void checkSecurity() {
        final SecurityManager securityManager = System.getSecurityManager();
        if (securityManager != null) securityManager.checkExec("/usr/bin/osascript");
    }

    static void TRACE(final String str) {
//        System.out.println(AppleScriptEngine.class.getName() + "." + str);
    }

    /**
     * Accessor for the ScriptEngine's long name variable
     * @return the long name of the ScriptEngine
     */
    protected static String getEngine() {
        TRACE("getEngine()");
        return AppleScriptEngineFactory.ENGINE_NAME;
    }

    /**
     * Accessor for the ScriptEngine's version
     * @return the version of the ScriptEngine
     */
    protected static String getEngineVersion() {
        TRACE("getEngineVersion()");
        return AppleScriptEngineFactory.ENGINE_VERSION;
    }

    /**
     * Accessor for the ScriptEngine's short name
     * @return the short name of the ScriptEngine
     */
    protected static String getName() {
        TRACE("getName()");
        return AppleScriptEngineFactory.ENGINE_SHORT_NAME;
    }

    /**
     * Accessor for the ScriptEngine's supported language name
     * @return the language the ScriptEngine supports
     */
    protected static String getLanguage() {
        TRACE("getLanguage()");
        return AppleScriptEngineFactory.LANGUAGE;
    }

    /**
     * The no argument constructor sets up the object with default members,
     * a factory for the engine and a fresh context.
     * @see com.apple.applescript.AppleScriptEngine#init()
     */
    public AppleScriptEngine() {
        TRACE("<ctor>()");
        // set our parent factory to be a new factory
        factory = AppleScriptEngineFactory.getFactory();

        // set up our noarg bindings
        setContext(new SimpleScriptContext());
        put(ARGV, "");

        init();
    }

    /**
     * All AppleScriptEngines share the same ScriptEngineFactory
     */
    private final ScriptEngineFactory factory;

    /**
     * The local context for the AppleScriptEngine
     */
    private ScriptContext context;

    /**
     * The constructor taking a factory as an argument sets the parent factory for
     * this engine to be the passed factory, and sets up the engine with a fresh context
     * @param factory
     * @see com.apple.applescript.AppleScriptEngine#init()
     */
    public AppleScriptEngine(final ScriptEngineFactory factory) {
        // inherit the factory passed to us
        this.factory = factory;

        // set up our noarg bindings
        setContext(new SimpleScriptContext());
        put(ARGV, "");

        init();
    }

    /**
     * The initializer populates the local context with some useful predefined variables:
     * <ul>
  • javax_script_language_version - the version of AppleScript that the AppleScriptEngine supports.
  • * <li>javax_script_language - "AppleScript" -- the language supported by the AppleScriptEngine. * <li>javax_script_engine - "AppleScriptEngine" -- the name of the ScriptEngine. * <li>javax_script_engine_version - the version of the AppleScriptEngine * <li>javax_script_argv - "" -- AppleScript does not take arguments from the command line * <li>javax_script_filename - "" -- the currently executing filename * <li>javax_script_name - "AppleScriptEngine" -- the short name of the AppleScriptEngine * <li>THREADING - null -- the AppleScriptEngine does not support concurrency, you will have to implement thread-safeness yourself. */ private void init() { TRACE("init()"); // set up our context /* TODO -- name of current executable? bad java documentation at: * http://docs.oracle.com/javase/6/docs/api/javax/script/ScriptEngine.html#FILENAME */ put(ScriptEngine.FILENAME, ""); put(ScriptEngine.ENGINE, getEngine()); put(ScriptEngine.ENGINE_VERSION, getEngineVersion()); put(ScriptEngine.NAME, getName()); put(ScriptEngine.LANGUAGE, getLanguage()); put(ScriptEngine.LANGUAGE_VERSION, getLanguageVersion()); // TODO -- for now, err on the side of caution and say that we are NOT thread-safe put("THREADING", null); } /** * Uses the AppleScriptEngine to get the local AppleScript version * @return the version of AppleScript running on the system */ protected String getLanguageVersion() { TRACE("AppleScriptEngine.getLanguageVersion()"); try { final Object result = eval("get the version of AppleScript"); if (result instanceof String) return (String)result; } catch (final ScriptException e) { e.printStackTrace(); } return "unknown"; } /** * Implementation required by ScriptEngine parent<br /> * Returns the factory parent of this AppleScriptEngine */ public ScriptEngineFactory getFactory() { return factory; } /** * Implementation required by ScriptEngine parent<br /> * Return the engine's context * @return this ScriptEngine's context */ public ScriptContext getContext() { return context; } /** * Implementation required by ScriptEngine parent<br /> * Set a new context for the engine * @param context the new context to install in the engine */ public void setContext(final ScriptContext context) { this.context = context; } /** * Implementation required by ScriptEngine parent<br /> * Create and return a new set of simple bindings. * @return a new and empty set of bindings */ public Bindings createBindings() { return new SimpleBindings(); } /** * Implementation required by ScriptEngine parent<br /> * Return the engines bindings for the context indicated by the argument. * @param scope contextual scope to return. * @return the bindings in the engine for the scope indicated by the parameter */ public Bindings getBindings(final int scope) { return context.getBindings(scope); } /** * Implementation required by ScriptEngine parent<br /> * Sets the bindings for the indicated scope * @param bindings a set of bindings to assign to the engine * @param scope the scope that the passed bindings should be assigned to */ public void setBindings(final Bindings bindings, final int scope) { context.setBindings(bindings, scope); } /** * Implementation required by ScriptEngine parent<br /> * Insert a key and value into the engine's bindings (scope: engine) * @param key the key of the pair * @param value the value of the pair */ public void put(final String key, final Object value) { getBindings(ScriptContext.ENGINE_SCOPE).put(key, value); } /** * Implementation required by ScriptEngine parent<br /> * Get a value from the engine's bindings using a key (scope: engine) * @param key the key of the pair * @return the value of the pair */ public Object get(final String key) { return getBindings(ScriptContext.ENGINE_SCOPE).get(key); } /** * Implementation required by ScriptEngine parent<br /> * Passes the Reader argument, as well as the engine's context to a lower evaluation function.<br /> * Prefers FileReader or BufferedReader wrapping FileReader as argument. * @param reader a Reader to AppleScript source or compiled AppleScript * @return an Object corresponding to the return value of the script * @see com.apple.applescript.AppleScriptEngine#eval(Reader, ScriptContext) */ public Object eval(final Reader reader) throws ScriptException { return eval(reader, getContext()); } /** * Implementation required by ScriptEngine parent<br /> * Uses the passed bindings as the context for executing the passed script. * @param reader a stream to AppleScript source or compiled AppleScript * @param bindings a Bindings object representing the contexts to execute inside * @return the return value of the script * @see com.apple.applescript.AppleScriptEngine#eval(Reader, ScriptContext) */ public Object eval(final Reader reader, final Bindings bindings) throws ScriptException { final Bindings tmp = getContext().getBindings(ScriptContext.ENGINE_SCOPE); getContext().setBindings(bindings, ScriptContext.ENGINE_SCOPE); final Object retval = eval(reader); getContext().setBindings(tmp, ScriptContext.ENGINE_SCOPE); return retval; } /** * Implementation required by ScriptEngine parent<br /> * This function can execute either AppleScript source or compiled AppleScript and functions by writing the * contents of the Reader to a temporary file and then executing it with the engine's context. * @param reader * @param scriptContext * @return an Object corresponding to the return value of the script */ public Object eval(final Reader reader, final ScriptContext context) throws ScriptException { checkSecurity(); // write our passed reader to a temporary file File tmpfile; FileWriter tmpwrite; try { tmpfile = Files.createTempFile("AppleScriptEngine.", ".scpt").toFile(); tmpwrite = new FileWriter(tmpfile); // read in our input and write directly to tmpfile /* TODO -- this may or may not be avoidable for certain Readers, * if a filename can be grabbed, it would be faster to get that and * use the underlying file than writing a temp file. */ int data; while ((data = reader.read()) != -1) { tmpwrite.write(data); } tmpwrite.close(); // set up our context business final long contextptr = scriptContextToNSDictionary(context); try { final long retCtx = evalScriptFromURL("file://" + tmpfile.getCanonicalPath(), contextptr); Object retVal = (retCtx == 0) ? null : createObjectFrom(retCtx); disposeContext(retCtx); return retVal; } finally { disposeContext(contextptr); tmpfile.delete(); } } catch (final IOException e) { throw new ScriptException(e); } } /** * Implementation required by ScriptEngine parent<br /> * Evaluate an AppleScript script passed as a source string. Using the engine's built in context. * @param script the string to execute. * @return an Object representing the return value of the script * @see com.apple.applescript.AppleScriptEngine#eval(String, ScriptContext) */ public Object eval(final String script) throws ScriptException { return eval(script, getContext()); } /** * Implementation required by ScriptEngine parent<br /> * Evaluate an AppleScript script passed as a source string with a custom ScriptContext. * @param script the AppleScript source to compile and execute. * @param scriptContext the context to execute the script under * @see com.apple.applescript.AppleScriptEngine#eval(String, ScriptContext) */ public Object eval(final String script, final Bindings bindings) throws ScriptException { final Bindings tmp = getContext().getBindings(ScriptContext.ENGINE_SCOPE); getContext().setBindings(bindings, ScriptContext.ENGINE_SCOPE); final Object retval = eval(script); getContext().setBindings(tmp, ScriptContext.ENGINE_SCOPE); return retval; } /** * Implementation required by ScriptEngine parent * @param script * @param scriptContext */ public Object eval(final String script, final ScriptContext context) throws ScriptException { checkSecurity(); final long ctxPtr = scriptContextToNSDictionary(context); try { final long retCtx = evalScript(script, ctxPtr); Object retVal = (retCtx == 0) ? null : createObjectFrom(retCtx); disposeContext(retCtx); return retVal; } finally { disposeContext(ctxPtr); } } /** * Converts a ScriptContext into an NSDictionary * @param context ScriptContext for the engine * @return a pointer to an NSDictionary */ private long scriptContextToNSDictionary(final ScriptContext context) throws ScriptException { final Map<String, Object> contextAsMap = new HashMap(); for (final Entry<String, Object> e : context.getBindings(ScriptContext.ENGINE_SCOPE).entrySet()) { contextAsMap.put(e.getKey().replaceAll("\\.", "_"), e.getValue()); } return createContextFrom(contextAsMap); } }

    Other Java examples (source code examples)

    Here is a short list of links related to this Java AppleScriptEngine.java source code file:

    ... this post is sponsored by my books ...

    #1 New Release!

    FP Best Seller

     

    new blog posts

     

    Copyright 1998-2021 Alvin Alexander, alvinalexander.com
    All Rights Reserved.

    A percentage of advertising revenue from
    pages under the /java/jwarehouse URI on this website is
    paid back to open source projects.