Spec-Zone .ru
спецификации, руководства, описания, API
Содержание документации

Java, Пишущий сценарий Руководства Программиста

Для кого Java Пишет сценарий API?

Некоторые полезные характеристики языков сценариев:

JavaTM, Пишущий сценарий API, является языком сценариев indepedent платформа для того, чтобы использовать механизмы выполнения сценария от кода Java. С API Сценариев Java возможно записать настраиваемые/растяжимые приложения на языке Java и оставить выбор языка сценариев настройки до конца пользователем. Разработчик приложений Java не должен выбрать язык расширения во время разработки. Если Вы пишете свое приложение с API JSR-223, то Ваши пользователи могут использовать любой совместимый язык сценариев JSR-223.

вершина

Сценарии Пакета

Функциональность Сценариев Java находится в javax.script пакет. Это - относительно маленький, простой API. Начальная точка API сценариев ScriptEngineManager класс. Объект ScriptEngineManager может обнаружить механизмы выполнения сценария через механизм открытия файловой службы фляги. Это может также инстанцировать объектов ScriptEngine, которые интерпретируют сценарии, записанные в определенном языке сценариев. Самый простой способ использовать API сценариев следующие:

  1. Создайте a ScriptEngineManager объект.
  2. Получите a ScriptEngine объект от менеджера.
  3. Оцените сценарий, используя ScriptEngine's eval методы.

Теперь, пора смотреть на некоторый пример кода. В то время как это не обязательно, может быть полезно знать, что немного JavaScript читает эти примеры.

вершина

Примеры

"Привет, Мир"

От ScriptEngineManager экземпляр, мы запрашиваем использование экземпляра механизма JavaScript getEngineByName метод. На механизме выполнения сценария, eval метод вызывают, чтобы выполнить данную Строку как код JavaScript! Для краткости, в этом так же как в последующих примерах, мы не показали обработку исключений. Там проверяются и исключения на этапе выполнения, брошенные от javax.script API. Само собой разумеется необходимо обработать исключения соответственно.

import javax.script.*;
public class EvalScript {
    public static void main(String[] args) throws Exception {
        // create a script engine manager
        ScriptEngineManager factory = new ScriptEngineManager();
        // create a JavaScript engine
        ScriptEngine engine = factory.getEngineByName("JavaScript");
        // evaluate JavaScript code from String
        engine.eval("print('Hello, World')");
    }
}

вершина

Оценка Файла Сценария

В этом примере мы вызываем eval метод, который принимает java.io.Reader для входного источника. Сценарий, считанный данным читателем, выполняется. Этим путем возможно выполнить сценарии от файлов, URL и ресурсов, обертывая соответствующие входные потоковые объекты как читатели.

import javax.script.*;
public class EvalFile {
    public static void main(String[] args) throws Exception {
        // create a script engine manager
        ScriptEngineManager factory = new ScriptEngineManager();
        // create JavaScript engine
        ScriptEngine engine = factory.getEngineByName("JavaScript");
        // evaluate JavaScript code from given file - specified by first argument
        engine.eval(new java.io.FileReader(args[0]));
    }
}

Давайте предполагать, что у нас есть файл, названный "test.js" со следующим текстом:

println("This is hello from test.js");

Мы можем выполнить вышеупомянутый Java как

java EvalFile test.js

вершина

Переменные сценария

Когда Вы встраиваете механизмы выполнения сценария и сценарии с Вашим приложением Java, можно хотеть представить свои объекты приложения как глобальные переменные к сценариям. Этот пример демонстрирует, как можно представить свои объекты приложения как глобальные переменные к сценарию. Мы создаем a java.io.File в приложении и представляют то же самое как глобальную переменную с именем "файл". Сценарий может получить доступ к переменной - например, это может вызвать открытые методы для этого. Отметьте, что синтаксис, чтобы получить доступ к объектам Java, методам и полям зависит от языка сценариев. JavaScript поддерживает самый "естественный" Подобный Java синтаксис.

public class ScriptVars { 
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        File f = new File("test.txt");
        // expose File object as variable to script
        engine.put("file", f);

        // evaluate a script string. The script accesses "file" 
        // variable and calls method on it
        engine.eval("print(file.getAbsolutePath())");
    }
}


вершина

Вызов Функций Сценария и Методов

Иногда можно хотеть вызвать определенную функцию сценариев неоднократно - например, Ваша функциональность меню приложения могла бы быть реализована сценарием. В обработчике событий действия Вашего меню можно хотеть вызвать определенную функцию сценария. Следующий пример демонстрирует, как вызывать определенную функцию сценария от кода Java.

import javax.script.*;

public class InvokeScriptFunction {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        // JavaScript code in a String
        String script = "function hello(name) { print('Hello, ' + name); }";
        // evaluate script
        engine.eval(script);

        // javax.script.Invocable is an optional interface.
        // Check whether your script engine implements or not!
        // Note that the JavaScript engine implements Invocable interface.
        Invocable inv = (Invocable) engine;

        // invoke the global function named "hello"
        inv.invokeFunction("hello", "Scripting!!" );
    }
}

Если Ваш язык сценариев является основанным на объектах (как JavaScript) или объектно-ориентированным, то можно вызвать метод сценария на объект сценария.


import javax.script.*;

public class InvokeScriptMethod {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        // JavaScript code in a String. This code defines a script object 'obj'
        // with one method called 'hello'.        
        String script = "var obj = new Object(); obj.hello = function(name) { print('Hello, ' + name); }";
        // evaluate script
        engine.eval(script);

        // javax.script.Invocable is an optional interface.
        // Check whether your script engine implements or not!
        // Note that the JavaScript engine implements Invocable interface.
        Invocable inv = (Invocable) engine;

        // get script object on which we want to call the method
        Object obj = engine.get("obj");

        // invoke the method named "hello" on the script object "obj"
        inv.invokeMethod(obj, "hello", "Script Method !!" );
    }
}


вершина

Реализация Интерфейсов Java Сценариями

Вместо того, чтобы вызвать определенные функции сценария от Java, иногда удобно реализовать интерфейс Java функциями сценария или методами. Кроме того, при использовании интерфейсов мы можем избежать иметь необходимость использовать javax.script API во многих местах. Мы можем получить интерфейсный объект конструктора и передать его к различным API Java. Следующий пример демонстрирует, как реализовывать java.lang.Runnable интерфейс со сценарием.


import javax.script.*;

public class RunnableImpl {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        // JavaScript code in a String
        String script = "function run() { println('run called'); }";

        // evaluate script
        engine.eval(script);

        Invocable inv = (Invocable) engine;

        // get Runnable interface object from engine. This interface methods
        // are implemented by script functions with the matching name.
        Runnable r = inv.getInterface(Runnable.class);

        // start a new thread that runs the script implemented
        // runnable interface
        Thread th = new Thread(r);
        th.start();
    }
}

Если Ваш язык сценариев основан на объектах или объектно-ориентирован, возможно реализовать интерфейс Java методами сценария на объектах сценария. Это избегает иметь необходимость вызвать глобальные функции сценария для интерфейсных методов. Объект сценария может сохранить "состояние", связанное интерфейсным конструктором.



import javax.script.*;

public class RunnableImplObject {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        // JavaScript code in a String
        String script = "var obj = new Object(); obj.run = function() { println('run method called'); }";

        // evaluate script
        engine.eval(script);

        // get script object on which we want to implement the interface with
        Object obj = engine.get("obj");

        Invocable inv = (Invocable) engine;

        // get Runnable interface object from engine. This interface methods
        // are implemented by script methods of object 'obj'
        Runnable r = inv.getInterface(obj, Runnable.class);

        // start a new thread that runs the script implemented
        // runnable interface
        Thread th = new Thread(r);
        th.start();
    }
}

вершина

Многократные Контексты для Сценариев

В примере переменных сценария мы видели, как представить объекты приложения как глобальные переменные сценария. Возможно представить многократную глобальную переменную "контексты" для сценариев. Единственный контекст является экземпляром javax.script.Bindings. Этот интерфейс получается из java.util.Map<String, Object>. Ряд контекста пар значение-имя, где имя является любой непустой, непустой строкой. Многократные контексты поддерживаются javax.script.ScriptContext интерфейс. Контекст сценария поддерживает один или более контекстов со связанной Привязкой для каждого контекста. По умолчанию у каждого механизма выполнения сценария есть контекст сценария по умолчанию. У контекста сценария по умолчанию есть по крайней мере один контекст под названием "ENGINE_SCOPE". Различные контексты, поддерживаемые контекстом сценария, доступны через getScopes метод.



import javax.script.*;

public class MultiScopes {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        engine.put("x", "hello");
        // print global variable "x"
        engine.eval("println(x);");
        // the above line prints "hello"

        // Now, pass a different script context
        ScriptContext newContext = new SimpleScriptContext();
        Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);

        // add new variable "x" to the new engineScope        
        engineScope.put("x", "world");

        // execute the same script - but this time pass a different script context
        engine.eval("println(x);", newContext);
        // the above line prints "world"
    }
}


вершина

Механизм выполнения сценария JavaScript

Реализация Oracle JDK 7 cо-связывается Mozilla Rhino базируемый механизм JavaScript, который может использоваться в соединении с javax.script (JSR-223) API.

Этот каталог и подкаталоги содержат источники Носорога с изменениями Oracle. Источники Носорога Mozilla лицензируются под Mozilla Public License Version 1.1. Можно получить копию этой Лицензии в http://www.mozilla.org/MPL. Пожалуйста, отметьте что источники в com.sun.script пакет и подпакеты не покрываются под MPL.

Функция изменяется в реализации JavaScript

Большая часть реализации Носорога включается, но есть несколько из компонентов Носорога, не включаются / изменился главным образом из-за места и соображений безопасности. Эти функции:
  1. Компиляция JavaScript к байт-коду (также названный "оптимизатором") ⠀“ оптимизатор отключается, когда менеджер безопасности присутствует. Когда менеджер безопасности не используется, свойство System "rhino.opt.level" может быть определено в диапазоне [-1, 9]. По умолчанию значение устанавливается в-1, что означает, что оптимизатор отключается.
  2. JavaAdapter носорога был переопределен. JavaAdapter является функцией, которой класс Java может быть расширен JavaScript, и интерфейсы Java могут быть реализованы JavaScript. Мы заменили JavaAdapter Носорога нашей собственной реализацией JavaAdapter. В нашей реализации только единственный интерфейс Java может быть реализован объектом JavaScript. Например, следующие работы как ожидалось.
           var v = new java.lang.Runnable() {
                        run: function() { print('hello'); }
                   }
           v.run();
    
    В большинстве случаев JavaAdapter используется, чтобы реализовать единственный интерфейс с программой сохранения анонимности Java подобный классу синтаксис. Использование JavaAdapter, чтобы расширить класс Java или реализовать многократные интерфейсы очень редко.
  3. Инструменты командной строки Носорога (Оболочка носорога, отладчик и т.д.) не включаются.
вершина

JavaScript к Передаче Java

По большей части, получая доступ к классам Java, объекты и методы являются прямыми. В определенном поле и доступе метода от JavaScript то же самое, как это от Java. Мы выделяем важные аспекты доступа Java JavaScript здесь. Для получения дополнительной информации, пожалуйста, обратитесь к http://www.mozilla.org/rhino/scriptjava.html. Следующие примеры являются отрывками JavaScript, получающими доступ к Java. Этот раздел требует знания JavaScript. Этот раздел может быть пропущен, если Вы планируете использовать некоторый другой язык сценариев JSR-223, а не JavaScript.

вершина

Импортируя Пакеты Java, Классы

Встроенные функции importPackage и importClass может использоваться, чтобы импортировать пакеты Java и классы.


// Import Java packages and classes 
// like import package.*; in Java
importPackage(java.awt);
// like import java.awt.Frame in Java
importClass(java.awt.Frame);
// Create Java Objects by "new ClassName"
var frame = new java.awt.Frame("hello");
// Call Java public methods from script
frame.setVisible(true);
// Access "JavaBean" properties like "fields"
print(frame.title);

Глобальная переменная Пакетов может привыкнуть к пакетам Java доступа. Примеры: Packages.java.util.Vector, Packages.javax.swing.JFrame. Пожалуйста, отметьте, что "java" является ярлыком для "Packages.java". Есть эквивалентные ярлыки для javax, org, edu, com, сетевых префиксов, таким образом, к pratically все классы платформы JDK можно получить доступ без префикса "Пакетов".

Отметьте, что java.lang не импортируется по умолчанию (в отличие от Java), потому что это привело бы к конфликтам со встроенным Объектом JavaScript, Булевской переменной, Математикой и так далее.

importPackage и importClass функции "загрязняют" контекст глобальной переменной JavaScript. Избегать, чтобы, можно было использовать JavaImporter.


// create JavaImporter with specific packages and classes to import

var SwingGui = new JavaImporter(javax.swing,
                            javax.swing.event,
                            javax.swing.border,
                            java.awt.event);
with (SwingGui) {
    // within this 'with' statement, we can access Swing and AWT
    // classes by unqualified (simple) names.

    var mybutton = new JButton("test");
    var myframe = new JFrame("test");
}


вершина

Создание и Используя Массивы Java

В то время как создание объекта Java является тем же самым как в Java, чтобы создать массивы Java в JavaScript, мы должны использовать отражение Java явно. Но когда-то создаваемый доступ доступа или длины элемента является тем же самым как в Java. Кроме того, массив сценария может использоваться, когда метод Java ожидает массив Java (автоматическое преобразование). Так в большинстве случаев мы не должны создать массивы Java явно.


// create Java String array of 5 elements
var a = java.lang.reflect.Array.newInstance(java.lang.String, 5);

// Accessing elements and length access is by usual Java syntax
a[0] = "scripting is great!";
print(a.length);


вершина

Реализация Интерфейсов Java

Интерфейс Java может быть реализован в JavaScript при использовании Java анонимный подобный классу синтаксис:


var r  = new java.lang.Runnable() {
    run: function() {
        print("running...\n");
    }
};

// "r" can be passed to Java methods that expect java.lang.Runnable
var th = new java.lang.Thread(r);
th.start();

Когда интерфейс с единственным методом ожидается, можно передать функцию сценария непосредственно. (автоматическое преобразование)


function func() {
     print("I am func!");
}

// pass script function for java.lang.Runnable argument
var th = new java.lang.Thread(func);
th.start();

вершина

Разрешение перегрузки

Методы Java могут быть перегружены типами параметра. В Java разрешение перегрузки происходит во время компиляции (выполняемый javac). Вызывая методы Java из сценария, интерпретатор/компилятор сценария должен выбрать соответствующий метод. С механизмом JavaScript Вы не должны сделать ничего специального - корректная разновидность перегрузки метода Java выбирается основанная на типах параметра. Но, иногда можно хотеть (или иметь) явно выбрать определенную разновидность перегрузки.


var out = java.lang.System.out;

// select a particular println function 
out["println(java.lang.Object)"]("hello");

Больше деталей о разрешении перегрузки метода Java JavaScript в http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html

вершина

Реализация Вашего Собственного Механизма выполнения сценария

Мы не будем покрывать реализацию совместимых механизмов выполнения сценария JSR-223 подробно. Минимально, Вы должны реализовать javax.script.ScriptEngine и javax.script.ScriptEngineFactory интерфейсы. Абстрактный класс javax.script.AbstractScriptEngine обеспечивает полезные значения по умолчанию для нескольких методов ScriptEngine интерфейс.

Прежде, чем начать реализовывать механизм JSR-223, можно хотеть проверить http://scripting.dev.java.net проект. Этот проект поддерживает реализации JSR-223 для многих популярных языков сценариев с открытым исходным кодом.

вершина

Ссылки

вершина

Oracle и/или его филиалы Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.
Свяжитесь с Нами