├── settings.gradle
├── .vscode
└── settings.json
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .settings
├── org.eclipse.wst.common.project.facet.core.xml
├── org.eclipse.jdt.core.prefs
└── org.eclipse.buildship.core.prefs
├── src
├── main
│ ├── java
│ │ └── net
│ │ │ └── arnx
│ │ │ └── nashorn
│ │ │ └── lib
│ │ │ └── PromiseException.java
│ └── resources
│ │ └── net
│ │ └── arnx
│ │ └── nashorn
│ │ └── lib
│ │ └── promise.js
└── test
│ └── java
│ └── net
│ └── arnx
│ └── nashorn
│ └── lib
│ └── PromiseTest.java
├── package.json
├── .gitignore
├── .project
├── .classpath
├── LICENSE
├── README.md
├── gradlew.bat
├── index.js
└── gradlew
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'nashorn-promise'
2 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "java.configuration.updateBuildConfiguration": "automatic"
3 | }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hidekatsu-izuno/nashorn-promise/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.settings/org.eclipse.wst.common.project.facet.core.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/src/main/java/net/arnx/nashorn/lib/PromiseException.java:
--------------------------------------------------------------------------------
1 | package net.arnx.nashorn.lib;
2 |
3 | @SuppressWarnings("serial")
4 | public class PromiseException extends RuntimeException {
5 | private Object result;
6 |
7 | public PromiseException(Object result) {
8 | this.result = result;
9 | }
10 |
11 | public Object getResult() {
12 | return result;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
4 | org.eclipse.jdt.core.compiler.compliance=1.8
5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
7 | org.eclipse.jdt.core.compiler.source=1.8
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nashorn-promise",
3 | "version": "0.1.3",
4 | "description": "ES6 Promise support for Nashorn",
5 | "main": "index.js",
6 | "repository": "https://github.com/hidekatsu-izuno/nashorn-promise.git",
7 | "author": "Hidekatsu Izuno ",
8 | "license": "MIT",
9 | "files": [
10 | "index.js",
11 | "LICENSE",
12 | "package.json",
13 | "README.json"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | build.commands=org.eclipse.jdt.core.javabuilder
2 | connection.arguments=
3 | connection.java.home=null
4 | connection.jvm.arguments=
5 | connection.project.dir=
6 | containers=org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/
7 | derived.resources=.gradle,build
8 | eclipse.preferences.version=1
9 | natures=org.eclipse.jdt.core.javanature
10 | project.path=\:
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 | .history/
11 |
12 | # Directory for instrumented libs generated by jscoverage/JSCover
13 | lib-cov
14 |
15 | # Coverage directory used by tools like istanbul
16 | coverage
17 |
18 | # nyc test coverage
19 | .nyc_output
20 |
21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
22 | .grunt
23 |
24 | # Gradle
25 | .gradle
26 | !gradle-wrapper.jar
27 |
28 | # node-waf configuration
29 | .lock-wscript
30 |
31 | # Compiled binary addons (http://nodejs.org/api/addons.html)
32 | build/Release
33 |
34 | # Dependency directories
35 | node_modules
36 | jspm_packages
37 |
38 | # Optional npm cache directory
39 | .npm
40 |
41 | # Optional REPL history
42 | .node_repl_history
43 | /bin/
44 | /build/
45 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | nashorn-promise
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.wst.common.project.facet.core.builder
20 |
21 |
22 |
23 |
24 |
25 | org.eclipse.wst.common.project.facet.core.nature
26 | org.eclipse.jdt.core.javanature
27 | org.eclipse.buildship.core.gradleprojectnature
28 |
29 |
30 |
--------------------------------------------------------------------------------
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Hidekatsu Izuno
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](LICENSE)
2 | [](https://maven-badges.herokuapp.com/maven-central/net.arnx/nashorn-promise)
3 |
4 |
5 | # ES6 Promise support for Nashorn
6 |
7 | This is a polyfill of the ES6 Promise using Java 8 CompletableFuture.
8 |
9 | ## Getting Started
10 |
11 | ### Setup
12 |
13 | To add a dependency using Maven, use the following:
14 |
15 | ```xml
16 |
17 | net.arnx
18 | nashorn-promise
19 | 0.1.3
20 |
21 | ```
22 |
23 | To add a dependency using Gradle:
24 |
25 | ```groovy
26 | dependencies {
27 | compile 'net.arnx:nashorn-promise:0.1.3'
28 | }
29 | ```
30 |
31 | ### Usage
32 |
33 | ```java
34 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
35 | engine.eval("load('classpath:net/arnx/nashorn/lib/promise.js')");
36 | ```
37 |
38 | ## License
39 |
40 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE) file for details
41 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
34 |
35 | @rem Find java.exe
36 | if defined JAVA_HOME goto findJavaFromJavaHome
37 |
38 | set JAVA_EXE=java.exe
39 | %JAVA_EXE% -version >NUL 2>&1
40 | if "%ERRORLEVEL%" == "0" goto init
41 |
42 | echo.
43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
44 | echo.
45 | echo Please set the JAVA_HOME variable in your environment to match the
46 | echo location of your Java installation.
47 |
48 | goto fail
49 |
50 | :findJavaFromJavaHome
51 | set JAVA_HOME=%JAVA_HOME:"=%
52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
53 |
54 | if exist "%JAVA_EXE%" goto init
55 |
56 | echo.
57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
58 | echo.
59 | echo Please set the JAVA_HOME variable in your environment to match the
60 | echo location of your Java installation.
61 |
62 | goto fail
63 |
64 | :init
65 | @rem Get command-line arguments, handling Windows variants
66 |
67 | if not "%OS%" == "Windows_NT" goto win9xME_args
68 |
69 | :win9xME_args
70 | @rem Slurp the command line arguments.
71 | set CMD_LINE_ARGS=
72 | set _SKIP=2
73 |
74 | :win9xME_args_slurp
75 | if "x%~1" == "x" goto execute
76 |
77 | set CMD_LINE_ARGS=%*
78 |
79 | :execute
80 | @rem Setup the command line
81 |
82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
83 |
84 | @rem Execute Gradle
85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
86 |
87 | :end
88 | @rem End local scope for the variables with windows NT shell
89 | if "%ERRORLEVEL%"=="0" goto mainEnd
90 |
91 | :fail
92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
93 | rem the _cmd.exe /c_ return code!
94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
95 | exit /b 1
96 |
97 | :mainEnd
98 | if "%OS%"=="Windows_NT" endlocal
99 |
100 | :omega
101 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * nashorn-promise
3 | *
4 | * @author hidekatsu.izuno@gmail.com (Hidekatsu Izuno)
5 | * @license MIT License
6 | */
7 |
8 | (function(global) {
9 | 'use strict';
10 |
11 | if (global.Promise === undefined) {
12 | var JCompletableFuture = Java.type('java.util.concurrent.CompletableFuture');
13 | var JCompleteFutureArray = Java.type('java.util.concurrent.CompletableFuture[]');
14 | var JPromiseException = Java.type('net.arnx.nashorn.lib.PromiseException');
15 |
16 | var Promise = function(resolver, promises) {
17 | var that = this;
18 | if (resolver instanceof JCompletableFuture) {
19 | that._future = resolver;
20 | that._promises = promises;
21 | } else {
22 | var func = Java.synchronized(function() {
23 | var status, result;
24 | (0, resolver)(function(value) {
25 | status = 'fulfilled';
26 | result = value;
27 | }, function(reason) {
28 | status = 'rejected';
29 | result = reason;
30 | });
31 | if (status == 'fulfilled') {
32 | return {
33 | result: result
34 | };
35 | } else if (status == 'rejected') {
36 | throw new JPromiseException(result);
37 | }
38 | }, global);
39 | if (Promise._pool) {
40 | that._future = JCompletableFuture.supplyAsync(func, Promise._pool);
41 | } else {
42 | that._future = JCompletableFuture.supplyAsync(func);
43 | }
44 | }
45 | };
46 |
47 | Promise.all = function(array) {
48 | if (array == null || array.length == null) {
49 | return Promise.reject(new TypeError('array is not iterable'))
50 | }
51 | if (array.length == 0) {
52 | return Promise.resolve([]);
53 | }
54 |
55 | var futures = new JCompleteFutureArray(array.length);
56 | var promises = [];
57 | for (var i = 0; i < array.length; i++) {
58 | if (array[i] instanceof Promise) {
59 | promises[i] = array[i];
60 | } else {
61 | promises[i] = Promise.resolve(array[i]);
62 | }
63 | futures[i] = promises[i]._future;
64 | }
65 | return new Promise(JCompletableFuture.allOf(futures), promises);
66 | };
67 |
68 | Promise.race = function(array) {
69 | if (array == null || array.length == null) {
70 | return Promise.reject(new TypeError('array is not iterable'))
71 | }
72 | if (array.length == 0) {
73 | return Promise.resolve([]);
74 | }
75 |
76 | var futures = new JCompleteFutureArray(array.length);
77 | for (var i = 0; i < array.length; i++) {
78 | if (array[i] instanceof Promise) {
79 | futures[i] = array[i]._future;
80 | } else {
81 | futures[i] = Promise.resolve(array[i])._future;
82 | }
83 | }
84 | return new Promise(JCompletableFuture.anyOf(futures));
85 | };
86 |
87 | Promise.resolve = function(value) {
88 | if (value instanceof Promise) {
89 | return value;
90 | } else if (value != null
91 | && (typeof value === 'function' || typeof value === 'object')
92 | && typeof value.then === 'function') {
93 | return new Promise(function(fulfill, reject) {
94 | try {
95 | return {
96 | result: value.then(fulfill, reject)
97 | }
98 | } catch (e) {
99 | throw new JPromiseException(e);
100 | }
101 | });
102 | } else {
103 | return new Promise(JCompletableFuture.completedFuture({
104 | result: value
105 | }));
106 | }
107 | };
108 |
109 | Promise.reject = function(value) {
110 | return new Promise(function(fulfill, reject) {
111 | reject(value);
112 | });
113 | };
114 |
115 | Promise.prototype.then = function(onFulfillment, onRejection) {
116 | var that = this;
117 | return new Promise(that._future.handle(function(success, error) {
118 | if (success == null && error == null && that._promises != null) {
119 | var traverse = function(promise) {
120 | if (promise._promises != null) {
121 | var result = [];
122 | for (var i = 0; i < promise._promises.length; i++) {
123 | result[i] = traverse(promise._promises[i]);
124 | }
125 | return result;
126 | }
127 | return promise._future.get().result;
128 | };
129 |
130 | var result = [];
131 | for (var i = 0; i < that._promises.length; i++) {
132 | result[i] = traverse(that._promises[i]);
133 | }
134 | success = {
135 | result: result
136 | };
137 | }
138 |
139 | if (success != null) {
140 | if (typeof onFulfillment === 'function') {
141 | try {
142 | var value = success.result;
143 | while (value instanceof Promise) {
144 | value = value._future.get().result;
145 | }
146 | return {
147 | result: (0, onFulfillment)(value)
148 | };
149 | } catch (e) {
150 | throw new JPromiseException(e)
151 | }
152 | }
153 | return success;
154 | } else if (error != null) {
155 | var cerror = error;
156 | do {
157 | if (cerror instanceof JPromiseException) {
158 | error = cerror;
159 | break;
160 | }
161 | } while ((cerror = cerror.getCause()) != null);
162 |
163 | if (typeof onRejection === 'function') {
164 | try {
165 | var reason = error;
166 | if (error instanceof JPromiseException) {
167 | reason = error.getResult();
168 | }
169 |
170 | return {
171 | result: (0, onRejection)(reason)
172 | };
173 | } catch (e) {
174 | throw new JPromiseException(e)
175 | }
176 | }
177 | throw error;
178 | }
179 | }));
180 | };
181 |
182 | Promise.prototype.catch = function(onRejection) {
183 | return this.then(null, onRejection);
184 | };
185 |
186 | global.Promise = Promise;
187 | }
188 | })(Function('return this')());
--------------------------------------------------------------------------------
/src/main/resources/net/arnx/nashorn/lib/promise.js:
--------------------------------------------------------------------------------
1 | /**
2 | * nashorn-promise
3 | *
4 | * @author hidekatsu.izuno@gmail.com (Hidekatsu Izuno)
5 | * @license MIT License
6 | */
7 |
8 | (function(global) {
9 | 'use strict';
10 |
11 | if (global.Promise === undefined) {
12 | var JCompletableFuture = Java.type('java.util.concurrent.CompletableFuture');
13 | var JCompleteFutureArray = Java.type('java.util.concurrent.CompletableFuture[]');
14 | var JPromiseException = Java.type('net.arnx.nashorn.lib.PromiseException');
15 |
16 | var Promise = function(resolver, promises) {
17 | var that = this;
18 | if (resolver instanceof JCompletableFuture) {
19 | that._future = resolver;
20 | that._promises = promises;
21 | } else {
22 | var func = Java.synchronized(function() {
23 | var status, result;
24 | (0, resolver)(function(value) {
25 | status = 'fulfilled';
26 | result = value;
27 | }, function(reason) {
28 | status = 'rejected';
29 | result = reason;
30 | });
31 | if (status == 'fulfilled') {
32 | return {
33 | result: result
34 | };
35 | } else if (status == 'rejected') {
36 | throw new JPromiseException(result);
37 | }
38 | }, global);
39 | if (Promise._pool) {
40 | that._future = JCompletableFuture.supplyAsync(func, Promise._pool);
41 | } else {
42 | that._future = JCompletableFuture.supplyAsync(func);
43 | }
44 | }
45 | };
46 |
47 | Promise.all = function(array) {
48 | if (array == null || array.length == null) {
49 | return Promise.reject(new TypeError('array is not iterable'))
50 | }
51 | if (array.length == 0) {
52 | return Promise.resolve([]);
53 | }
54 |
55 | var futures = new JCompleteFutureArray(array.length);
56 | var promises = [];
57 | for (var i = 0; i < array.length; i++) {
58 | if (array[i] instanceof Promise) {
59 | promises[i] = array[i];
60 | } else {
61 | promises[i] = Promise.resolve(array[i]);
62 | }
63 | futures[i] = promises[i]._future;
64 | }
65 | return new Promise(JCompletableFuture.allOf(futures), promises);
66 | };
67 |
68 | Promise.race = function(array) {
69 | if (array == null || array.length == null) {
70 | return Promise.reject(new TypeError('array is not iterable'))
71 | }
72 | if (array.length == 0) {
73 | return Promise.resolve([]);
74 | }
75 |
76 | var futures = new JCompleteFutureArray(array.length);
77 | for (var i = 0; i < array.length; i++) {
78 | if (array[i] instanceof Promise) {
79 | futures[i] = array[i]._future;
80 | } else {
81 | futures[i] = Promise.resolve(array[i])._future;
82 | }
83 | }
84 | return new Promise(JCompletableFuture.anyOf(futures));
85 | };
86 |
87 | Promise.resolve = function(value) {
88 | if (value instanceof Promise) {
89 | return value;
90 | } else if (value != null
91 | && (typeof value === 'function' || typeof value === 'object')
92 | && typeof value.then === 'function') {
93 | return new Promise(function(fulfill, reject) {
94 | try {
95 | return {
96 | result: value.then(fulfill, reject)
97 | }
98 | } catch (e) {
99 | throw new JPromiseException(e);
100 | }
101 | });
102 | } else {
103 | return new Promise(JCompletableFuture.completedFuture({
104 | result: value
105 | }));
106 | }
107 | };
108 |
109 | Promise.reject = function(value) {
110 | return new Promise(function(fulfill, reject) {
111 | reject(value);
112 | });
113 | };
114 |
115 | Promise.prototype.then = function(onFulfillment, onRejection) {
116 | var that = this;
117 | return new Promise(that._future.handle(function(success, error) {
118 | if (success == null && error == null && that._promises != null) {
119 | var traverse = function(promise) {
120 | if (promise._promises != null) {
121 | var result = [];
122 | for (var i = 0; i < promise._promises.length; i++) {
123 | result[i] = traverse(promise._promises[i]);
124 | }
125 | return result;
126 | }
127 | return promise._future.get().result;
128 | };
129 |
130 | var result = [];
131 | for (var i = 0; i < that._promises.length; i++) {
132 | result[i] = traverse(that._promises[i]);
133 | }
134 | success = {
135 | result: result
136 | };
137 | }
138 |
139 | if (success != null) {
140 | if (typeof onFulfillment === 'function') {
141 | try {
142 | var value = success.result;
143 | while (value instanceof Promise) {
144 | value = value._future.get().result;
145 | }
146 | return {
147 | result: (0, onFulfillment)(value)
148 | };
149 | } catch (e) {
150 | throw new JPromiseException(e)
151 | }
152 | }
153 | return success;
154 | } else if (error != null) {
155 | var cerror = error;
156 | do {
157 | if (cerror instanceof JPromiseException) {
158 | error = cerror;
159 | break;
160 | }
161 | } while ((cerror = cerror.getCause()) != null);
162 |
163 | if (typeof onRejection === 'function') {
164 | try {
165 | var reason = error;
166 | if (error instanceof JPromiseException) {
167 | reason = error.getResult();
168 | }
169 |
170 | return {
171 | result: (0, onRejection)(reason)
172 | };
173 | } catch (e) {
174 | throw new JPromiseException(e)
175 | }
176 | }
177 | throw error;
178 | }
179 | }));
180 | };
181 |
182 | Promise.prototype.catch = function(onRejection) {
183 | return this.then(null, onRejection);
184 | };
185 |
186 | global.Promise = Promise;
187 | }
188 | })(Function('return this')());
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 | # Determine the Java command to use to start the JVM.
86 | if [ -n "$JAVA_HOME" ] ; then
87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
88 | # IBM's JDK on AIX uses strange locations for the executables
89 | JAVACMD="$JAVA_HOME/jre/sh/java"
90 | else
91 | JAVACMD="$JAVA_HOME/bin/java"
92 | fi
93 | if [ ! -x "$JAVACMD" ] ; then
94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
95 |
96 | Please set the JAVA_HOME variable in your environment to match the
97 | location of your Java installation."
98 | fi
99 | else
100 | JAVACMD="java"
101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
102 |
103 | Please set the JAVA_HOME variable in your environment to match the
104 | location of your Java installation."
105 | fi
106 |
107 | # Increase the maximum file descriptors if we can.
108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
109 | MAX_FD_LIMIT=`ulimit -H -n`
110 | if [ $? -eq 0 ] ; then
111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
112 | MAX_FD="$MAX_FD_LIMIT"
113 | fi
114 | ulimit -n $MAX_FD
115 | if [ $? -ne 0 ] ; then
116 | warn "Could not set maximum file descriptor limit: $MAX_FD"
117 | fi
118 | else
119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
120 | fi
121 | fi
122 |
123 | # For Darwin, add options to specify how the application appears in the dock
124 | if $darwin; then
125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
126 | fi
127 |
128 | # For Cygwin, switch paths to Windows format before running java
129 | if $cygwin ; then
130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
132 | JAVACMD=`cygpath --unix "$JAVACMD"`
133 |
134 | # We build the pattern for arguments to be converted via cygpath
135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
136 | SEP=""
137 | for dir in $ROOTDIRSRAW ; do
138 | ROOTDIRS="$ROOTDIRS$SEP$dir"
139 | SEP="|"
140 | done
141 | OURCYGPATTERN="(^($ROOTDIRS))"
142 | # Add a user-defined pattern to the cygpath arguments
143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
145 | fi
146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
147 | i=0
148 | for arg in "$@" ; do
149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
151 |
152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
154 | else
155 | eval `echo args$i`="\"$arg\""
156 | fi
157 | i=$((i+1))
158 | done
159 | case $i in
160 | (0) set -- ;;
161 | (1) set -- "$args0" ;;
162 | (2) set -- "$args0" "$args1" ;;
163 | (3) set -- "$args0" "$args1" "$args2" ;;
164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
170 | esac
171 | fi
172 |
173 | # Escape application args
174 | save () {
175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
176 | echo " "
177 | }
178 | APP_ARGS=$(save "$@")
179 |
180 | # Collect all arguments for the java command, following the shell quoting and substitution rules
181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
182 |
183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
185 | cd "$(dirname "$0")"
186 | fi
187 |
188 | exec "$JAVACMD" "$@"
189 |
--------------------------------------------------------------------------------
/src/test/java/net/arnx/nashorn/lib/PromiseTest.java:
--------------------------------------------------------------------------------
1 | package net.arnx.nashorn.lib;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import javax.script.ScriptEngine;
6 | import javax.script.ScriptEngineManager;
7 | import javax.script.ScriptException;
8 |
9 | import org.junit.Test;
10 |
11 | public class PromiseTest {
12 |
13 | @Test
14 | public void testPromise() throws ScriptException {
15 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
16 | engine.eval("load('classpath:net/arnx/nashorn/lib/promise.js');");
17 |
18 | assertEquals("fulfilled: test", engine.eval(
19 | "var promise = new Promise(function(fulfill, reject) {\n" +
20 | " fulfill('test');\n" +
21 | "}).then(function(value) {\n" +
22 | " return 'fulfilled: ' + value\n" +
23 | "}).catch(function(value) {\n" +
24 | " return 'rejected: ' + value\n" +
25 | "});\n" +
26 | "promise._future.get().result;\n"));
27 |
28 | assertEquals("rejected: test", engine.eval(
29 | "var promise = new Promise(function(fulfill, reject) {\n" +
30 | " reject('test');\n" +
31 | "}).then(function(value) {\n" +
32 | " return 'fulfilled: ' + value\n" +
33 | "}).catch(function(value) {\n" +
34 | " return 'rejected: ' + value\n" +
35 | "});\n" +
36 | "promise._future.get().result;\n"));
37 |
38 | assertEquals("fulfilled: rejected: test", engine.eval(
39 | "var result = 'init';\n" +
40 | "var promise = new Promise(function(fulfill, reject) {\n" +
41 | " reject('test');\n" +
42 | "}).catch(function(value) {\n" +
43 | " return 'rejected: ' + value\n" +
44 | "}).then(function(value) {\n" +
45 | " return 'fulfilled: ' + value\n" +
46 | "});\n" +
47 | "promise._future.get().result;\n"));
48 | }
49 |
50 | @Test
51 | public void testPromiseAll() throws ScriptException {
52 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
53 | engine.eval("load('classpath:net/arnx/nashorn/lib/promise.js');");
54 |
55 | assertEquals("fulfilled: 6", engine.eval(
56 | "var promise = Promise.all([new Promise(function(fulfill, reject) {\n" +
57 | " fulfill(1);\n" +
58 | "}), new Promise(function(fulfill, reject) {\n" +
59 | " fulfill(2);\n" +
60 | "}), new Promise(function(fulfill, reject) {\n" +
61 | " fulfill(3);\n" +
62 | "})]).then(function(value) {\n" +
63 | " return 'fulfilled: ' + value.reduce(function(prev, current) { return prev + current; });\n" +
64 | "}).catch(function(reason) {\n" +
65 | " return 'rejected: ' + reason;\n" +
66 | "});\n" +
67 | "String(promise._future.get().result);\n"));
68 |
69 | assertEquals("rejected: 2", engine.eval(
70 | "var promise = Promise.all([new Promise(function(fulfill, reject) {\n" +
71 | " fulfill(1);\n" +
72 | "}), new Promise(function(fulfill, reject) {\n" +
73 | " reject(2);\n" +
74 | "}), new Promise(function(fulfill, reject) {\n" +
75 | " fulfill(3);\n" +
76 | "})]).then(function(value) {\n" +
77 | " return 'fulfilled: ' + value.reduce(function(prev, current) { return prev + current; });\n" +
78 | "}).catch(function(reason) {\n" +
79 | " return 'rejected: ' + reason;\n" +
80 | "});\n" +
81 | "String(promise._future.get().result);\n"));
82 | }
83 |
84 | @Test
85 | public void testPromiseRace() throws ScriptException {
86 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
87 | engine.eval("load('classpath:net/arnx/nashorn/lib/promise.js');");
88 |
89 | assertEquals("fulfilled: 1", engine.eval(
90 | "var promise = Promise.race([new Promise(function(fulfill, reject) {\n" +
91 | " fulfill(1);\n" +
92 | "}), new Promise(function(fulfill, reject) {\n" +
93 | " reject(2);\n" +
94 | "}), new Promise(function(fulfill, reject) {\n" +
95 | " fulfill(3);\n" +
96 | "})]).then(function(value) {\n" +
97 | " return 'fulfilled: ' + value;\n" +
98 | "}).catch(function(reason) {\n" +
99 | " return 'rejected: ' + reason;\n" +
100 | "});\n" +
101 | "String(promise._future.get().result);\n"));
102 |
103 | assertEquals("rejected: 1", engine.eval(
104 | "var promise = Promise.race([new Promise(function(fulfill, reject) {\n" +
105 | " reject(1);\n" +
106 | "}), new Promise(function(fulfill, reject) {\n" +
107 | " reject(2);\n" +
108 | "}), new Promise(function(fulfill, reject) {\n" +
109 | " reject(3);\n" +
110 | "})]).then(function(value) {\n" +
111 | " return 'fulfilled: ' + value;\n" +
112 | "}).catch(function(reason) {\n" +
113 | " return 'rejected: ' + reason;\n" +
114 | "});\n" +
115 | "String(promise._future.get().result);\n"));
116 | }
117 |
118 | @Test
119 | public void testPromiseResolve() throws ScriptException {
120 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
121 | engine.eval("load('classpath:net/arnx/nashorn/lib/promise.js')");
122 |
123 | assertEquals("fulfilled: test", engine.eval(
124 | "var promise = Promise.resolve(new Promise(function(fulfill, reject) {\n" +
125 | " fulfill('test');\n" +
126 | "})).then(function(value) {\n" +
127 | " return 'fulfilled: ' + value\n" +
128 | "}).catch(function(value) {\n" +
129 | " return 'rejected: ' + value\n" +
130 | "});\n" +
131 | "promise._future.get().result;\n"));
132 |
133 | assertEquals("fulfilled: test", engine.eval(
134 | "var promise = Promise.resolve({\n" +
135 | " then: function(fulfill, reject) {\n" +
136 | " fulfill('test');\n" +
137 | " }\n" +
138 | "}).then(function(value) {\n" +
139 | " return 'fulfilled: ' + value\n" +
140 | "}).catch(function(value) {\n" +
141 | " return 'rejected: ' + value\n" +
142 | "});\n" +
143 | "promise._future.get().result;\n"));
144 |
145 | assertEquals("fulfilled: test", engine.eval(
146 | "var promise = Promise.resolve('test')" +
147 | ".then(function(value) {\n" +
148 | " return 'fulfilled: ' + value\n" +
149 | "}).catch(function(value) {\n" +
150 | " return 'rejected: ' + value\n" +
151 | "});\n" +
152 | "promise._future.get().result;\n"));
153 | }
154 |
155 | @Test
156 | public void testPromiseReject() throws ScriptException {
157 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
158 | engine.eval("load('classpath:net/arnx/nashorn/lib/promise.js');");
159 |
160 | assertEquals("rejected: test", engine.eval(
161 | "var promise = Promise.reject('test')" +
162 | ".then(function(value) {\n" +
163 | " return 'fulfilled: ' + value\n" +
164 | "}).catch(function(value) {\n" +
165 | " return 'rejected: ' + value\n" +
166 | "});\n" +
167 | "promise._future.get().result;\n"));
168 | }
169 |
170 | @Test
171 | public void testPromiseReturn() throws ScriptException {
172 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
173 | engine.eval("load('classpath:net/arnx/nashorn/lib/promise.js');");
174 |
175 | assertEquals("fulfilled: test", engine.eval(
176 | "var promise = Promise.resolve('test')" +
177 | ".then(function(value) {\n" +
178 | " return Promise.resolve('fulfilled: ' + value);\n" +
179 | "}).then(function(value) {" +
180 | " return value;" +
181 | "});\n" +
182 | "promise._future.get().result;\n"));
183 | }
184 |
185 | @Test
186 | public void testPromiseNested() throws ScriptException {
187 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
188 | engine.eval("load('classpath:net/arnx/nashorn/lib/promise.js');");
189 |
190 | assertEquals("fulfilled: 4", engine.eval(
191 | "var promise = Promise.resolve(1)" +
192 | ".then(function(value) {\n" +
193 | " return Promise.resolve(value + 1).then(function(value) {" +
194 | " return Promise.resolve(value + 1).then(function(value) {" +
195 | " return Promise.resolve(value + 1);" +
196 | " });\n" +
197 | " });\n" +
198 | "}).then(function(value) {" +
199 | " return 'fulfilled: ' + value;" +
200 | "});\n" +
201 | "promise._future.get().result;\n"));
202 |
203 | assertEquals("fulfilled: [1,[2,[3]],4]", engine.eval(
204 | "var promise = Promise.all([\n" +
205 | " Promise.resolve(1),\n" +
206 | " Promise.all([\n" +
207 | " Promise.resolve(2),\n" +
208 | " Promise.all([\n" +
209 | " Promise.resolve(3)\n" +
210 | " ])\n" +
211 | " ]),\n" +
212 | " Promise.resolve(4)\n" +
213 | "]).then(function(values) {" +
214 | " return 'fulfilled: ' + JSON.stringify(values);" +
215 | "});\n" +
216 | "promise._future.get().result;\n"));
217 | }
218 | }
219 |
--------------------------------------------------------------------------------