├── .gitignore
├── Android.mk
├── Application.mk
├── LICENSE
├── README.md
├── app
├── .classpath
├── .project
├── AndroidManifest.xml
├── assets
│ └── .gitignore
├── build.xml
├── contrib
│ └── jtar-2.2.jar
├── proguard.cfg
├── res
│ ├── drawable-hdpi
│ │ └── icon.png
│ ├── drawable-ldpi
│ │ └── icon.png
│ ├── drawable-mdpi
│ │ └── icon.png
│ ├── layout
│ │ └── main.xml
│ └── values
│ │ └── strings.xml
└── src
│ └── org
│ └── meshpoint
│ └── anode
│ ├── AnodeActivity.java
│ ├── AnodeReceiver.java
│ ├── AnodeService.java
│ ├── Constants.java
│ └── util
│ ├── AndroidLog.java
│ ├── ArgProcessor.java
│ ├── ModuleUtils.java
│ ├── TarExtractor.java
│ └── ZipExtractor.java
├── bridge-java
├── .classpath
├── .project
├── build.xml
├── jni
│ └── src
│ │ ├── org_meshpoint_anode_bridge_BridgeNative.cpp
│ │ └── org_meshpoint_anode_bridge_BridgeNative.h
└── src
│ └── org
│ ├── meshpoint
│ └── anode
│ │ ├── bridge
│ │ ├── BridgeNative.java
│ │ ├── Env.java
│ │ ├── FinalizeQueue.java
│ │ ├── ModuleContext.java
│ │ └── SynchronousOperation.java
│ │ ├── error
│ │ ├── GeneralError.java
│ │ ├── InternalError.java
│ │ ├── ReferenceError.java
│ │ ├── ScriptError.java
│ │ └── TypeError.java
│ │ ├── idl
│ │ ├── BoundInterface.java
│ │ ├── Callback.java
│ │ ├── Dictionary.java
│ │ ├── IDLInterface.java
│ │ ├── InterfaceManager.java
│ │ ├── StubUtil.java
│ │ └── Types.java
│ │ ├── java
│ │ ├── Array.java
│ │ ├── Base.java
│ │ ├── ByteArray.java
│ │ ├── DoubleArray.java
│ │ ├── IntegerArray.java
│ │ ├── LongArray.java
│ │ └── ObjectArray.java
│ │ ├── js
│ │ ├── JSArray.java
│ │ ├── JSByteArray.java
│ │ ├── JSDoubleArray.java
│ │ ├── JSFunction.java
│ │ ├── JSIntegerArray.java
│ │ ├── JSInterface.java
│ │ ├── JSLongArray.java
│ │ ├── JSObject.java
│ │ ├── JSObjectArray.java
│ │ └── JSValue.java
│ │ ├── module
│ │ ├── IModule.java
│ │ └── IModuleContext.java
│ │ ├── type
│ │ ├── ICollection.java
│ │ ├── IFunction.java
│ │ └── IIndexedCollection.java
│ │ └── util
│ │ ├── Log.java
│ │ └── PrintStreamLog.java
│ └── w3c
│ └── dom
│ ├── Array.java
│ ├── ByteArray.java
│ ├── DoubleArray.java
│ ├── IntegerArray.java
│ ├── LongArray.java
│ ├── ObjectArray.java
│ └── PrimitiveArray.java
├── bridge-stub-generator
├── .classpath
├── .project
├── build.xml
└── src
│ └── org
│ └── meshpoint
│ └── anode
│ └── stub
│ ├── DictionaryStubGenerator.java
│ ├── PlatformStubGenerator.java
│ ├── StubGenerator.java
│ ├── UserStubGenerator.java
│ └── util
│ ├── DirectoryClassLoader.java
│ └── StubGen.java
├── bridge
├── Android.mk
├── Application.mk
└── src
│ ├── AndroidVM.cpp
│ ├── AndroidVM.h
│ ├── ArrayConv.cpp
│ ├── ArrayConv.h
│ ├── Bridge.cpp
│ ├── Bridge.h
│ ├── Conv.cpp
│ ├── Conv.h
│ ├── Env.cpp
│ ├── Env.h
│ ├── Interface.cpp
│ ├── Interface.h
│ ├── JREVM.cpp
│ ├── JREVM.h
│ ├── Utils-inl.h
│ ├── Utils.h
│ ├── VM.cpp
│ ├── VM.h
│ └── defines.h
├── libnode
├── .classpath
├── .project
├── AndroidManifest.xml
├── assets
│ └── .gitignore
├── build.xml
├── custom_rules.xml
├── gen
│ └── org
│ │ └── meshpoint
│ │ └── anode
│ │ └── R.java
├── jni
│ ├── Android.mk
│ └── src
│ │ ├── defines.h
│ │ ├── org_meshpoint_anode_RuntimeNative.cpp
│ │ └── org_meshpoint_anode_RuntimeNative.h
├── proguard.cfg
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ └── icon.png
│ ├── drawable-ldpi
│ │ └── icon.png
│ ├── drawable-mdpi
│ │ └── icon.png
│ ├── layout
│ │ └── main.xml
│ └── values
│ │ └── strings.xml
└── src
│ └── org
│ └── meshpoint
│ └── anode
│ ├── AndroidContext.java
│ ├── Isolate.java
│ ├── Runtime.java
│ ├── RuntimeNative.java
│ └── bridge
│ └── ModuleClassLoader.java
└── sdk
├── addon
├── build-node-addon.mk
└── sample
│ └── hello
│ ├── Android.mk
│ ├── Application.mk
│ └── src
│ └── hello.cc
└── java
├── lib
├── .classpath
├── .project
└── src
│ └── org
│ ├── meshpoint
│ └── anode
│ │ ├── bridge
│ │ └── Env.java
│ │ ├── idl
│ │ ├── Dictionary.java
│ │ ├── IDLInterface.java
│ │ └── InterfaceManager.java
│ │ ├── java
│ │ └── Base.java
│ │ └── module
│ │ ├── IModule.java
│ │ └── IModuleContext.java
│ └── w3c
│ └── dom
│ ├── Array.java
│ ├── ByteArray.java
│ ├── DoubleArray.java
│ ├── IntegerArray.java
│ ├── LongArray.java
│ ├── ObjectArray.java
│ └── PrimitiveArray.java
└── tools
└── stubgen.jar
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # generated files
12 | app/bin/
13 | app/gen/
14 | libnode/gen/
15 | libnode/bin/
16 | bridge-java/bin/
17 | bridge-java/out/
18 | bridge-stub-generator/bin/
19 |
20 | # shared libraries
21 | app/assets/
22 |
23 | # Local configuration file (sdk path, etc)
24 | local.properties
25 | project.properties
26 | proguard-project.txt
27 |
28 | # ndk-build files
29 | libs/
30 | obj/
31 |
--------------------------------------------------------------------------------
/Android.mk:
--------------------------------------------------------------------------------
1 | $(call import-module,libnode/jni)
2 | $(call import-module,bridge)
3 |
--------------------------------------------------------------------------------
/Application.mk:
--------------------------------------------------------------------------------
1 | ANODE_ROOT := $(call my-dir)
2 |
3 | ifndef NODE_ROOT
4 | NODE_ROOT := $(ANODE_ROOT)/../node
5 | endif
6 |
7 | APP_PROJECT_PATH := $(ANODE_ROOT)
8 | APP_MODULES := jninode bridge
9 | APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/Android.mk
10 | APP_PLATFORM := android-14
11 | APP_ABI := armeabi
12 | NDK_MODULE_PATH := $(NDK_MODULE_PATH):$(ANODE_ROOT):$(ANODE_ROOT)/..:$(NODE_ROOT):$(NODE_ROOT)/..
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Paddy Byers
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Introduction
2 |
3 | Anode is an embryonic framework for running node.js applications on Android. There are two main parts to this:
4 |
5 | - a port of [node.js](https://github.com/joyent/node) to the Android OS and libraries. The code is [here](https://github.com/paddybyers/node);
6 |
7 | - a set of Android projects (this repo) that provide the integration with the Android frameworks.
8 |
9 | Anode builds to an Android application package (.apk) that encapsulates the node.js runtime and can run node.js applications through an intent-based API.
10 |
11 | ## Status
12 |
13 | This work is at an early stage. All input is welcome.
14 |
15 | The current target is to support node.js applications, invoked by intent. Multiple instances can be run in parallel. Modules (or addons) for node.js written in JavaScript or native are supported, and support for modules implemented in Java is on the roadmap.
16 |
17 | This framework depends on a port of node [here](https://github.com/paddybyers/node).
18 |
19 | ## More information
20 |
21 | Please see the [wiki](https://github.com/paddybyers/anode/wiki/Anode) for more information.
22 |
--------------------------------------------------------------------------------
/app/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | app
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/app/assets/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddybyers/anode/0dd99e2ec33e80c6ec46ed769530fe208bfcf488/app/assets/.gitignore
--------------------------------------------------------------------------------
/app/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
29 |
30 |
31 |
35 |
36 |
37 |
38 |
39 |
40 |
49 |
50 |
51 |
52 |
56 |
57 |
69 |
70 |
71 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/app/contrib/jtar-2.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddybyers/anode/0dd99e2ec33e80c6ec46ed769530fe208bfcf488/app/contrib/jtar-2.2.jar
--------------------------------------------------------------------------------
/app/proguard.cfg:
--------------------------------------------------------------------------------
1 | -optimizationpasses 5
2 | -dontusemixedcaseclassnames
3 | -dontskipnonpubliclibraryclasses
4 | -dontpreverify
5 | -verbose
6 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
7 |
8 | -keep public class * extends android.app.Activity
9 | -keep public class * extends android.app.Application
10 | -keep public class * extends android.app.Service
11 | -keep public class * extends android.content.BroadcastReceiver
12 | -keep public class * extends android.content.ContentProvider
13 | -keep public class * extends android.app.backup.BackupAgentHelper
14 | -keep public class * extends android.preference.Preference
15 | -keep public class com.android.vending.licensing.ILicensingService
16 |
17 | -keepclasseswithmembernames class * {
18 | native ;
19 | }
20 |
21 | -keepclasseswithmembers class * {
22 | public (android.content.Context, android.util.AttributeSet);
23 | }
24 |
25 | -keepclasseswithmembers class * {
26 | public (android.content.Context, android.util.AttributeSet, int);
27 | }
28 |
29 | -keepclassmembers class * extends android.app.Activity {
30 | public void *(android.view.View);
31 | }
32 |
33 | -keepclassmembers enum * {
34 | public static **[] values();
35 | public static ** valueOf(java.lang.String);
36 | }
37 |
38 | -keep class * implements android.os.Parcelable {
39 | public static final android.os.Parcelable$Creator *;
40 | }
41 |
--------------------------------------------------------------------------------
/app/res/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddybyers/anode/0dd99e2ec33e80c6ec46ed769530fe208bfcf488/app/res/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/app/res/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddybyers/anode/0dd99e2ec33e80c6ec46ed769530fe208bfcf488/app/res/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/app/res/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paddybyers/anode/0dd99e2ec33e80c6ec46ed769530fe208bfcf488/app/res/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/app/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Anode
4 | Start
5 | Stop
6 | Arguments:
7 | Run state
8 | Created
9 | Started
10 | Stopping
11 | Stopped
12 | Anode Receiver
13 | A broadcast receiver for controlling invocations of node.js
14 | Anode Service
15 | A service that permits the running of node.js invocations in the background
16 |
17 |
--------------------------------------------------------------------------------
/app/src/org/meshpoint/anode/AnodeActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Paddy Byers
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.meshpoint.anode;
18 |
19 | import org.meshpoint.anode.Runtime;
20 | import org.meshpoint.anode.Runtime.IllegalStateException;
21 | import org.meshpoint.anode.Runtime.InitialisationException;
22 | import org.meshpoint.anode.Runtime.NodeException;
23 | import org.meshpoint.anode.Runtime.StateListener;
24 |
25 | import android.app.Activity;
26 | import android.content.Context;
27 | import android.content.res.Resources;
28 | import android.os.Bundle;
29 | import android.os.Handler;
30 | import android.util.Log;
31 | import android.view.KeyEvent;
32 | import android.view.View;
33 | import android.view.View.OnClickListener;
34 | import android.view.View.OnKeyListener;
35 | import android.widget.Button;
36 | import android.widget.EditText;
37 | import android.widget.TextView;
38 |
39 | public class AnodeActivity extends Activity implements StateListener {
40 |
41 | private static String TAG = "anode::AnodeActivity";
42 | private Context ctx;
43 | private Button startButton;
44 | private Button stopButton;
45 | private EditText argsText;
46 | private TextView stateText;
47 | private Handler viewHandler = new Handler();
48 | private long uiThread;
49 | private String instance;
50 | private Isolate isolate;
51 |
52 | /** Called when the activity is first created. */
53 | @Override
54 | public void onCreate(Bundle savedInstanceState) {
55 | super.onCreate(savedInstanceState);
56 | setContentView(R.layout.main);
57 | ctx = getApplicationContext();
58 | initUI();
59 | uiThread = viewHandler.getLooper().getThread().getId();
60 | }
61 |
62 | private void initUI() {
63 | startButton = (Button)findViewById(R.id.start_button);
64 | startButton.setOnClickListener(new StartClickListener());
65 | stopButton = (Button)findViewById(R.id.stop_button);
66 | stopButton.setOnClickListener(new StopClickListener());
67 | argsText = (EditText)findViewById(R.id.args_editText);
68 | stateText = (TextView)findViewById(R.id.args_stateText);
69 | argsText.setOnKeyListener(new OnKeyListener() {
70 | public boolean onKey(View v, int keyCode, KeyEvent event) {
71 | /* If the event is a key-down event on the "enter" button */
72 | if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
73 | (keyCode == KeyEvent.KEYCODE_ENTER)) {
74 | startAction();
75 | return true;
76 | }
77 | return false;
78 | }
79 | });
80 | __stateChanged(Runtime.STATE_CREATED);
81 | }
82 |
83 | private void initRuntime(String[] opts) {
84 | try {
85 | Runtime.initRuntime(ctx, opts);
86 | } catch (InitialisationException e) {
87 | Log.v(TAG, "initRuntime: exception: " + e + "; cause: " + e.getCause());
88 | }
89 | }
90 |
91 | private void startAction() {
92 | String options = getIntent().getStringExtra(AnodeReceiver.OPTS);
93 | String instance = getIntent().getStringExtra(AnodeReceiver.INST);
94 | String[] opts = options == null ? null : options.split("\\s");
95 | initRuntime(opts);
96 | String args = argsText.getText().toString();
97 | try {
98 | isolate = Runtime.createIsolate();
99 | isolate.addStateListener(this);
100 | this.instance = AnodeService.addInstance(instance, isolate);
101 | isolate.start(args.split("\\s"));
102 | } catch (IllegalStateException e) {
103 | Log.v(TAG, "isolate start: exception: " + e + "; cause: " + e.getCause());
104 | } catch (NodeException e) {
105 | Log.v(TAG, "isolate start: exception: " + e);
106 | }
107 | }
108 |
109 | private void stopAction() {
110 | if(instance == null) {
111 | Log.v(TAG, "AnodeReceiver.onReceive::stop: no instance currently running for this activity");
112 | return;
113 | }
114 | try {
115 | isolate.stop();
116 | } catch (IllegalStateException e) {
117 | Log.v(TAG, "isolate stop : exception: " + e + "; cause: " + e.getCause());
118 | } catch (NodeException e) {
119 | Log.v(TAG, "isolate stop: exception: " + e);
120 | }
121 | }
122 |
123 | class StartClickListener implements OnClickListener {
124 | public void onClick(View arg0) {
125 | startAction();
126 | }
127 | }
128 |
129 | class StopClickListener implements OnClickListener {
130 | public void onClick(View arg0) {
131 | stopAction();
132 | }
133 | }
134 |
135 | @Override
136 | public void stateChanged(final int state) {
137 | if(Thread.currentThread().getId() == uiThread) {
138 | __stateChanged(state);
139 | } else {
140 | viewHandler.post(new Runnable() {
141 | public void run() {
142 | __stateChanged(state);
143 | }
144 | });
145 | }
146 | }
147 |
148 | private void __stateChanged(final int state) {
149 | stateText.setText(getStateString(state));
150 | startButton.setEnabled(state == Runtime.STATE_CREATED);
151 | stopButton.setEnabled(state == Runtime.STATE_STARTED);
152 | /* exit the activity if the runtime has exited */
153 | if(state == Runtime.STATE_STOPPED) {
154 | finish();
155 | }
156 | }
157 |
158 | private String getStateString(int state) {
159 | Resources res = ctx.getResources();
160 | String result = null;
161 | switch(state) {
162 | case Runtime.STATE_CREATED:
163 | result = res.getString(R.string.created);
164 | break;
165 | case Runtime.STATE_STARTED:
166 | result = res.getString(R.string.started);
167 | break;
168 | case Runtime.STATE_STOPPING:
169 | result = res.getString(R.string.stopping);
170 | break;
171 | case Runtime.STATE_STOPPED:
172 | result = res.getString(R.string.stopped);
173 | break;
174 | }
175 | return result;
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/app/src/org/meshpoint/anode/AnodeReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Paddy Byers
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.meshpoint.anode;
18 |
19 | import org.meshpoint.anode.Runtime.IllegalStateException;
20 | import org.meshpoint.anode.Runtime.NodeException;
21 |
22 | import android.content.BroadcastReceiver;
23 | import android.content.Context;
24 | import android.content.Intent;
25 | import android.util.Log;
26 |
27 | public class AnodeReceiver extends BroadcastReceiver {
28 |
29 | private static String TAG = "anode::AnodeReceiver";
30 | public static final String ACTION_START = "org.meshpoint.anode.START";
31 | public static final String ACTION_STOP = "org.meshpoint.anode.STOP";
32 | public static final String ACTION_STOPALL = "org.meshpoint.anode.STOPALL";
33 | public static final String ACTION_INSTALL = "org.meshpoint.anode.INSTALL";
34 | public static final String ACTION_UNINSTALL = "org.meshpoint.anode.UNINSTALL";
35 | public static final String CMD = "cmdline";
36 | public static final String INST = "instance";
37 | public static final String OPTS = "options";
38 | public static final String MODULE = "module";
39 | public static final String PATH = "path";
40 |
41 | public AnodeReceiver() {
42 | super();
43 | }
44 |
45 | @Override
46 | public void onReceive(Context ctx, Intent intent) {
47 | /* get the system options */
48 | String action = intent.getAction();
49 | if(ACTION_STOPALL.equals(action)) {
50 | if(Runtime.isInitialised()) {
51 | for(Isolate isolate : AnodeService.getAll())
52 | stopInstance(isolate);
53 | }
54 | return;
55 | }
56 | if(ACTION_STOP.equals(action)) {
57 | if(Runtime.isInitialised()) {
58 | String instance = intent.getStringExtra(INST);
59 | if(instance == null) {
60 | instance = AnodeService.soleInstance();
61 | if(instance == null) {
62 | Log.v(TAG, "AnodeReceiver.onReceive::stop: no instance specified");
63 | return;
64 | }
65 | }
66 | Isolate isolate = AnodeService.getInstance(instance);
67 | if(isolate == null) {
68 | Log.v(TAG, "AnodeReceiver.onReceive::stop: instance " + instance + " not found");
69 | return;
70 | }
71 | stopInstance(isolate);
72 | }
73 | return;
74 | }
75 |
76 | if(ACTION_START.equals(action)) {
77 | /* get the launch commandline */
78 | String args = intent.getStringExtra(CMD);
79 |
80 | /* if no cmdline was sent, then launch the activity for interactive behaviour */
81 | if(args == null || args.isEmpty()) {
82 | intent.setClassName(ctx, AnodeActivity.class.getName());
83 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
84 | ctx.startActivity(intent);
85 | return;
86 | }
87 | }
88 |
89 | /* otherwise, start service */
90 | intent.setClassName(ctx, AnodeService.class.getName());
91 | ctx.startService(intent);
92 | }
93 |
94 | private void stopInstance(Isolate isolate) {
95 | try {
96 | isolate.stop();
97 | } catch (IllegalStateException e) {
98 | Log.v(TAG, "AnodeReceiver.onReceive::stop: exception: " + e + "; cause: " + e.getCause());
99 | } catch (NodeException e) {
100 | Log.v(TAG, "AnodeReceiver.onReceive::stop: exception: " + e + "; cause: " + e.getCause());
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/app/src/org/meshpoint/anode/Constants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Paddy Byers
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.meshpoint.anode;
18 |
19 | public interface Constants {
20 |
21 | public static final String RESOURCE_DIR = "/data/data/org.meshpoint.anode/uriCache";
22 | public static final String MODULE_DIR = "/data/data/org.meshpoint.anode/node_modules";
23 | public static final String APP_DIR = "/data/data/org.meshpoint.anode/app";
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/org/meshpoint/anode/util/AndroidLog.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Paddy Byers
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.meshpoint.anode.util;
18 |
19 | public class AndroidLog implements Log {
20 |
21 | @Override
22 | public int v(String tag, String msg) {
23 | return android.util.Log.v(tag, msg);
24 | }
25 |
26 | @Override
27 | public int v(String tag, String msg, Throwable tr) {
28 | return android.util.Log.v(tag, msg, tr);
29 | }
30 |
31 | @Override
32 | public int d(String tag, String msg) {
33 | return android.util.Log.d(tag, msg);
34 | }
35 |
36 | @Override
37 | public int d(String tag, String msg, Throwable tr) {
38 | return android.util.Log.d(tag, msg, tr);
39 | }
40 |
41 | @Override
42 | public int i(String tag, String msg) {
43 | return android.util.Log.i(tag, msg);
44 | }
45 |
46 | @Override
47 | public int i(String tag, String msg, Throwable tr) {
48 | return android.util.Log.i(tag, msg, tr);
49 | }
50 |
51 | @Override
52 | public int w(String tag, String msg) {
53 | return android.util.Log.w(tag, msg);
54 | }
55 |
56 | @Override
57 | public int w(String tag, String msg, Throwable tr) {
58 | return android.util.Log.w(tag, msg, tr);
59 | }
60 |
61 | @Override
62 | public int w(String tag, Throwable tr) {
63 | return android.util.Log.w(tag, tr);
64 | }
65 |
66 | @Override
67 | public int e(String tag, String msg) {
68 | return android.util.Log.e(tag, msg);
69 | }
70 |
71 | @Override
72 | public int e(String tag, String msg, Throwable tr) {
73 | return android.util.Log.e(tag, msg, tr);
74 | }
75 |
76 | @Override
77 | public int wtf(String tag, String msg) {
78 | return android.util.Log.wtf(tag, msg);
79 | }
80 |
81 | @Override
82 | public int wtf(String tag, Throwable tr) {
83 | return android.util.Log.wtf(tag, tr);
84 | }
85 |
86 | @Override
87 | public int wtf(String tag, String msg, Throwable tr) {
88 | return android.util.Log.wtf(tag, msg, tr);
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/app/src/org/meshpoint/anode/util/ArgProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Paddy Byers
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.meshpoint.anode.util;
18 |
19 | import java.io.IOException;
20 | import java.net.URI;
21 | import java.net.URISyntaxException;
22 | import java.util.HashMap;
23 | import java.util.Map;
24 | import java.util.Set;
25 |
26 | import org.meshpoint.anode.Constants;
27 |
28 | import android.os.Bundle;
29 | import android.util.Log;
30 |
31 | /**
32 | * A class that processes a given commandline together with an optional
33 | * mapping of resource identifiers and URLs to fetch those resources.
34 | *
35 | * Resources are limited to those that can be fetched with an http GET.
36 | *
37 | * Downloaded resources are cached in an asset directory specific to the
38 | * application, obtained using the supplied Context.
39 | * Cached resources are stored in files whose names are a hash of the
40 | * originating URL. It is safe to reuse the cache directory across
41 | * multiple invocations of the same app, or across invocations of different
42 | * apps.
43 | *
44 | * No processing is performed of expiry times of the specified resources
45 | * so they are downloaded again on each invocation.
46 | *
47 | * Name substitution is performed in the supplied commandline, to map
48 | * resource specifiers to the local cache filename.
49 | *
50 | * A resource is identified with a Bundle entry of:
51 | * get: =
52 | * and is referenced in the commandline by:
53 | * %
54 | */
55 | public class ArgProcessor {
56 |
57 | private static String TAG = "anode::ArgsProcessor";
58 | private static final String GET_PREFIX = "get:";
59 |
60 | private Bundle extras;
61 | private String text;
62 | private Map uriMap;
63 | private Map filenameMap;
64 |
65 | /**
66 | * Constructs an instance of ArgProcessor
67 | * @param extras an optional bundle containing the mapping parameters
68 | * @param text the string to process
69 | */
70 | public ArgProcessor(Bundle extras, String text) {
71 | this.extras = extras;
72 | this.text = text;
73 | uriMap = new HashMap();
74 | filenameMap = new HashMap();
75 | }
76 |
77 | /**
78 | * Process the text string
79 | * @return the processed string, with downloaded resource names substituted
80 | */
81 | public String processString() {
82 | if(extras != null) {
83 | /* extract list of args to get */
84 | try {
85 | Set keys = extras.keySet();
86 | for(String key : keys) {
87 | if(key.startsWith(GET_PREFIX)) {
88 | String rawUri = extras.getString(key);
89 | String rawKey = key.substring(GET_PREFIX.length());
90 | URI uri = new URI(rawUri);
91 | String filename = ModuleUtils.getResourceUriHash(rawUri);
92 | uriMap.put(rawKey, uri);
93 | filenameMap.put(rawKey, filename);
94 | }
95 | }
96 | } catch(URISyntaxException e) {
97 | Log.v(TAG, "process exception: aborting; exception: " + e);
98 | return null;
99 | }
100 |
101 | /* download each asset */
102 | for(String key : uriMap.keySet()) {
103 | try {
104 | ModuleUtils.getResource(uriMap.get(key), filenameMap.get(key));
105 | } catch(IOException e) {
106 | Log.v(TAG, "process exception: aborting; exception: " + e + "; resource = " + uriMap.get(key).toString());
107 | return null;
108 | }
109 | }
110 |
111 | /* process the commandline */
112 | for(String key : filenameMap.keySet()) {
113 | text = text.replace("%" + key, Constants.RESOURCE_DIR + '/' + filenameMap.get(key));
114 | }
115 | }
116 | return text;
117 | }
118 |
119 | public String[] processArray() {
120 | /* split the commandline at whitespace */
121 | processString();
122 | return text.split("\\s");
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/app/src/org/meshpoint/anode/util/TarExtractor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Paddy Byers
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.meshpoint.anode.util;
18 |
19 | import java.io.BufferedInputStream;
20 | import java.io.BufferedOutputStream;
21 | import java.io.File;
22 | import java.io.FileInputStream;
23 | import java.io.FileOutputStream;
24 | import java.io.IOException;
25 | import java.util.zip.GZIPInputStream;
26 |
27 | import org.kamranzafar.jtar.TarEntry;
28 | import org.kamranzafar.jtar.TarInputStream;
29 |
30 | public class TarExtractor implements ModuleUtils.Unpacker {
31 |
32 | public void unpack(File src, File dest) throws IOException {
33 | /* first extract the tar file */
34 | File tarFile = new File(src.getAbsolutePath() + ".tar");
35 | byte[] buf = new byte[1024];
36 | GZIPInputStream zis = null;
37 | zis = new GZIPInputStream(new FileInputStream(src));
38 | FileOutputStream tarfos = new FileOutputStream(tarFile);
39 | int count;
40 | while ((count = zis.read(buf, 0, 1024)) != -1)
41 | tarfos.write(buf, 0, count);
42 | tarfos.close();
43 | zis.close();
44 |
45 | /* now unpack the tar */
46 | TarInputStream tis = new TarInputStream(new BufferedInputStream(
47 | new FileInputStream(tarFile)));
48 | TarEntry entry;
49 | while ((entry = tis.getNextEntry()) != null) {
50 | File entryFile = new File(dest, entry.getName());
51 | File parentDir = new File(entryFile.getParent());
52 |
53 | if (!parentDir.isDirectory() && !parentDir.mkdirs()) {
54 | tis.close();
55 | throw new IOException(
56 | "TarExtractor.unpack(): unable to create directory");
57 | }
58 |
59 | if (entry.getName().equals("././@LongLink")) {
60 | // GNU tar format not supported by jtar
61 | // attempt to recover:
62 | // LongLink entry provides full file name for following entry
63 | // -> read file name from body and skip ahead
64 | String filename = "";
65 | while ((count = tis.read(buf)) != -1) {
66 | filename += new String(buf, 0, count - 1);
67 | }
68 | entry = tis.getNextEntry();
69 | entryFile = new File(dest, filename);
70 | android.util.Log.v("TarExtractor",
71 | String.format("Encountered long filename." +
72 | " Moving on to: %s:%s -> %s",
73 | entry.getName(), entry.isDirectory(), entryFile));
74 | }
75 | if (entry.isDirectory()) {
76 | if (entryFile.isDirectory()) {
77 | // directory already exists
78 | android.util.Log.v("TarExtractor",
79 | "directory for " + entry.getName() + " already exists");
80 | } else if (entryFile.mkdir()) {
81 | // directory created (side effect)
82 | android.util.Log.v("TarExtractor",
83 | "directory created for " + entry.getName());
84 | } else {
85 | // fail
86 | android.util.Log.w("TarExtractor",
87 | "failed to create directory for " + entry.getName());
88 | }
89 | } else if (!entryFile.isDirectory()) {
90 | FileOutputStream fos = new FileOutputStream(entryFile);
91 | BufferedOutputStream bos = new BufferedOutputStream(fos);
92 | while ((count = tis.read(buf)) != -1) {
93 | bos.write(buf, 0, count);
94 | }
95 |
96 | bos.flush();
97 | bos.close();
98 | } else {
99 | android.util.Log.v("TarExtractor",
100 | String.format("What? %s:%s:%s", entryFile,
101 | entryFile.isDirectory(), entry.isDirectory())
102 | );
103 | }
104 | }
105 | tis.close();
106 |
107 | /* delete the tar file */
108 | tarFile.delete();
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/app/src/org/meshpoint/anode/util/ZipExtractor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Paddy Byers
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.meshpoint.anode.util;
18 |
19 | import java.io.File;
20 | import java.io.FileInputStream;
21 | import java.io.FileOutputStream;
22 | import java.io.IOException;
23 | import java.util.zip.ZipEntry;
24 | import java.util.zip.ZipInputStream;
25 |
26 | public class ZipExtractor implements ModuleUtils.Unpacker {
27 |
28 | public void unpack(File src, File dest) throws IOException {
29 | int count;
30 | byte[] buf = new byte[1024];
31 | ZipInputStream zis = null;
32 | ZipEntry zipentry;
33 | zis = new ZipInputStream(new FileInputStream(src));
34 |
35 | while ((zipentry = zis.getNextEntry()) != null) {
36 | String entryName = zipentry.getName();
37 | File entryFile = new File(dest, entryName);
38 | File parentDir = new File(entryFile.getParent());
39 | if(!parentDir.isDirectory() && !parentDir.mkdirs())
40 | throw new IOException("ZipExtractor.unpack(): unable to create directory");
41 |
42 | if(zipentry.isDirectory()) {
43 | if(!entryFile.mkdir())
44 | throw new IOException("ZipExtractor.unpack(): unable to create directory entry");
45 | } else {
46 | FileOutputStream fos = new FileOutputStream(entryFile);
47 | while ((count = zis.read(buf, 0, 1024)) != -1)
48 | fos.write(buf, 0, count);
49 |
50 | fos.close();
51 | }
52 | zis.closeEntry();
53 | }
54 | zis.close();
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/bridge-java/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/bridge-java/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | bridge-java
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/bridge-java/build.xml:
--------------------------------------------------------------------------------
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 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/bridge-java/src/org/meshpoint/anode/bridge/BridgeNative.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Paddy Byers
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.meshpoint.anode.bridge;
18 |
19 | import java.util.Collection;
20 |
21 | import org.meshpoint.anode.idl.IDLInterface;
22 |
23 | public class BridgeNative {
24 |
25 | private static final String LIBRARY_PATH = System.getenv("NODE_ROOT");
26 | private static final String BRIDGE_LIBRARY = "bridge.node";
27 |
28 | static {
29 | try {
30 | System.load(LIBRARY_PATH + '/' + BRIDGE_LIBRARY);
31 | } catch(UnsatisfiedLinkError e) {
32 | System.err.println("Unable to load bridge native library: " + LIBRARY_PATH);
33 | }
34 | }
35 |
36 | /* IFunction */
37 | native static Object callAsFunction(long envHandle, long instHandle, Object target, Object[] args);
38 | native static Object callAsConstructor(long envHandle, long instHandle, Object[] args);
39 |
40 | /* ICollection */
41 | native static Object getProperty(long envHandle, long instHandle, String key);
42 | native static void setProperty(long envHandle, long instHandle, String key, Object value);
43 | native static void deleteProperty(long envHandle, long instHandle, String key);
44 | native static boolean containsProperty(long envHandle, long instHandle, String key);
45 | native static Collection properties(long envHandle, long instHandle);
46 |
47 | /* IIndexedCollection */
48 | public native static Object getIndexedProperty(long envHandle, long instHandle, int elementType, int idx);
49 | public native static void setIndexedProperty(long envHandle, long instHandle, int elementType, int idx, Object value);
50 | public native static void deleteIndexedProperty(long envHandle, long instHandle, int idx);
51 | public native static boolean containsIndex(long envHandle, long instHandle, int idx);
52 | public native static int getLength(long envHandle, long instHandle);
53 | public native static void setLength(long envHandle, long instHandle, int length);
54 |
55 | /* JSInterface */
56 | public native static Object invokeJSInterface(long envHandle, long instHandle, int classId, int opIdx, Object[] args);
57 | public native static Object getJSInterface(long envHandle, long instHandle, int classId, int attrIdx);
58 | public native static void setJSInterface(long envHandle, long instHandle, int classId, int attrIdx, Object val);
59 |
60 | /* instance handle management */
61 | native static void releaseObjectHandle(long envHandle, long instHandle, int type);
62 |
63 | /* interface handle management */
64 | public native static long bindInterface(long envHandle, long parentHandle, IDLInterface iface, int classId, int attrCount, int opCount, Class> declaredClass);
65 | public native static void bindAttribute(long envHandle, long ifaceHandle, int attrIdx, int type, String name);
66 | public native static void bindOperation(long envHandle, long ifaceHandle, int opIdx, int type, String name, int argCount, int[] argTypes);
67 | public native static void releaseInterface(long envHandle, long ifaceHandle);
68 | public native static void bindUserStub(long envHandle, long interfaceHandle, Class> userStub);
69 | public native static void bindPlatformStub(long envHandle, long interfaceHandle, Class> platformStub);
70 | public native static void bindDictStub(long envHandle, long interfaceHandle, Class> dictStub);
71 |
72 | /* event thread management */
73 | public native static void requestEntry(long envHandle);
74 |
75 | /* context initialisation:
76 | * used in the Android implementation to pass an Android context
77 | * object which is then passed to modules implemented in the bridge */
78 | public native static void setContext(Object opaqueContextObject);
79 | }
80 |
--------------------------------------------------------------------------------
/bridge-java/src/org/meshpoint/anode/bridge/FinalizeQueue.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Paddy Byers
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.meshpoint.anode.bridge;
18 |
19 | public class FinalizeQueue implements SynchronousOperation {
20 |
21 | /********************
22 | * private state
23 | ********************/
24 | private final String TAG = FinalizeQueue.class.getCanonicalName();
25 | private Env env;
26 | private static final int QUEUE_LENGTH = 1024;
27 | private long[] handleBuffer = new long[QUEUE_LENGTH];
28 | private int[] typeBuffer = new int[QUEUE_LENGTH];
29 | private int count;
30 |
31 | /********************
32 | * public API
33 | *******************/
34 |
35 | public FinalizeQueue(Env env) {
36 | this.env = env;
37 | }
38 |
39 | /**
40 | * Appends a new item to the queue; may be called
41 | * from any thread
42 | * @param h the handle
43 | */
44 | public synchronized void put(long h, int type) {
45 | if(count == QUEUE_LENGTH)
46 | env.waitForOperation(this);
47 | if(count == QUEUE_LENGTH)
48 | throw new RuntimeException("Fatal error processing FinalizeQueue");
49 | handleBuffer[count] = h;
50 | typeBuffer[count++] = type;
51 | }
52 |
53 | /**
54 | * Removes and releases all items currently queued
55 | */
56 | @Override
57 | public synchronized void run() {
58 | for(int i = 0; i < count; i++) {
59 | //Log.v(TAG, "Finalizing; instHandle = " + handleBuffer[i] + "; type = " + typeBuffer[i]);
60 | BridgeNative.releaseObjectHandle(env.envHandle, handleBuffer[i], typeBuffer[i]);
61 | }
62 | count = 0;
63 | }
64 |
65 | @Override
66 | public synchronized boolean isPending() {
67 | return count > 0;
68 | }
69 |
70 | @Override
71 | public void cancel() {}
72 | }
73 |
--------------------------------------------------------------------------------
/bridge-java/src/org/meshpoint/anode/bridge/ModuleContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011-2012 Paddy Byers
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.meshpoint.anode.bridge;
18 |
19 | import org.meshpoint.anode.js.JSObject;
20 | import org.meshpoint.anode.module.IModule;
21 | import org.meshpoint.anode.module.IModuleContext;
22 | import org.meshpoint.anode.type.IIndexedCollection;
23 |
24 | public class ModuleContext implements IModuleContext {
25 | @SuppressWarnings("unused")
26 | private Env env;
27 | private JSObject exports;
28 | private IModule module;
29 | private long threadId;
30 |
31 | protected ModuleContext(Env env, JSObject exports) {
32 | this.env = env;
33 | this.exports = exports;
34 | threadId = Thread.currentThread().getId();
35 | }
36 |
37 | void setModule(IModule module) {
38 | this.module = module;
39 | }
40 |
41 | @Override
42 | public IIndexedCollection