├── .travis.yml ├── nodel-framework-ios └── reserved.txt ├── nodel-framework-dotnet └── reserved.txt ├── nodel-webui-js ├── src │ ├── custom.js │ ├── logo.png │ ├── favicon.ico │ ├── apple-touch-icon.png │ ├── custom.css │ ├── build.json │ ├── qrcode.css │ ├── index.smil │ ├── custom-sample.py │ ├── nodes.xml │ ├── locals.xml │ ├── toolkit.xml │ ├── index.htm │ ├── light │ │ └── gen │ │ │ └── variable_gen.py │ ├── diagnostics.xml │ ├── polyfill.js │ ├── generator.py │ ├── status.xml │ ├── schemas.json │ ├── nodel.xml │ └── spectrum │ │ └── spectrum-dark.css └── package.json ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── nodelbrowse-chromeext ├── img │ ├── icon-128.png │ ├── icon-16.png │ └── working.gif ├── background.js ├── README.md ├── manifest.json ├── main.html └── main.css ├── nodel-windows └── service │ ├── NodelHostsvcw.exe │ ├── NodelHostsvc.exe.x64 │ ├── NodelHostsvc.exe.x86 │ ├── uninstall_service.bat │ ├── readme.md │ └── install_as_service.bat ├── nodel-jyhost └── src │ └── main │ ├── resources │ └── org │ │ ├── slf4j │ │ └── impl │ │ │ └── jdk14_logging.properties │ │ └── nodel │ │ └── jyhost │ │ ├── example.pysp │ │ └── first_node.py │ └── java │ └── org │ ├── nodel │ ├── websockets │ │ ├── QueueEntry.java │ │ ├── WebSocketMessage.java │ │ └── SessionEntry.java │ ├── http │ │ └── StaticNodelHttpClientProvider.java │ ├── snmp │ │ └── NodelSnmp.java │ └── jyhost │ │ ├── PyToolkit.java │ │ ├── ExampleScript.java │ │ └── ExamplePySp.java │ └── slf4j │ └── impl │ └── JDK14LoggingHandler.java ├── recipes └── README.md ├── toolkit-util └── ProcessSandbox │ ├── App.config │ ├── Properties │ └── AssemblyInfo.cs │ └── ProcessSandbox.csproj ├── dictionary.txt ├── nodel-framework ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── nanohttpd │ │ │ │ ├── mimetypes.properties │ │ │ │ └── default-mimetypes.properties │ │ └── java │ │ │ └── org │ │ │ ├── nodel │ │ │ ├── reflection │ │ │ │ ├── SetterInfo.java │ │ │ │ ├── EnumDesc.java │ │ │ │ ├── EnumTitle.java │ │ │ │ ├── ReflectionException.java │ │ │ │ ├── Setter.java │ │ │ │ ├── EnumInfo.java │ │ │ │ ├── SerialisationException.java │ │ │ │ ├── MultiClassValue.java │ │ │ │ ├── ServiceInfo.java │ │ │ │ ├── ParameterInfo.java │ │ │ │ ├── Param.java │ │ │ │ ├── Service.java │ │ │ │ └── Value.java │ │ │ ├── core │ │ │ │ ├── ArgInstance.java │ │ │ │ ├── ActionRequestHandler.java │ │ │ │ ├── NodelEventHandler.java │ │ │ │ ├── BindingState.java │ │ │ │ ├── NodelException.java │ │ │ │ ├── LoopbackChannelClient.java │ │ │ │ ├── NodelPoint.java │ │ │ │ ├── LoopbackChannelServer.java │ │ │ │ ├── NodeAddress.java │ │ │ │ └── ChannelMessage.java │ │ │ ├── diagnostics │ │ │ │ ├── MeasurementProvider.java │ │ │ │ ├── LongSharableMeasurementProvider.java │ │ │ │ ├── AtomicLongMeasurementProvider.java │ │ │ │ ├── AtomicIntegerMeasurementProvider.java │ │ │ │ ├── SharableMeasurementProvider.java │ │ │ │ ├── CountableOutputStream.java │ │ │ │ └── CountableInputStream.java │ │ │ ├── io │ │ │ │ ├── UnexpectedIOException.java │ │ │ │ └── UTF8Charset.java │ │ │ ├── rest │ │ │ │ ├── InvalidCallException.java │ │ │ │ ├── CallException.java │ │ │ │ └── EndpointNotFoundException.java │ │ │ ├── json │ │ │ │ ├── JSONString.java │ │ │ │ ├── JSONException.java │ │ │ │ └── HTTPTokener.java │ │ │ ├── StartupException.java │ │ │ ├── UnexpectedInterruptedException.java │ │ │ ├── host │ │ │ │ ├── OperationPendingException.java │ │ │ │ ├── ParamValues.java │ │ │ │ ├── ConsoleLogEntry.java │ │ │ │ ├── ParameterBinding.java │ │ │ │ ├── NodelEventInfo.java │ │ │ │ ├── NodelActionInfo.java │ │ │ │ ├── Bindings.java │ │ │ │ ├── NodeConfig.java │ │ │ │ ├── LogEntry.java │ │ │ │ └── ParameterBindings.java │ │ │ ├── logging │ │ │ │ ├── Level.java │ │ │ │ └── slf4j │ │ │ │ │ └── SimpleLoggerFactory.java │ │ │ ├── threading │ │ │ │ ├── TimerTask.java │ │ │ │ └── Atomic.java │ │ │ ├── toolkit │ │ │ │ └── Console.java │ │ │ ├── net │ │ │ │ ├── Credentials.java │ │ │ │ ├── NodelHttpClientProvider.java │ │ │ │ └── HTTPSimpleResponse.java │ │ │ ├── Random.java │ │ │ ├── LockFreeList.java │ │ │ ├── Version.java │ │ │ ├── Exceptions.java │ │ │ ├── DateTimes.java │ │ │ ├── Strings.java │ │ │ ├── UUIDs.java │ │ │ └── discovery │ │ │ │ ├── NameServicesChannelMessage.java │ │ │ │ └── UDPPacketRecycleQueue.java │ │ │ └── nanohttpd │ │ │ ├── protocols │ │ │ ├── http │ │ │ │ ├── request │ │ │ │ │ ├── Request.java │ │ │ │ │ └── Method.java │ │ │ │ ├── response │ │ │ │ │ ├── IStatus.java │ │ │ │ │ └── ChunkedOutputStream.java │ │ │ │ ├── threading │ │ │ │ │ └── IAsyncRunner.java │ │ │ │ ├── tempfiles │ │ │ │ │ ├── ITempFileManager.java │ │ │ │ │ ├── ITempFile.java │ │ │ │ │ ├── DefaultTempFileManagerFactory.java │ │ │ │ │ └── DefaultTempFile.java │ │ │ │ ├── sockets │ │ │ │ │ ├── DefaultServerSocketFactory.java │ │ │ │ │ └── SecureServerSocketFactory.java │ │ │ │ └── content │ │ │ │ │ └── Cookie.java │ │ │ └── websockets │ │ │ │ ├── State.java │ │ │ │ ├── OpCode.java │ │ │ │ ├── CloseCode.java │ │ │ │ └── WebSocketException.java │ │ │ ├── util │ │ │ ├── IFactory.java │ │ │ ├── IHandler.java │ │ │ ├── IFactoryThrowing.java │ │ │ └── ServerRunner.java │ │ │ └── webserver │ │ │ ├── WebServerPluginInfo.java │ │ │ ├── WebServerPlugin.java │ │ │ └── InternalRewrite.java │ └── test │ │ └── java │ │ └── org │ │ └── nodel │ │ ├── GitHubIssue.java │ │ └── SimpleNameTest.java └── build.gradle └── .gitignore /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | -------------------------------------------------------------------------------- /nodel-framework-ios/reserved.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /nodel-framework-dotnet/reserved.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /nodel-webui-js/src/custom.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | // local overrides 3 | }); -------------------------------------------------------------------------------- /nodel-webui-js/src/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/museumsvictoria/nodel/HEAD/nodel-webui-js/src/logo.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include 'nodel-framework', 2 | 'nodel-webui-js', 3 | 'nodel-jyhost' 4 | 5 | -------------------------------------------------------------------------------- /nodel-webui-js/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/museumsvictoria/nodel/HEAD/nodel-webui-js/src/favicon.ico -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/museumsvictoria/nodel/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /nodelbrowse-chromeext/img/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/museumsvictoria/nodel/HEAD/nodelbrowse-chromeext/img/icon-128.png -------------------------------------------------------------------------------- /nodelbrowse-chromeext/img/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/museumsvictoria/nodel/HEAD/nodelbrowse-chromeext/img/icon-16.png -------------------------------------------------------------------------------- /nodelbrowse-chromeext/img/working.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/museumsvictoria/nodel/HEAD/nodelbrowse-chromeext/img/working.gif -------------------------------------------------------------------------------- /nodel-webui-js/src/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/museumsvictoria/nodel/HEAD/nodel-webui-js/src/apple-touch-icon.png -------------------------------------------------------------------------------- /nodel-windows/service/NodelHostsvcw.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/museumsvictoria/nodel/HEAD/nodel-windows/service/NodelHostsvcw.exe -------------------------------------------------------------------------------- /nodel-windows/service/NodelHostsvc.exe.x64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/museumsvictoria/nodel/HEAD/nodel-windows/service/NodelHostsvc.exe.x64 -------------------------------------------------------------------------------- /nodel-windows/service/NodelHostsvc.exe.x86: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/museumsvictoria/nodel/HEAD/nodel-windows/service/NodelHostsvc.exe.x86 -------------------------------------------------------------------------------- /nodel-webui-js/src/custom.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* add for top navbar */ 3 | padding-top: 70px; 4 | /* add for bottom navbar */ 5 | /*padding-bottom: 70px;*/ 6 | } -------------------------------------------------------------------------------- /nodel-windows/service/uninstall_service.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo Unregistering the "NodelHostsvc" service... 3 | pause 4 | ..\NodelHostsvc.exe //DS 5 | 6 | echo Done! 7 | pause 8 | -------------------------------------------------------------------------------- /nodel-jyhost/src/main/resources/org/slf4j/impl/jdk14_logging.properties: -------------------------------------------------------------------------------- 1 | # Java Legacy handler configuration file (java.util.logging) 2 | handlers= org.slf4j.impl.JDK14LoggingHandler 3 | -------------------------------------------------------------------------------- /recipes/README.md: -------------------------------------------------------------------------------- 1 | Moved to https://github.com/museumvictoria/nodel-recipes 2 | 3 | Nodel recipes have been logically separated from the core and moved into their own independent repository. 4 | -------------------------------------------------------------------------------- /toolkit-util/ProcessSandbox/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /nodel-windows/service/readme.md: -------------------------------------------------------------------------------- 1 | For Windows service installation, please use **install_as_service.bat**. 2 | 3 | 32-bit vs 64-bit selection is automatically performed. 4 | 5 | ### Links 6 | Apache commons daemon reference - http://commons.apache.org/proper/commons-daemon/procrun.html -------------------------------------------------------------------------------- /nodel-webui-js/src/build.json: -------------------------------------------------------------------------------- 1 | { 2 | "project" : "@buildProject@", 3 | "origin" : "@buildOrigin@", 4 | "branch" : "@buildBranch@", 5 | "version" : "@buildVersion@", 6 | "id" : "@buildId@", 7 | "rev" : "@buildRev@", 8 | "host" : "@buildHost@", 9 | "date" : "@buildDate@" 10 | } -------------------------------------------------------------------------------- /nodel-webui-js/src/qrcode.css: -------------------------------------------------------------------------------- 1 | .qrcode-card { 2 | } 3 | 4 | .qrcode { 5 | padding: 2px 2px; 6 | background: #fff; 7 | } 8 | 9 | .qrcode-help { 10 | font-size: 12px; 11 | color: #fff; 12 | text-align: center; 13 | margin-top: 5px; 14 | overflow: hidden; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /nodelbrowse-chromeext/background.js: -------------------------------------------------------------------------------- 1 | chrome.app.runtime.onLaunched.addListener(function() { 2 | var w = chrome.appWindow || chrome.app.window; 3 | w.create('main.html', { 4 | frame: 'none', 5 | width: 440, 6 | minWidth: 440, 7 | minHeight: 200, 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /nodelbrowse-chromeext/README.md: -------------------------------------------------------------------------------- 1 | # Nodel browser 2 | 3 | ## APIs 4 | 5 | * [UDP Network](http://developer.chrome.com/trunk/apps/app_network.html#udp) 6 | * [Runtime](http://developer.chrome.com/trunk/apps/app.runtime.html) 7 | * [Window](http://developer.chrome.com/trunk/apps/app.window.html) 8 | 9 | -------------------------------------------------------------------------------- /dictionary.txt: -------------------------------------------------------------------------------- 1 | initialised 2 | config 3 | scriptability 4 | deserialisation 5 | deserialise 6 | concierge 7 | interstitial 8 | mins 9 | lumicom 10 | json 11 | app 12 | deserialises 13 | generics 14 | params 15 | resilient 16 | proxy 17 | downtime 18 | spamming 19 | proxies 20 | deactivation 21 | embeddable 22 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /nodel-framework/src/main/resources/META-INF/nanohttpd/mimetypes.properties: -------------------------------------------------------------------------------- 1 | #mime types for nanohttpd, use a file like this for user defined mimetypes 2 | json=application/javascript 3 | ttf=font/truetype 4 | otf=font/opentype 5 | eot=application/vnd.ms-fontobject 6 | woff=application/x-font-woff 7 | 7z=application/x-7z-compressed -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/SetterInfo.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | public class SetterInfo { 6 | 7 | public String name; 8 | 9 | public Method method; 10 | 11 | public SetterInfo(String name, Method method) { 12 | this.name = name; 13 | this.method = method; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /nodel-webui-js/src/index.smil: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /nodel-jyhost/src/main/java/org/nodel/websockets/QueueEntry.java: -------------------------------------------------------------------------------- 1 | package org.nodel.websockets; 2 | 3 | public class QueueEntry { 4 | /** 5 | * The websocket data. 6 | */ 7 | public WebSocketMessage msg; 8 | 9 | /** 10 | * 'Ping' to be sent 11 | */ 12 | public boolean ping; 13 | 14 | /** 15 | * Socket to close because of silence. 16 | */ 17 | public boolean silentTooLong; 18 | } 19 | -------------------------------------------------------------------------------- /nodel-webui-js/src/custom-sample.py: -------------------------------------------------------------------------------- 1 | local_event_DynamicList = LocalEvent({'group': 'Custom', 'schema': {'type': 'array', 'items': { 2 | 'type': 'object', 'title': 'List', 'properties': { 3 | 'key': {'type': 'string', 'title': 'Key'}, 'value': {'type': 'string', 'title': 'Label'} 4 | }}}}) 5 | 6 | local_event_ConfirmCode = LocalEvent({'group': 'Custom', 'schema': {'type': 'number'}}) -------------------------------------------------------------------------------- /nodel-framework/src/test/java/org/nodel/GitHubIssue.java: -------------------------------------------------------------------------------- 1 | package org.nodel; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target({ ElementType.TYPE, ElementType.METHOD }) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface GitHubIssue { 11 | String value(); // The URL or ID of the GitHub issue 12 | } -------------------------------------------------------------------------------- /nodelbrowse-chromeext/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Nodel browser", 3 | "description": "Browses the Nodel network.", 4 | "manifest_version": 2, 5 | "version": "0.6", 6 | "app": { 7 | "background": { 8 | "scripts": ["background.js"] 9 | } 10 | }, 11 | "permissions": [ 12 | { 13 | "socket": [ 14 | "udp-bind:*", 15 | "udp-send-to:*" 16 | ] 17 | } 18 | ], 19 | "icons": { "128": "img/icon-128.png", "16": "img/icon-16.png" } 20 | } 21 | -------------------------------------------------------------------------------- /nodel-webui-js/src/nodes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
-------------------------------------------------------------------------------- /nodel-webui-js/src/locals.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
-------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/core/ArgInstance.java: -------------------------------------------------------------------------------- 1 | package org.nodel.core; 2 | 3 | import org.joda.time.DateTime; 4 | import org.nodel.reflection.Value; 5 | 6 | /** 7 | * Value and timestamp composite value. 8 | */ 9 | public class ArgInstance { 10 | 11 | public static ArgInstance NULL = new ArgInstance(); 12 | 13 | @Value(name = "timestamp") 14 | public DateTime timestamp; 15 | 16 | @Value(name = "arg") 17 | public Object arg; 18 | 19 | @Value(name = "seq") 20 | public long seqNum; 21 | 22 | } -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/diagnostics/MeasurementProvider.java: -------------------------------------------------------------------------------- 1 | package org.nodel.diagnostics; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Returns a measurement that is used within the diagnostics package. 11 | */ 12 | public interface MeasurementProvider { 13 | 14 | public long getMeasurement(); 15 | 16 | } // (method) 17 | -------------------------------------------------------------------------------- /nodel-webui-js/src/toolkit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 | 8 | 9 | 10 | Toolkit 11 | 12 | 13 | 14 | 15 |
-------------------------------------------------------------------------------- /nodel-jyhost/src/main/java/org/nodel/http/StaticNodelHttpClientProvider.java: -------------------------------------------------------------------------------- 1 | package org.nodel.http; 2 | 3 | import org.nodel.http.impl.ApacheNodelHttpClient; 4 | import org.nodel.net.NodelHTTPClient; 5 | import org.nodel.net.NodelHttpClientProvider; 6 | 7 | /** 8 | * Provides HTTP clients based on the Apache HTTP client 9 | */ 10 | public class StaticNodelHttpClientProvider extends NodelHttpClientProvider { 11 | 12 | @Override 13 | public NodelHTTPClient create() { 14 | return new ApacheNodelHttpClient(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/core/ActionRequestHandler.java: -------------------------------------------------------------------------------- 1 | package org.nodel.core; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Handler to deal with action requests as they arrive via the Nodel layer. 11 | */ 12 | public interface ActionRequestHandler { 13 | 14 | public void handleActionRequest(Object arg); 15 | 16 | } // (class) 17 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/core/NodelEventHandler.java: -------------------------------------------------------------------------------- 1 | package org.nodel.core; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import org.nodel.SimpleName; 10 | 11 | /** 12 | * Callback for Nodel events. 13 | */ 14 | public interface NodelEventHandler { 15 | 16 | public void handleEvent(SimpleName node, SimpleName event, Object arg); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/core/BindingState.java: -------------------------------------------------------------------------------- 1 | package org.nodel.core; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * All possible binding states for dynamic actions and events. 11 | */ 12 | public enum BindingState { 13 | Empty, 14 | ResolutionFailure, 15 | Resolved, 16 | Wired, 17 | MissingActionPoint, 18 | MissingEventPoint 19 | } 20 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/EnumDesc.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target({ElementType.FIELD}) 16 | public @interface EnumDesc { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/EnumTitle.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target({ElementType.FIELD}) 16 | public @interface EnumTitle { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /nodel-jyhost/src/main/java/org/nodel/websockets/WebSocketMessage.java: -------------------------------------------------------------------------------- 1 | package org.nodel.websockets; 2 | 3 | import java.util.List; 4 | 5 | import org.nodel.host.LogEntry; 6 | import org.nodel.reflection.Value; 7 | 8 | public class WebSocketMessage { 9 | 10 | @Value(name = "node") 11 | public String node; 12 | 13 | @Value(name = "error") 14 | public String error; 15 | 16 | @Value(name = "activity", title = "Activity", desc = "Live activity") 17 | public LogEntry activity; 18 | 19 | @Value(name = "activityHistory", title = "Activity history") 20 | public List activityHistory; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/io/UnexpectedIOException.java: -------------------------------------------------------------------------------- 1 | package org.nodel.io; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * Runtime version of IO exception. 7 | */ 8 | public class UnexpectedIOException extends RuntimeException { 9 | 10 | private static final long serialVersionUID = -685861555660909086L; 11 | 12 | public UnexpectedIOException(String message) { 13 | super(message); 14 | } 15 | 16 | public UnexpectedIOException(IOException cause) { 17 | super(cause); 18 | } 19 | 20 | public UnexpectedIOException(String message, IOException cause) { 21 | super(message, cause); 22 | } 23 | 24 | } // (class) -------------------------------------------------------------------------------- /nodel-webui-js/src/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/rest/InvalidCallException.java: -------------------------------------------------------------------------------- 1 | package org.nodel.rest; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | @SuppressWarnings("serial") 10 | public class InvalidCallException extends RuntimeException { 11 | 12 | public InvalidCallException(String message) { 13 | super(message); 14 | } // (constructor) 15 | 16 | public InvalidCallException(String message, Throwable reason) { 17 | super(message, reason); 18 | } // (constructor) 19 | 20 | } // (class) 21 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/rest/CallException.java: -------------------------------------------------------------------------------- 1 | package org.nodel.rest; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | @SuppressWarnings("serial") 10 | public class CallException extends RuntimeException { 11 | 12 | public CallException() { } 13 | 14 | public CallException(int code, String message) { 15 | super(message); 16 | this.code = code; 17 | } 18 | 19 | int code; 20 | 21 | public int getCode() { 22 | return this.code; 23 | } 24 | 25 | } // (class) 26 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/io/UTF8Charset.java: -------------------------------------------------------------------------------- 1 | package org.nodel.io; 2 | 3 | import java.nio.charset.Charset; 4 | 5 | /** 6 | * A fast lookup class for the UTF8 character set. 7 | */ 8 | public class UTF8Charset { 9 | 10 | private Charset _charset = Charset.forName("UTF8"); 11 | 12 | private UTF8Charset() { 13 | _charset = Charset.forName("UTF8"); 14 | } 15 | 16 | private static class LazyHolder { 17 | private static final UTF8Charset INSTANCE = new UTF8Charset(); 18 | } 19 | 20 | public static Charset instance() { 21 | return LazyHolder.INSTANCE.charset(); 22 | } 23 | 24 | private Charset charset() { 25 | return _charset; 26 | } 27 | 28 | } // (class) 29 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/ReflectionException.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | public class ReflectionException extends RuntimeException { 10 | 11 | /** 12 | * (auto generated) 13 | */ 14 | private static final long serialVersionUID = 3387747167574834289L; 15 | 16 | public ReflectionException(String message) { 17 | super(message); 18 | } 19 | 20 | public ReflectionException(String message, Throwable cause) { 21 | super(message, cause); 22 | } 23 | 24 | } // (class) 25 | -------------------------------------------------------------------------------- /nodelbrowse-chromeext/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 14 | 15 | 18 | 21 |
  • Nodel browser
  • 22 |
    23 |
    24 | 25 |
    26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /nodel-webui-js/src/light/gen/variable_gen.py: -------------------------------------------------------------------------------- 1 | import re 2 | pattern = r"^((.*):.*)" 3 | prog = re.compile(pattern) 4 | 5 | def find(orig, substr, infile, outfile): 6 | with open(infile) as a, open(outfile, 'ab+') as b: 7 | for line in a: 8 | r = prog.match(line) 9 | if r and r.group(2) == substr: 10 | b.write(line) 11 | return True 12 | with open(outfile, 'a+') as b: 13 | print 'not found: ' + substr 14 | b.write(orig + '\n') 15 | 16 | with open('variables.src.less') as x: 17 | with open('variables.less', 'wb+') as b: 18 | pass 19 | for line in x: 20 | r = prog.match(line) 21 | if(r): 22 | find(r.group(0), r.group(2), 'variables.orig.less', 'variables.less') 23 | else: 24 | with open('variables.less', 'ab+') as b: 25 | b.write(line) -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/Setter.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | /** 15 | * An annotation used to represent JSON fields 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target({ElementType.METHOD}) 19 | public @interface Setter { 20 | 21 | /** 22 | * The strict name/id/alias to use for the value. 23 | */ 24 | public String name(); 25 | 26 | } // (class) 27 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/json/JSONString.java: -------------------------------------------------------------------------------- 1 | package org.nodel.json; 2 | 3 | /** 4 | * The JSONString interface allows a toJSONString() 5 | * method so that a class can change the behavior of 6 | * JSONObject.toString(), JSONArray.toString(), 7 | * and JSONWriter.value(Object). The 8 | * toJSONString method will be used instead of the default behavior 9 | * of using the Object's toString() method and quoting the result. 10 | */ 11 | public interface JSONString { 12 | /** 13 | * The toJSONString method allows a class to produce its own JSON 14 | * serialization. 15 | * 16 | * @return A strictly syntactically correct JSON text. 17 | */ 18 | public String toJSONString(); 19 | } 20 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/json/JSONException.java: -------------------------------------------------------------------------------- 1 | package org.nodel.json; 2 | 3 | /** 4 | * The JSONException is thrown by the JSON.org classes when things are amiss. 5 | * @author JSON.org 6 | * @version 2010-12-24 7 | */ 8 | public class JSONException extends Exception { 9 | private static final long serialVersionUID = 0; 10 | private Throwable cause; 11 | 12 | /** 13 | * Constructs a JSONException with an explanatory message. 14 | * @param message Detail about the reason for the exception. 15 | */ 16 | public JSONException(String message) { 17 | super(message); 18 | } 19 | 20 | public JSONException(Throwable cause) { 21 | super(cause.getMessage()); 22 | this.cause = cause; 23 | } 24 | 25 | public Throwable getCause() { 26 | return this.cause; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /nodel-webui-js/src/diagnostics.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
    5 | 6 |
    7 | 8 | 9 | 10 | Diagnostics 11 | 12 | 13 | 14 | 15 | 16 | Log 17 | 18 | 19 | 20 | 21 | 22 | Charts 23 | 24 | 25 | 26 | 27 |
    -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/diagnostics/LongSharableMeasurementProvider.java: -------------------------------------------------------------------------------- 1 | package org.nodel.diagnostics; 2 | 3 | import java.util.concurrent.atomic.AtomicLong; 4 | 5 | public class LongSharableMeasurementProvider implements SharableMeasurementProvider { 6 | 7 | private AtomicLong _base = new AtomicLong(); 8 | 9 | @Override 10 | public long getMeasurement() { 11 | return _base.get(); 12 | } 13 | 14 | @Override 15 | public void set(long value) { 16 | _base.set(value); 17 | } 18 | 19 | @Override 20 | public void add(long delta) { 21 | _base.addAndGet(delta); 22 | } 23 | 24 | @Override 25 | public void incr() { 26 | _base.incrementAndGet(); 27 | } 28 | 29 | @Override 30 | public void decr() { 31 | _base.decrementAndGet(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /nodel-framework/src/main/resources/META-INF/nanohttpd/default-mimetypes.properties: -------------------------------------------------------------------------------- 1 | #default mime types for nanohttpd, use META-INF/mimetypes.properties for user defined mimetypes 2 | css=text/css 3 | htm=text/html 4 | html=text/html 5 | xml=text/xml 6 | java=text/x-java-source, text/java 7 | md=text/plain 8 | txt=text/plain 9 | asc=text/plain 10 | gif=image/gif 11 | jpg=image/jpeg 12 | jpeg=image/jpeg 13 | png=image/png 14 | svg=image/svg+xml 15 | mp3=audio/mpeg 16 | m3u=audio/mpeg-url 17 | mp4=video/mp4 18 | ogv=video/ogg 19 | flv=video/x-flv 20 | mov=video/quicktime 21 | swf=application/x-shockwave-flash 22 | js=application/javascript 23 | pdf=application/pdf 24 | doc=application/msword 25 | ogg=application/x-ogg 26 | zip=application/octet-stream 27 | exe=application/octet-stream 28 | class=application/octet-stream 29 | m3u8=application/vnd.apple.mpegurl 30 | ts=video/mp2t -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/EnumInfo.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | public class EnumInfo { 10 | 11 | /** 12 | * Holds the actual enum constant. 13 | */ 14 | public Object constant; 15 | 16 | /** 17 | * A title (defaults to value (as string) if unavailable) 18 | */ 19 | public String title; 20 | 21 | /** 22 | * A description (will be null if none available) 23 | */ 24 | public String desc; 25 | 26 | public EnumInfo(Object constant) { 27 | this.constant = constant; 28 | this.title = constant.toString(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/diagnostics/AtomicLongMeasurementProvider.java: -------------------------------------------------------------------------------- 1 | package org.nodel.diagnostics; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.util.concurrent.atomic.AtomicLong; 10 | 11 | /** 12 | * Binds to an atomic counter for measurement providing purposes. 13 | */ 14 | public class AtomicLongMeasurementProvider implements MeasurementProvider { 15 | 16 | protected AtomicLong atomicLong; 17 | 18 | public AtomicLongMeasurementProvider(AtomicLong atomicLong) { 19 | this.atomicLong = atomicLong; 20 | } 21 | 22 | @Override 23 | public long getMeasurement() { 24 | return this.atomicLong.get(); 25 | } 26 | 27 | } // (class) 28 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/rest/EndpointNotFoundException.java: -------------------------------------------------------------------------------- 1 | package org.nodel.rest; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | public class EndpointNotFoundException extends RuntimeException { 10 | 11 | /** 12 | * (generated) 13 | */ 14 | private static final long serialVersionUID = -1516647525053272225L; 15 | 16 | private String endpoint; 17 | 18 | public EndpointNotFoundException(String endpoint) { 19 | super("'" + endpoint + "' not found."); 20 | 21 | this.endpoint = endpoint; 22 | } // (class) 23 | 24 | public String getEndpoint() { 25 | return this.endpoint; 26 | } 27 | 28 | } // (class) 29 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/SerialisationException.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Represents any exception related to a serialisation failure. 11 | */ 12 | public class SerialisationException extends RuntimeException { 13 | 14 | private static final long serialVersionUID = 0L; 15 | 16 | public SerialisationException(String message) { 17 | super(message); 18 | } 19 | 20 | public SerialisationException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public SerialisationException(String message, Throwable cause) { 25 | super(message, cause); 26 | } 27 | 28 | } // (class) 29 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/StartupException.java: -------------------------------------------------------------------------------- 1 | package org.nodel; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Represents a runtime exception when part of a startup procedure 11 | * fails. 12 | */ 13 | public class StartupException extends RuntimeException { 14 | 15 | private static final long serialVersionUID = 9164072670146296673L; 16 | 17 | public StartupException() { 18 | } 19 | 20 | public StartupException(String message) { 21 | super(message); 22 | } 23 | 24 | public StartupException(Throwable cause) { 25 | super(cause); 26 | } 27 | 28 | public StartupException(String message, Throwable cause) { 29 | super(message, cause); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/core/NodelException.java: -------------------------------------------------------------------------------- 1 | package org.nodel.core; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Nodel specific exceptions. 11 | */ 12 | public class NodelException extends RuntimeException { 13 | 14 | private static final long serialVersionUID = 4493818877974306542L; 15 | 16 | public NodelException() { 17 | super(); 18 | } 19 | 20 | public NodelException(String message) { 21 | super(message); 22 | } 23 | 24 | public NodelException(Throwable cause) { 25 | super(cause); 26 | } 27 | 28 | public NodelException(String message, Throwable cause) { 29 | super(message, cause); 30 | } 31 | 32 | } // (class) 33 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/diagnostics/AtomicIntegerMeasurementProvider.java: -------------------------------------------------------------------------------- 1 | package org.nodel.diagnostics; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.util.concurrent.atomic.AtomicInteger; 10 | 11 | /** 12 | * Binds to an atomic counter for measurement providing purposes. 13 | */ 14 | public class AtomicIntegerMeasurementProvider implements MeasurementProvider { 15 | 16 | private AtomicInteger atomicInteger; 17 | 18 | public AtomicIntegerMeasurementProvider(AtomicInteger atomicInteger) { 19 | this.atomicInteger = atomicInteger; 20 | } // (init) 21 | 22 | @Override 23 | public long getMeasurement() { 24 | return this.atomicInteger.get(); 25 | } 26 | 27 | } // (class) 28 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/UnexpectedInterruptedException.java: -------------------------------------------------------------------------------- 1 | package org.nodel; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Runtime version of Interrupted exception. 11 | */ 12 | public class UnexpectedInterruptedException extends RuntimeException { 13 | 14 | private static final long serialVersionUID = 8255453972778347818L; 15 | 16 | public UnexpectedInterruptedException(String message) { 17 | super(message); 18 | } 19 | 20 | public UnexpectedInterruptedException(InterruptedException cause) { 21 | super(cause); 22 | } 23 | 24 | public UnexpectedInterruptedException(String message, InterruptedException cause) { 25 | super(message, cause); 26 | } 27 | 28 | } // (class) -------------------------------------------------------------------------------- /nodel-webui-js/src/polyfill.js: -------------------------------------------------------------------------------- 1 | // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js 2 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart 3 | if (!String.prototype.padStart) { 4 | String.prototype.padStart = function padStart(targetLength, padString) { 5 | targetLength = targetLength >> 0; //truncate if number, or convert non-number to 0; 6 | padString = String(typeof padString !== 'undefined' ? padString : ' '); 7 | if (this.length >= targetLength) { 8 | return String(this); 9 | } else { 10 | targetLength = targetLength - this.length; 11 | if (targetLength > padString.length) { 12 | padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed 13 | } 14 | return padString.slice(0, targetLength) + String(this); 15 | } 16 | }; 17 | } -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/host/OperationPendingException.java: -------------------------------------------------------------------------------- 1 | package org.nodel.host; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Used when a operation is in progress. 11 | */ 12 | public class OperationPendingException extends Exception { 13 | 14 | /** 15 | * (auto-generated) 16 | */ 17 | private static final long serialVersionUID = 4776299254834378717L; 18 | 19 | public OperationPendingException() { 20 | super("There is still an operation in progress; try again later."); 21 | } 22 | 23 | public OperationPendingException(String message) { 24 | super(message); 25 | } 26 | 27 | public OperationPendingException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | } // (class) 32 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/logging/Level.java: -------------------------------------------------------------------------------- 1 | package org.nodel.logging; 2 | 3 | import org.nodel.reflection.EnumTitle; 4 | import org.slf4j.spi.LocationAwareLogger; 5 | 6 | public enum Level { 7 | 8 | TRACE("trace", LocationAwareLogger.TRACE_INT), 9 | DEBUG("debug", LocationAwareLogger.DEBUG_INT), 10 | INFO("info", LocationAwareLogger.INFO_INT), 11 | WARN("warn", LocationAwareLogger.WARN_INT), 12 | ERROR("error", LocationAwareLogger.ERROR_INT); 13 | 14 | private int intLevel; 15 | 16 | @EnumTitle 17 | public String name; 18 | 19 | Level(String name, int intLevel) { 20 | this.name = name; 21 | this.intLevel = intLevel; 22 | } 23 | 24 | public String getName() { 25 | return this.name; 26 | } 27 | 28 | public int intLevel() { 29 | return this.intLevel; 30 | } 31 | 32 | public boolean isMoreSpecificThan(Level other) { 33 | return this.intLevel > other.intLevel; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /nodel-jyhost/src/main/java/org/nodel/websockets/SessionEntry.java: -------------------------------------------------------------------------------- 1 | package org.nodel.websockets; 2 | 3 | import org.nanohttpd.protocols.websockets.WebSocket; 4 | import org.nodel.Handler; 5 | import org.nodel.host.BaseNode; 6 | import org.nodel.host.LogEntry; 7 | import org.nodel.threading.TimerTask; 8 | 9 | import java.util.LinkedList; 10 | import java.util.Queue; 11 | 12 | public class SessionEntry { 13 | public boolean busy = false; 14 | 15 | public WebSocket webSocket; 16 | 17 | public BaseNode node; 18 | 19 | public Handler.H1 activityHandler; 20 | 21 | public Queue sendQueue = new LinkedList(); 22 | 23 | public TimerTask pingTimer; 24 | 25 | /** 26 | * Last time this session received data. 27 | * (System.nanoTime base) 28 | */ 29 | public long lastReceive = System.nanoTime(); 30 | 31 | public SessionEntry(WebSocket webSocket, BaseNode node) { 32 | this.webSocket = webSocket; 33 | this.node = node; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/threading/TimerTask.java: -------------------------------------------------------------------------------- 1 | package org.nodel.threading; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * The specialised timer task class for use with the Timers class in this package. 11 | */ 12 | public abstract class TimerTask implements Runnable { 13 | 14 | private boolean _cancelled; 15 | 16 | /** 17 | * The native Java timer-task. 18 | */ 19 | java.util.TimerTask nativeTimerTask; 20 | 21 | /** 22 | * The timer callback. 23 | */ 24 | public abstract void run(); 25 | 26 | /** 27 | * Cancels this timer. 28 | */ 29 | public void cancel() { 30 | _cancelled = true; 31 | this.nativeTimerTask.cancel(); 32 | } 33 | 34 | public boolean isCancelled() { 35 | return _cancelled; 36 | } 37 | 38 | } // (method) 39 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/MultiClassValue.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target({ElementType.TYPE}) 16 | public @interface MultiClassValue { 17 | 18 | /** 19 | * Stores the list of allowed item names when 'allowedInstances' is used. 20 | * (Valid for class annotations only) 21 | */ 22 | public String[] allowedItemTitles() default {}; 23 | 24 | /** 25 | * Stores the list of allowed instances. 26 | * (Valid for class annotations only) 27 | */ 28 | public Class[] allowedItemClasses() default {}; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/toolkit/Console.java: -------------------------------------------------------------------------------- 1 | package org.nodel.toolkit; 2 | 3 | public class Console { 4 | 5 | public interface Interface { 6 | 7 | public void info(Object obj); 8 | 9 | public void log(Object obj); 10 | 11 | public void error(Object obj); 12 | 13 | public void warn(Object obj); 14 | } 15 | 16 | /** 17 | * Null console, never throws exceptions. 18 | */ 19 | private static class Null implements Interface { 20 | 21 | @Override 22 | public void info(Object obj) { 23 | } 24 | 25 | @Override 26 | public void log(Object obj) { 27 | } 28 | 29 | @Override 30 | public void error(Object obj) { 31 | } 32 | 33 | @Override 34 | public void warn(Object obj) { 35 | } 36 | 37 | } 38 | 39 | private static class LazyHolder { 40 | private static final Interface INSTANCE = new Null(); 41 | } 42 | 43 | public static Interface NullConsole() { 44 | return LazyHolder.INSTANCE; 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/host/ParamValues.java: -------------------------------------------------------------------------------- 1 | package org.nodel.host; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.util.LinkedHashMap; 10 | 11 | import org.nodel.SimpleName; 12 | import org.nodel.reflection.Serialisation; 13 | 14 | /** 15 | * Stores the values of the parameters. 16 | */ 17 | public class ParamValues extends LinkedHashMap { 18 | 19 | /** 20 | * (auto-generated) 21 | */ 22 | private static final long serialVersionUID = -6657841283220392716L; 23 | 24 | /** 25 | * Empty version. 26 | */ 27 | public static final ParamValues Empty = new ParamValues(); 28 | 29 | public static final ParamValues Example = new ParamValues(); 30 | 31 | static { 32 | Example.put(new SimpleName("ipAddress"), "192.168.100.22"); 33 | } 34 | 35 | public String toString() { 36 | return Serialisation.serialise(this); 37 | } 38 | 39 | } // (class) 40 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/net/Credentials.java: -------------------------------------------------------------------------------- 1 | package org.nodel.net; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Represents network credentials 11 | */ 12 | public class Credentials { 13 | 14 | private String username; 15 | 16 | private String password; 17 | 18 | /** 19 | * Empty constructor. 20 | */ 21 | public Credentials() { 22 | } 23 | 24 | /** 25 | * Full constructor. 26 | */ 27 | public Credentials(String username, String password) { 28 | this.username = username; 29 | this.password = password; 30 | } 31 | 32 | public String getUsername() { 33 | return this.username; 34 | } 35 | 36 | public void setUsername(String value) { 37 | this.username = value; 38 | } 39 | 40 | public String getPassword() { 41 | return this.password; 42 | } 43 | 44 | public void setPassword(String value) { 45 | this.password = value; 46 | } 47 | 48 | } // (class) 49 | -------------------------------------------------------------------------------- /nodel-webui-js/src/generator.py: -------------------------------------------------------------------------------- 1 | from xml.etree.ElementTree import Element, SubElement, tostring 2 | from xml.dom.minidom import parseString 3 | import json 4 | import urllib2 5 | url = "http://192.168.178.49:8087/REST/nodes/lumicomofficedashboard/events/controls" 6 | result = json.load(urllib2.urlopen(url)) 7 | 8 | root = Element('pages',{'title':'Status Page'}) 9 | for location in result['arg']: 10 | loc = SubElement(root, "page", {'title':location['title']}) 11 | row = SubElement(loc, "row") 12 | for group in location['groups']: 13 | col = SubElement(row, "column", {"sm":"6","md":"4"}) 14 | ttlt = SubElement(col, "title") 15 | ttlt.text = group['title'] 16 | for control in group['controls']: 17 | stac = SubElement(col, "status", {"event":control['control']}) 18 | stac.text = control['title'] 19 | 20 | rough_string = tostring(root, 'utf-8') 21 | reparsed = parseString(rough_string) 22 | pi = reparsed.createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="index.xsl"') 23 | reparsed.insertBefore(pi, reparsed.firstChild) 24 | 25 | target = open('status.xml', 'w') 26 | target.truncate() 27 | target.write(reparsed.toprettyxml(indent=" ", encoding="utf-8")) 28 | target.close() -------------------------------------------------------------------------------- /nodel-webui-js/src/status.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Infrastructure 8 | Network 9 | 10 | 11 | Areas 12 | Upstairs 13 | Downstairs 14 | 15 | 16 | 17 | 18 | 19 | 20 | Equipment 21 | Display 22 | Amp 23 | Projector 24 | 25 | 26 | 27 | 28 | 29 | 30 | Equipment 31 | Amp 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /nodel-jyhost/.settings 2 | /nodel-framework/.settings 3 | /export 4 | /nodel-jyhost/build 5 | /nodel-framework/build 6 | /nodel-webui-js/build 7 | /.gradle 8 | /nodel-framework/bin 9 | /nodel-jyhost/bin 10 | /nodel-jyhost/content 11 | /nodel-jyhost/logs 12 | /nodel-jyhost/nodes 13 | /nodel-framework/.classpath 14 | /nodel-jyhost/.classpath 15 | /nodel-jyhost/.project 16 | /nodel-jyhost/.version 17 | /nodel-jyhost/_bootstrap_example.json 18 | /nodel-jyhost/_bootstrap_schema.json 19 | /nodel-framework/.project 20 | /nodel-jyhost/bootstrap.json 21 | /nodel-framework/src/main/resources/org/nodel/host/content.zip 22 | /nodel-framework/src/main/resources/org/nodel/build.json 23 | .lastHTTPPort 24 | _instance.lock 25 | _lastError.txt 26 | /nodel-webui-js/.classpath 27 | /nodel-webui-js/.project 28 | /nodel-webui-js/.settings 29 | /nodel-webui-js/bin 30 | /nodel-jyhost/.nodel 31 | /nodel-jyhost/recipes 32 | nodel-webui-js/node_modules/ 33 | /nodel-webui-js/temp 34 | nodel-webui-js/src/dark/theme.less 35 | nodel-webui-js/src/light/theme.less 36 | nodel-webui-js/.ftppass 37 | nodel-webui-js/sftpCache.json 38 | 39 | # IntelliJ IDEA 40 | .idea/ 41 | *.iml 42 | out/ 43 | 44 | # Visual Studio Code 45 | .vscode/ 46 | *.code-workspace 47 | -------------------------------------------------------------------------------- /nodel-jyhost/src/main/java/org/nodel/snmp/NodelSnmp.java: -------------------------------------------------------------------------------- 1 | package org.nodel.snmp; 2 | 3 | import java.io.IOException; 4 | 5 | import org.nodel.io.UnexpectedIOException; 6 | import org.snmp4j.Snmp; 7 | 8 | /** 9 | * Convenience class for nodes to share and save resources. 10 | */ 11 | public class NodelSnmp { 12 | 13 | /** 14 | * (exception-less convenience) 15 | */ 16 | private static NodelUdpTransportMapping tryCreate() { 17 | try { 18 | NodelUdpTransportMapping result = new NodelUdpTransportMapping(); 19 | result.listen(); 20 | 21 | return result; 22 | 23 | } catch (IOException exc) { 24 | throw new UnexpectedIOException("Failed to create UDP transport for SNMP", exc); 25 | } 26 | } 27 | 28 | /** 29 | * (singleton, thread-safe, non-blocking) 30 | */ 31 | private static class Instances { 32 | 33 | private static final Snmp INSTANCE = new Snmp(tryCreate()); 34 | 35 | } 36 | 37 | /** 38 | * Returns a shared SNMP instance with UDP transport. 39 | */ 40 | public static Snmp shared() { 41 | return Instances.INSTANCE; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/diagnostics/SharableMeasurementProvider.java: -------------------------------------------------------------------------------- 1 | package org.nodel.diagnostics; 2 | 3 | /** 4 | * Measurement provider that can be altered by a 3rd-party. 5 | */ 6 | public interface SharableMeasurementProvider extends MeasurementProvider { 7 | 8 | public void set(long value); 9 | 10 | public void add(long value); 11 | 12 | public void incr(); 13 | 14 | public void decr(); 15 | 16 | /** 17 | * For convenience. 18 | */ 19 | public class Null implements SharableMeasurementProvider { 20 | 21 | /** 22 | * A sharable instance of a 'null' provider. 23 | */ 24 | public final static SharableMeasurementProvider INSTANCE = new Null(); 25 | 26 | @Override 27 | public long getMeasurement() { 28 | return 0; 29 | } 30 | 31 | @Override 32 | public void set(long value) { 33 | } 34 | 35 | @Override 36 | public void add(long value) { 37 | } 38 | 39 | @Override 40 | public void incr() { 41 | } 42 | 43 | @Override 44 | public void decr() { 45 | } 46 | 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /nodelbrowse-chromeext/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | background: rgba(102, 102, 119, 0.85); 5 | background: white; 6 | width: 100%; 7 | -webkit-app-region: drag; 8 | } 9 | 10 | div#main { 11 | position: absolute; 12 | top: 44px; 13 | bottom: 0; 14 | width: 100%; 15 | overflow-y: scroll; 16 | color: white; 17 | color: black; 18 | -webkit-app-region: no-drag; 19 | } 20 | 21 | ul#results { 22 | list-style: none; 23 | font-family: Arial, Helvetica, Sans-Serif; 24 | font-size: 12px; 25 | line-height: 21px; 26 | padding: 0em 0.5em; 27 | padding-right: 2em; 28 | margin: 0; 29 | } 30 | 31 | ul.working#results { 32 | background: url(img/working.gif) no-repeat center; 33 | min-height: 80px; 34 | } 35 | 36 | ul strong.warning { 37 | color: #D14836; 38 | text-align: center; 39 | display: block; 40 | padding: 0.5em; 41 | } 42 | 43 | ul#results > ul { 44 | list-style: square; 45 | } 46 | 47 | ul#results > li { 48 | font-weight: bold; 49 | margin-left: 1em; 50 | margin-top: 0.5em; 51 | } 52 | 53 | ul.loading { 54 | background: red; 55 | } 56 | 57 | ul#results li em { 58 | font-style: normal; 59 | font-weight: normal; 60 | opacity: 0.33; 61 | } 62 | 63 | ul#results li em::before { 64 | content: "\2014 \a0"; 65 | padding: 0 4px; 66 | } 67 | -------------------------------------------------------------------------------- /nodel-framework/src/test/java/org/nodel/SimpleNameTest.java: -------------------------------------------------------------------------------- 1 | package org.nodel; 2 | 3 | import org.junit.jupiter.api.TestInstance; 4 | import org.junit.jupiter.params.ParameterizedTest; 5 | import org.junit.jupiter.params.provider.CsvSource; 6 | import org.junit.jupiter.params.provider.ValueSource; 7 | import static org.junit.jupiter.api.Assertions.*; 8 | 9 | @TestInstance(TestInstance.Lifecycle.PER_CLASS) 10 | class SimpleNameTest { 11 | 12 | @ParameterizedTest 13 | @ValueSource(strings = { 14 | "node_name", 15 | "Node Name", 16 | "node-name", 17 | "node.name", 18 | "node name" 19 | }) 20 | void testGetOriginalName(String originalName) { 21 | SimpleName name = new SimpleName(originalName); 22 | assertEquals(originalName, name.getOriginalName()); 23 | } 24 | 25 | @ParameterizedTest 26 | @CsvSource({ 27 | "node_name, nodename", 28 | "Node Name, NodeName", 29 | "node-name, nodename", 30 | "node.name, nodename", 31 | "node name, nodename" 32 | }) 33 | public void testGetReducedName(String originalName, String expectedReducedName) { 34 | SimpleName name = new SimpleName(originalName); 35 | assertEquals(expectedReducedName, name.getReducedName()); 36 | } 37 | } -------------------------------------------------------------------------------- /toolkit-util/ProcessSandbox/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Process Sandbox")] 9 | 10 | 11 | // Setting ComVisible to false makes the types in this assembly not visible 12 | // to COM components. If you need to access a type in this assembly from 13 | // COM, set the ComVisible attribute to true on that type. 14 | [assembly: ComVisible(false)] 15 | 16 | // The following GUID is for the ID of the typelib if this project is exposed to COM 17 | [assembly: Guid("a2fe9439-1523-48ad-8316-a091e1f95559")] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.2.3")] 30 | [assembly: AssemblyFileVersion("1.0.2.3")] 31 | [assembly: AssemblyDescription("(see nodel.io or github.com/museumvictoria/nodel)")] 32 | 33 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/host/ConsoleLogEntry.java: -------------------------------------------------------------------------------- 1 | package org.nodel.host; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import org.joda.time.DateTime; 10 | import org.nodel.reflection.Value; 11 | 12 | /** 13 | * Console logs. 14 | */ 15 | public class ConsoleLogEntry { 16 | 17 | /** 18 | * Console types: standard out, or standard error. 19 | */ 20 | public enum Console { 21 | out, err, warn, info 22 | } 23 | 24 | @Value(name = "seq", title = "Sequence", desc = "A sequence number.") 25 | public long seq; 26 | 27 | @Value(name = "timestamp", title = "Timestamp", desc = "A universal timestamp.") 28 | public DateTime timestamp; 29 | 30 | @Value(name = "console", title = "Console", desc = "The console type.") 31 | public Console console; 32 | 33 | @Value(name = "comment", title = "Comment", desc = "Short commentary.") 34 | public String comment; 35 | 36 | public ConsoleLogEntry(long seq, DateTime timestamp, Console console, String comment) { 37 | this.seq = seq; 38 | this.timestamp = timestamp; 39 | this.console = console; 40 | this.comment = comment; 41 | } 42 | 43 | } // (class) -------------------------------------------------------------------------------- /nodel-webui-js/src/schemas.json: -------------------------------------------------------------------------------- 1 | { 2 | "pills": { 3 | "type": "string" 4 | }, 5 | 6 | "select": { 7 | "type": "string" 8 | }, 9 | 10 | "title": { 11 | "type": "string" 12 | }, 13 | 14 | "text": { 15 | "type": "string" 16 | }, 17 | 18 | "panel": { 19 | "type": "string", 20 | "format": "long" 21 | }, 22 | 23 | "switch": { 24 | "type": "boolean" 25 | }, 26 | 27 | "partialswitch": { 28 | "type": "string", 29 | "enum": ["Off", "PartiallyOff", "PartiallyOn", "On"] 30 | }, 31 | 32 | "partialbadge": { 33 | "type": "string", 34 | "enum": ["Off", "PartiallyOff", "PartiallyOn", "On"] 35 | }, 36 | 37 | "status_signal": { 38 | "type": "object", 39 | "properties": { 40 | "level": {"type": "integer", "title": "Level", "order": 1}, 41 | "message": {"type": "string", "title": "Message", "order": 2} 42 | } 43 | }, 44 | 45 | "meter": { 46 | "type": "number" 47 | }, 48 | 49 | "range": { 50 | "type": "number" 51 | }, 52 | 53 | "field": { 54 | "type": "string" 55 | }, 56 | 57 | "image": { 58 | "type": "string" 59 | }, 60 | 61 | "badge": { 62 | "type": "object", 63 | "properties": { 64 | "level": {"type": "integer", "title": "Level", "order": 1}, 65 | "message": {"type": "string", "title": "Message", "order": 2} 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /nodel-webui-js/src/nodel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
    5 | 6 | 7 | 8 |
    9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Console 18 | 19 | 20 | 21 | 22 | 23 | Recipe 24 | 25 | 26 | 27 | 28 | 29 | Actions & Signals 30 | 31 | 32 | 33 | Log 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Parameters 42 | 43 | 44 | 45 | Bindings 46 | 47 | 48 | 49 | 50 |
    -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/ServiceInfo.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.lang.reflect.Member; 10 | import java.util.Map; 11 | 12 | import org.nodel.Strings; 13 | 14 | /** 15 | * Holds quick lookup info when Service attributes are specified. 16 | */ 17 | public class ServiceInfo implements Comparable { 18 | 19 | public ServiceInfo(String name, Service annotation) { 20 | this.name = name; 21 | this.annotation = annotation; 22 | } 23 | 24 | /** 25 | * A short name. 26 | */ 27 | public String name; 28 | 29 | /** 30 | * Could be a field or method 31 | */ 32 | public Member member; 33 | 34 | /** 35 | * The annotation (never null) 36 | */ 37 | public Service annotation; 38 | 39 | public Map parameterMap; 40 | 41 | /** 42 | * Compares by 'order' field, then by name 43 | */ 44 | @Override 45 | public int compareTo(ServiceInfo o) { 46 | double x = annotation.order(); 47 | double y = o.annotation.order(); 48 | 49 | return (x < y) ? -1 : ((x == y) ? Strings.compare(this.name, o.name) : 1); 50 | } // (method) 51 | 52 | } // (class) -------------------------------------------------------------------------------- /nodel-webui-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootskel", 3 | "version": "0.0.1", 4 | "description": "Bootstrap skeleton", 5 | "dependencies": { 6 | "@fortawesome/fontawesome-free": "^5.9.0", 7 | "array.findindex": "^1.0.4", 8 | "bootstrap": "^3.4.1", 9 | "bootstrap-select": "1.13.10", 10 | "cm-resize": "^1.0.1", 11 | "codemirror": "^5.58.3", 12 | "davidshimjs-qrcodejs": "^0.0.2", 13 | "fuzzyset.js": "0.0.8", 14 | "google-charts": "^2.0.0", 15 | "gsap": "^2.1.3", 16 | "identicon.js": "^2.3.3", 17 | "jquery": "3.4.1", 18 | "jquery.scrollbar": "^0.2.11", 19 | "jsviews": "^1.0.3", 20 | "moment": "^2.29.4", 21 | "pagedown": "^1.1.0", 22 | "xregexp": "^4.2.4", 23 | "xxhashjs": "^0.2.2" 24 | }, 25 | "devDependencies": { 26 | "grunt": "^1.4.1", 27 | "grunt-concat-css": "^0.3.2", 28 | "grunt-contrib-concat": "^2.0.0", 29 | "grunt-contrib-copy": "^1.0.0", 30 | "grunt-contrib-less": "^3.0.0", 31 | "grunt-contrib-uglify": "^5.0.1", 32 | "grunt-contrib-watch": "^1.1.0", 33 | "grunt-google-fonts": "^0.5.0", 34 | "grunt-text-replace": "^0.4.0", 35 | "grunt-twbs": "0.0.5", 36 | "mkdirp": "^1.0.4", 37 | "tslib": "^2.3.1", 38 | "uglify-js": "^3.14.2", 39 | "uglifycss": "0.0.29", 40 | "grunt-cli": "^1.4.3", 41 | "lodash": "^4.17.21" 42 | }, 43 | "license": "MPL-2.0", 44 | "repository": { 45 | "type": "git", 46 | "url": "https://github.com/museumsvictoria/nodel.git" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /nodel-jyhost/src/main/java/org/nodel/jyhost/PyToolkit.java: -------------------------------------------------------------------------------- 1 | package org.nodel.jyhost; 2 | 3 | import org.python.core.Py; 4 | import org.python.core.PyDictionary; 5 | import org.python.core.PyObject; 6 | 7 | /** 8 | * This class is reserved for any (Jy)Python-Java interfacing. 9 | */ 10 | public class PyToolkit { 11 | 12 | private static class FrozenDict extends PyDictionary { 13 | 14 | private static final long serialVersionUID = 1L; 15 | 16 | @Override 17 | public void __setitem__(int key, PyObject value) { 18 | throw Py.TypeError(String.format("object does not support item assignment", getType().fastGetName())); 19 | } 20 | 21 | @Override 22 | public void __setitem__(PyObject key, PyObject value) { 23 | throw Py.TypeError(String.format("object does not support item assignment", getType().fastGetName())); 24 | } 25 | 26 | @Override 27 | public void __setitem__(String key, PyObject value) { 28 | throw Py.TypeError(String.format("object does not support item assignment", getType().fastGetName())); 29 | } 30 | 31 | @Override 32 | public void __delitem__(PyObject key) { 33 | throw Py.TypeError(String.format("object has no items", getType().fastGetName())); 34 | } 35 | } 36 | 37 | /** 38 | * A convenient immutable constant for sharing. 39 | */ 40 | public final static FrozenDict EmptyDict = new FrozenDict(); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/request/Request.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.request; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.net.Socket; 5 | import java.util.Properties; 6 | 7 | /** 8 | * Holds data related to an HTTP request. 9 | */ 10 | public class Request { 11 | 12 | public String uri; 13 | 14 | public String method; 15 | 16 | public Properties parms; 17 | 18 | public Properties header; 19 | 20 | public Properties files; 21 | 22 | public byte[] raw; 23 | 24 | public Socket peer; 25 | 26 | public final String remoteHost; 27 | 28 | public final int remotePort; 29 | 30 | public final String localHost; 31 | 32 | public final int localPort; 33 | 34 | public Request(String uri, String method, Properties parms, Properties header, Properties files, byte[] raw, Socket peer) { 35 | this.uri = uri; 36 | this.method = method; 37 | this.parms = parms; 38 | this.header = header; 39 | this.files = files; 40 | this.raw = raw; 41 | this.peer = peer; 42 | 43 | InetSocketAddress remoteSocketAddr = (InetSocketAddress) peer.getRemoteSocketAddress(); 44 | this.remoteHost = remoteSocketAddr.getHostString(); 45 | this.remotePort = remoteSocketAddr.getPort(); 46 | 47 | InetSocketAddress localSocketAddr = (InetSocketAddress) peer.getLocalSocketAddress(); 48 | this.localHost = localSocketAddr.getHostString(); 49 | this.localPort = localSocketAddr.getPort(); 50 | } 51 | 52 | } // (class) 53 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/ParameterInfo.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | public class ParameterInfo implements Comparable { 10 | 11 | /** 12 | * The name of the parameter. 13 | */ 14 | public String name; 15 | 16 | /** 17 | * Can be null if no annotation was used. 18 | */ 19 | public Param annotation; 20 | 21 | /** 22 | * The index of the parameter. 23 | */ 24 | public int index; 25 | 26 | public Class klass; 27 | 28 | public ParameterInfo(String name, int index, Class klass, Param annotation) { 29 | this.name = name; 30 | this.index = index; 31 | this.klass = klass; 32 | this.annotation = annotation; 33 | } 34 | 35 | public ParameterInfo(String name, int index, Class klass) { 36 | this(name, index, klass, null); 37 | } 38 | 39 | /** 40 | * Compares by index. 41 | */ 42 | @Override 43 | public int compareTo(ParameterInfo o) { 44 | int x = this.index; 45 | int y = o.index; 46 | 47 | return (x < y) ? -1 : ((x == y) ? 0 : 1); 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return String.format("{ name=%s, index=%s, class=%s }", 53 | this.name, this.index, this.klass); 54 | } 55 | 56 | } // (class) 57 | -------------------------------------------------------------------------------- /nodel-jyhost/src/main/java/org/nodel/jyhost/ExampleScript.java: -------------------------------------------------------------------------------- 1 | package org.nodel.jyhost; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | import org.nodel.io.Stream; 7 | import org.nodel.io.UnexpectedIOException; 8 | 9 | /* 10 | * This Source Code Form is subject to the terms of the Mozilla Public 11 | * License, v. 2.0. If a copy of the MPL was not distributed with this 12 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 13 | */ 14 | 15 | public class ExampleScript { 16 | 17 | private String _generated; 18 | 19 | /** 20 | * Loads from the embedded resource. 21 | */ 22 | private void initOnce() { 23 | try { 24 | try (InputStream is = PyNode.class.getResourceAsStream("example_script.py")) { 25 | String data = Stream.readFully(is); 26 | _generated = data.replace("%VERSION%", Launch.VERSION); 27 | } 28 | } catch (IOException exc) { 29 | throw new UnexpectedIOException("While opening 'example_script.py'", exc); 30 | } 31 | } 32 | 33 | /** 34 | * Generate an example script file. 35 | */ 36 | public static String get() { 37 | return Instance.INSTANCE._generated; 38 | } 39 | 40 | /** 41 | * (private constructor) 42 | */ 43 | private ExampleScript() { 44 | initOnce(); 45 | } 46 | 47 | /** 48 | * (singleton, thread-safe, non-blocking) 49 | */ 50 | private static class Instance { 51 | private static final ExampleScript INSTANCE = new ExampleScript(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/host/ParameterBinding.java: -------------------------------------------------------------------------------- 1 | package org.nodel.host; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.util.Map; 10 | 11 | import org.nodel.reflection.Schema; 12 | import org.nodel.reflection.Serialisation; 13 | import org.nodel.reflection.Value; 14 | 15 | /** 16 | * Represents a dynamic node's parameter. 17 | */ 18 | public class ParameterBinding { 19 | 20 | public final static ParameterBinding Example; 21 | 22 | public final static String ExampleName = "ipAddress"; 23 | 24 | static { 25 | Example = new ParameterBinding(); 26 | Example.title = "IP address"; 27 | Example.desc = "The IP address to connect to."; 28 | Example.schema = Schema.getSchemaObject(String.class); 29 | Example.value = "192.168.100.1"; 30 | } 31 | 32 | @Value(name = "desc", order = 2) 33 | public String desc; 34 | 35 | @Value(name = "group", order = 3) 36 | public String group; 37 | 38 | @Value(name = "schema", order = 4) 39 | public Map schema; 40 | 41 | @Value(name = "value", order = 5) 42 | public Object value; 43 | 44 | @Value(name = "title", order = 6) 45 | public String title; 46 | 47 | @Value(name = "order", title = "Order", order = 7, required = false) 48 | public double order; 49 | 50 | public String toString() { 51 | return Serialisation.serialise(this); 52 | } 53 | 54 | } // (class) 55 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/host/NodelEventInfo.java: -------------------------------------------------------------------------------- 1 | package org.nodel.host; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import org.nodel.reflection.Serialisation; 10 | import org.nodel.reflection.Value; 11 | 12 | /** 13 | * Represents a dynamic node's event. 14 | */ 15 | public class NodelEventInfo { 16 | 17 | public final static NodelEventInfo Example; 18 | 19 | static { 20 | Example = new NodelEventInfo(); 21 | Example.node = "ExhibitSensor1"; 22 | Example.event = "Triggered"; 23 | Example.group = "General"; 24 | } 25 | 26 | @Value(name = "node", title = "Node", order = 2) 27 | public String node; 28 | 29 | @Value(name = "event", title = "Event", order = 3) 30 | public String event; 31 | 32 | @Value(name = "group", title = "Group", order = 4, required = false) 33 | public String group; 34 | 35 | @Value(name = "title", title = "Title", order = 5, required = false) 36 | public String title; 37 | 38 | @Value(name = "desc", title = "Description", order = 6, required = false) 39 | public String desc; 40 | 41 | @Value(name = "caution", title = "Caution", order = 7, required = false) 42 | public String caution; 43 | 44 | @Value(name = "order", title = "Order", order = 8, required = false) 45 | public double order; 46 | 47 | public String toString() { 48 | return Serialisation.serialise(this); 49 | } 50 | 51 | } // (class) 52 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/host/NodelActionInfo.java: -------------------------------------------------------------------------------- 1 | package org.nodel.host; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import org.nodel.reflection.Serialisation; 10 | import org.nodel.reflection.Value; 11 | 12 | /** 13 | * Represents a dynamic node's action. 14 | */ 15 | public class NodelActionInfo { 16 | 17 | public final static NodelActionInfo Example; 18 | 19 | static { 20 | Example = new NodelActionInfo(); 21 | Example.node = "MyProjector"; 22 | Example.action = "TurnOn"; 23 | Example.group = "Power"; 24 | } 25 | 26 | @Value(name = "node", title = "Node", order = 2) 27 | public String node; 28 | 29 | @Value(name = "action", title = "Action", order = 3) 30 | public String action; 31 | 32 | @Value(name = "title", title = "Title", order = 4, required = false) 33 | public String title; 34 | 35 | @Value(name = "group", title = "Group", order = 5, required = false) 36 | public String group; 37 | 38 | @Value(name = "desc", title = "Description", order = 6, required = false) 39 | public String desc; 40 | 41 | @Value(name = "caution", title = "Caution", order = 7, required = false) 42 | public String caution; 43 | 44 | @Value(name = "order", title = "Order", order = 8, required = false) 45 | public double order; 46 | 47 | public String toString() { 48 | return Serialisation.serialise(this); 49 | } 50 | 51 | } // (class) 52 | -------------------------------------------------------------------------------- /nodel-webui-js/src/spectrum/spectrum-dark.css: -------------------------------------------------------------------------------- 1 | /*.sp-replacer {*/ 2 | /* background: #000;*/ 3 | /* color: #999999;*/ 4 | /* border: 1px solid #333333;*/ 5 | /* border-radius: 2px;*/ 6 | /* padding: 8px;*/ 7 | /*}*/ 8 | 9 | /*.sp-replacer:hover,*/ 10 | /*.sp-replacer.sp-active {*/ 11 | /* border-color: #ffffff;*/ 12 | /* color: #d0d0d0;*/ 13 | /*}*/ 14 | 15 | /*.sp-replacer.sp-disabled {*/ 16 | /* color: #333333;*/ 17 | /* border: 1px solid #333333;*/ 18 | /*}*/ 19 | 20 | /*.sp-container {*/ 21 | /* background-color: #424242;*/ 22 | /* border: 1px solid #ececec;*/ 23 | /* border-radius: 4px;*/ 24 | /*}*/ 25 | 26 | /*.sp-input {*/ 27 | /* color: #ffffff;*/ 28 | /*}*/ 29 | 30 | /*.sp-picker-container {*/ 31 | /* border-left: none;*/ 32 | /* width: 240px;*/ 33 | /*}*/ 34 | 35 | /*.sp-preview {*/ 36 | /* width: 50px;*/ 37 | /* height: 30px;*/ 38 | /* border: 4px solid #222;*/ 39 | /* margin-right: 0;*/ 40 | /*}*/ 41 | 42 | /*.sp-dd {*/ 43 | /* display: none;*/ 44 | /*}*/ 45 | 46 | /*.sp-color,*/ 47 | /*.sp-hue {*/ 48 | /* border: 4px solid #424242;*/ 49 | /*}*/ 50 | 51 | input.spectrum-color-picker { 52 | font-size: 12px; 53 | } 54 | .sp-container.sp-light { 55 | background-color: white; 56 | } 57 | .sp-container.sp-dark { 58 | background-color: #666666; 59 | } 60 | .sp-colorize-container { 61 | border-radius: 4px; 62 | width: 60px; 63 | } 64 | .sp-colorize { 65 | width: 60px; 66 | height: 60px; 67 | } 68 | .sp-container.sp-dark .sp-input-container { 69 | background-color: white; 70 | } 71 | 72 | /* for mobile */ 73 | @media screen and (max-width: 450px){ 74 | .sp-palette-container { 75 | display: none; 76 | } 77 | } -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/Param.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | /** 15 | * An annotation used to represent JSON fields 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.PARAMETER) 19 | public @interface Param { 20 | 21 | /** 22 | * The strict name/id/alias to use for the value. 23 | * Name is compulsory because Java doesn't not support named parameters 24 | */ 25 | public String name() default ""; 26 | 27 | /** 28 | * A short title for the value. 29 | */ 30 | public String title() default ""; 31 | 32 | /** 33 | * A short description of the parameter. 34 | */ 35 | public String desc() default ""; 36 | 37 | /** 38 | * Holds if generics are being used. 39 | * 'Type A' would apply to Lists and Map keys. 40 | */ 41 | public Class genericClassA() default Object.class; 42 | 43 | /** 44 | * Holds if generics are being used. 45 | * 'Type B' would apply to Map values. 46 | */ 47 | public Class genericClassB() default Object.class; 48 | 49 | /** 50 | * Required field? 51 | */ 52 | public boolean required() default true; 53 | 54 | /** 55 | * 'Complete values' means it encompasses a major parameter. 56 | * @return 57 | */ 58 | public boolean isMajor() default false; 59 | 60 | } // (method) 61 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/host/Bindings.java: -------------------------------------------------------------------------------- 1 | package org.nodel.host; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import org.nodel.reflection.Serialisation; 10 | import org.nodel.reflection.Value; 11 | 12 | /** 13 | * Holds all local / remote action / event binding information for a dynamic node. 14 | */ 15 | public class Bindings { 16 | 17 | /** 18 | * A default or empty version. 19 | */ 20 | public final static Bindings Empty; 21 | 22 | static { 23 | Empty = new Bindings(); 24 | Empty.local = LocalBindings.Empty; 25 | Empty.remote = RemoteBindings.Empty; 26 | Empty.params = ParameterBindings.Empty; 27 | } // (static) 28 | 29 | @Value(name = "desc", title = "Description", order = 0.5, desc = "The description of the node.") 30 | public String desc; 31 | 32 | @Value(name = "local", title = "Local", order = 1, desc = "The actions and events this node provides (local).") 33 | public LocalBindings local; 34 | 35 | @Value(name = "remote", title = "Remote", order = 2, desc = "The actions and events this node requires of remote (or peer) nodes.") 36 | public RemoteBindings remote; 37 | 38 | @Value(name = "params", title = "Parameters", order = 3, desc = "The global parameters used within the script.", genericClassA = String.class, genericClassB = ParameterBinding.class) 39 | public ParameterBindings params; 40 | 41 | public String toString() { 42 | return Serialisation.serialise(this); 43 | } 44 | 45 | } // (class) 46 | 47 | 48 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/Random.java: -------------------------------------------------------------------------------- 1 | package org.nodel; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Avoids having to create several instances of the Java Random class. 11 | */ 12 | public class Random { 13 | 14 | /** 15 | * (see getter) 16 | */ 17 | private java.util.Random _random = new java.util.Random(); 18 | 19 | /** 20 | * Returns a reference to this shared java.util.Random instance. 21 | */ 22 | public java.util.Random random() { 23 | return _random; 24 | } 25 | 26 | /** 27 | * (for convenience - see #java.util.Random) 28 | */ 29 | public int nextInt() { 30 | return _random.nextInt(); 31 | } 32 | 33 | /** 34 | * (for convenience - see #java.util.Random) 35 | * @param toExcl from 0 (inclusive) to 'toExcl' (exclusive). 36 | */ 37 | public int nextInt(int toExcl) { 38 | return _random.nextInt(toExcl); 39 | } 40 | 41 | /** 42 | * Returns random double from 0 (incl.) to 1 (excl.) 43 | * (for convenience - see #java.util.Random) 44 | */ 45 | public double nextDouble() { 46 | return _random.nextDouble(); 47 | } 48 | 49 | /** 50 | * (hidden) 51 | */ 52 | private Random() { 53 | } 54 | 55 | /** 56 | * (singleton) 57 | */ 58 | private static class LazyHolder { 59 | private static final Random INSTANCE = new Random(); 60 | } 61 | 62 | /** 63 | * (singleton) 64 | */ 65 | public static Random shared() { 66 | return LazyHolder.INSTANCE; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/host/NodeConfig.java: -------------------------------------------------------------------------------- 1 | package org.nodel.host; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import org.nodel.SimpleName; 10 | import org.nodel.reflection.Value; 11 | 12 | /** 13 | * Configuration required by a dynamic node. 14 | */ 15 | public class NodeConfig { 16 | 17 | public static NodeConfig Empty = new NodeConfig(); 18 | 19 | public static NodeConfig Example = new NodeConfig(); 20 | 21 | static { 22 | Empty.remoteBindingValues = RemoteBindingValues.Empty; 23 | Empty.paramValues = ParamValues.Empty; 24 | 25 | Example.remoteBindingValues = RemoteBindingValues.Example; 26 | Example.paramValues = ParamValues.Example; 27 | Example.dependencies = new String[] { "script.py", "custom.py" }; 28 | } 29 | 30 | 31 | @Value(name="dependencies", title="Dependencies / scripts / entry-points", order = 49, required = false, 32 | desc="An ordering of dependencies / scripts / entry-points that will be used when loading the node") 33 | public String[] dependencies; 34 | 35 | @Value(name = "remoteBindingValues", title = "Remote binding values", order = 50, required = true, 36 | desc = "The remote action and event binding values.") 37 | public RemoteBindingValues remoteBindingValues; 38 | 39 | @Value(name = "paramValues", title = "Parameter values", order = 60, required = true, 40 | genericClassA = SimpleName.class, genericClassB = Object.class, 41 | desc = "The script parameter values.") 42 | public ParamValues paramValues; 43 | 44 | } // (class) 45 | -------------------------------------------------------------------------------- /nodel-framework/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply plugin: 'maven-publish' 3 | apply plugin: 'eclipse' 4 | 5 | // some extended unicode is used in SimpleName 6 | compileJava.options.encoding = 'utf-8' 7 | 8 | jar { 9 | from "$buildDir/output" 10 | archiveBaseName = 'nodel-framework' 11 | manifest { 12 | attributes 'Implementation-Title': 'Nodel framework for Java', 13 | 'Implementation-Version': rootProject.ext.versionIdentifier 14 | } 15 | } 16 | 17 | java { 18 | sourceCompatibility = JavaVersion.VERSION_11 19 | targetCompatibility = JavaVersion.VERSION_11 20 | } 21 | 22 | tasks.withType(JavaCompile).configureEach { 23 | options.release = 11 24 | } 25 | 26 | testing { 27 | suites { 28 | test { 29 | useJUnitJupiter() 30 | 31 | targets { 32 | all { 33 | testTask.configure { 34 | testLogging { 35 | events 'passed', 'skipped', 'failed' 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | } 43 | 44 | dependencies { 45 | implementation 'joda-time:joda-time:2.6' 46 | implementation 'org.slf4j:slf4j-api:1.7.10' 47 | 48 | // SSH features 49 | implementation group: 'com.jcraft', name: 'jsch', version: '0.1.55' 50 | } 51 | 52 | testing { 53 | suites { 54 | // Configure the built-in test suite 55 | test { 56 | // Use JUnit Jupiter test framework 57 | useJUnitJupiter('5.7.0') 58 | 59 | dependencies { 60 | implementation 'org.junit.jupiter:junit-jupiter-params:5.7.0' 61 | implementation 'org.mockito:mockito-core:3.12.4' 62 | implementation 'ch.qos.logback:logback-classic:1.4.14' 63 | } 64 | } 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/net/NodelHttpClientProvider.java: -------------------------------------------------------------------------------- 1 | package org.nodel.net; 2 | 3 | import java.lang.reflect.Constructor; 4 | 5 | /** 6 | * The factory class for creating HTTP clients. Providers may be different depending on the platform / environment. 7 | * 8 | * This is based on late binding methodology used by SLF4j to split API vs impl. when dealing with logger factories. 9 | */ 10 | public abstract class NodelHttpClientProvider { 11 | 12 | public final static String CLASS = "org.nodel.http.StaticNodelHttpClientProvider"; 13 | 14 | public final static Object s_lock = new Object(); 15 | 16 | public static NodelHttpClientProvider s_provider; 17 | 18 | /** 19 | * Dynamically instantiates the provider only once. 20 | */ 21 | public static NodelHttpClientProvider instance() { 22 | if (s_provider != null) 23 | return s_provider; 24 | 25 | synchronized (s_lock) { 26 | // check again while locked 27 | if (s_provider != null) 28 | return s_provider; 29 | 30 | try { 31 | // resolve class 32 | Class clazz = Class.forName(CLASS); 33 | 34 | // resolve method 35 | Constructor constructor = clazz.getConstructor(); 36 | 37 | // invoke constructor 38 | s_provider = (NodelHttpClientProvider) constructor.newInstance(); 39 | 40 | // return the instance 41 | return s_provider; 42 | 43 | } catch (Exception exc) { 44 | throw new RuntimeException("Could not create an HTTP client provider", exc); 45 | } 46 | } 47 | } 48 | 49 | /** 50 | * Creates a Nodel HTTP client. 51 | */ 52 | public abstract NodelHTTPClient create(); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/threading/Atomic.java: -------------------------------------------------------------------------------- 1 | package org.nodel.threading; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.util.concurrent.atomic.AtomicInteger; 10 | 11 | /** 12 | * Some useful convenience methods for extra atomic operations. 13 | */ 14 | public class Atomic { 15 | 16 | /** 17 | * Atomic way to set if less than. 18 | */ 19 | public static int atomicIncrementAndWrap(AtomicInteger currentValue, int modulus) { 20 | for (;;) { 21 | int current = currentValue.get(); 22 | int next = current + 1; 23 | 24 | if (next == modulus) 25 | next = 0; 26 | 27 | if (currentValue.compareAndSet(current, next)) 28 | return next; 29 | } // (for) 30 | 31 | } // (method) 32 | 33 | /** 34 | * Atomic way to set if less than. 35 | */ 36 | public static int atomicLessThanAndSet(int value, AtomicInteger currentValue) { 37 | for (;;) { 38 | int current = currentValue.get(); 39 | int next = (value < current ? value : current); 40 | if (currentValue.compareAndSet(current, next)) 41 | return next; 42 | } // (for) 43 | 44 | } // (method) 45 | 46 | /** 47 | * Atomic way to set if more than. 48 | */ 49 | public static int atomicMoreThanAndSet(int value, AtomicInteger currentValue) { 50 | for (;;) { 51 | int current = currentValue.get(); 52 | int next = (value > current ? value : current); 53 | if (currentValue.compareAndSet(current, next)) 54 | return next; 55 | } // (for) 56 | 57 | } // (method) 58 | 59 | } // (class) 60 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/response/IStatus.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.response; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | public interface IStatus { 37 | 38 | String getDescription(); 39 | 40 | int getRequestStatus(); 41 | } 42 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/websockets/State.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.websockets; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Websocket 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | public enum State { 37 | UNCONNECTED, 38 | CONNECTING, 39 | OPEN, 40 | CLOSING, 41 | CLOSED 42 | } 43 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/Service.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | /** 15 | * An annotation used to represent a method or field that will act as a service end-point 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target({ElementType.FIELD, ElementType.METHOD}) 19 | public @interface Service { 20 | 21 | /** 22 | * The strict name/id/alias to use for the value. 23 | */ 24 | public String name(); 25 | 26 | /** 27 | * A short title for the value. 28 | */ 29 | public String title() default ""; 30 | 31 | /** 32 | * The field order. 33 | */ 34 | public double order() default 0; 35 | 36 | /** 37 | * Is the default value for a given class. 38 | */ 39 | public boolean treatAsDefaultService() default false; 40 | 41 | /** 42 | * Holds an optional description of this service. 43 | */ 44 | public String desc() default ""; 45 | 46 | /** 47 | * Overrides the content type (MIME). 48 | * TODO: reserved only; not supported 49 | */ 50 | public String contentType() default ""; 51 | 52 | /** 53 | * Embed in outer class using the field name specified. 54 | */ 55 | public String embeddedFieldName() default ""; 56 | 57 | /** 58 | * Holds if generics are being used. 59 | * 'Type A' would apply to Lists and Map keys, for example. 60 | */ 61 | public Class genericClassA() default Object.class; 62 | 63 | /** 64 | * Holds if generics are being used. 65 | * 'Type B' would apply to Map values. 66 | */ 67 | public Class genericClassB() default Object.class; 68 | 69 | } // (class) -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/core/LoopbackChannelClient.java: -------------------------------------------------------------------------------- 1 | package org.nodel.core; 2 | 3 | /** 4 | * When nodes live in the same runtime, this class is used for rapid node messaging instead 5 | * of a networking stack. 6 | */ 7 | public class LoopbackChannelClient extends ChannelClient { 8 | 9 | /** 10 | * Static lock 11 | */ 12 | private static Object s_lock = new Object(); 13 | 14 | /** 15 | * Shared instance (Write locked around 's_lock'). 16 | */ 17 | private static LoopbackChannelClient s_instance; 18 | 19 | /** 20 | * Only one instance can exist. 21 | */ 22 | private LoopbackChannelClient() { 23 | super(NodeAddress.IN_PROCESS); 24 | } 25 | 26 | @Override 27 | protected void start() { 28 | // always started 29 | } 30 | 31 | @Override 32 | public boolean isConnected() { 33 | // always connected 34 | return true; 35 | } 36 | 37 | @Override 38 | public void sendMessage(final ChannelMessage message) { 39 | // use thread-pool to avoid deep dive into server-side stack 40 | s_threadPool.execute(new Runnable() { 41 | 42 | @Override 43 | public void run() { 44 | LoopbackChannelServer.instance().receiveMessage(message); 45 | } 46 | 47 | }); 48 | } 49 | 50 | /** 51 | * Called by its peer, LoopbackChannelServer. 52 | */ 53 | public void receiveMessage(ChannelMessage message) { 54 | super.handleMessage(message); 55 | } 56 | 57 | /** 58 | * Returns an instance which can be shared. 59 | */ 60 | public static LoopbackChannelClient instance() { 61 | if (s_instance == null) { 62 | synchronized(s_lock) { 63 | if (s_instance == null) 64 | s_instance = new LoopbackChannelClient(); 65 | } 66 | } 67 | 68 | return s_instance; 69 | } // (method) 70 | 71 | } // (class) 72 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/util/IFactory.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.util; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | /** 37 | * Represents a simple factory 38 | * 39 | * @author LordFokas 40 | * @param 41 | * The Type of object to create 42 | */ 43 | public interface IFactory { 44 | 45 | T create(); 46 | } 47 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/LockFreeList.java: -------------------------------------------------------------------------------- 1 | package org.nodel; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.concurrent.atomic.AtomicReference; 7 | 8 | public class LockFreeList { 9 | 10 | @SuppressWarnings("unchecked") 11 | private List empty() { 12 | return (List) Collections.emptyList(); 13 | } 14 | 15 | /** 16 | * Snapshot of list able to grow safely without any locking. 17 | * (actual reference can never be null) 18 | */ 19 | private AtomicReference> _array = new AtomicReference<>(empty()); 20 | 21 | /** 22 | * Adds an element. 23 | */ 24 | public void add(T obj) { 25 | if (obj == null) 26 | throw new IllegalArgumentException("Element cannot be null"); 27 | 28 | for (;;) { 29 | // grow array 'lock-lessly' 30 | List current = _array.get(); 31 | 32 | // make space for one more, copy original and new items. 33 | ArrayList newValue = new ArrayList<>(current.size() + 1); 34 | newValue.addAll(current); 35 | newValue.add(obj); 36 | 37 | // swap in the new one if the original hasn't been changed 38 | if (_array.compareAndSet(current, newValue)) 39 | break; 40 | 41 | // otherwise keep trying 42 | } 43 | } 44 | 45 | /** 46 | * Clears the list. 47 | */ 48 | public void clear() { 49 | for (;;) { 50 | List current = _array.get(); 51 | 52 | if (_array.compareAndSet(current, empty())) 53 | break; 54 | } 55 | } 56 | 57 | /** 58 | * Returns a snap-shot of the items. 59 | */ 60 | public List items() { 61 | return _array.get(); 62 | } 63 | 64 | /** 65 | * The size of list. 66 | */ 67 | public int size() { 68 | return _array.get().size(); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /nodel-jyhost/src/main/resources/org/nodel/jyhost/example.pysp: -------------------------------------------------------------------------------- 1 | <% 2 | # Nodel auto-generated example PySp (server-side script) that applies to Nodel $VERSION or compatible versions. 3 | %> 4 | 5 | <%! _node.getName() %> Python server page 6 | 7 | 8 |

    PySP - Nodel's server-side Python pages

    9 | 10 |

    (To use this example, place it in a 'content' folder) 11 | 12 |

    (click here for pre- and post-Python rendered pages) 13 | 14 |

    Raw node name is <%= _node.getName() %>. 15 | 16 |

    HTML friendly node description which may have HTML tags is <%! _node.getDesc() %>. 17 | 18 |

    ipAddress parameter is <%! param_ipAddress %>. 19 | 20 |

    Useful server-side Python

    21 | 22 |

    URI is <%! req.uri %>. 23 | 24 |

    local host is <%! req.localHost %>, local port is <%! req.localPort %>. 25 | 26 |

    local host is <%! req.remoteHost %>, remote port is <%! req.remotePort %>. 27 | 28 |

    Request headers

    29 |
      30 | <% 31 | for x in req.headers: 32 | %>
    • <%! x %> is <%! req.headers[x] %>
    • 33 | <% 34 | 35 | %> 36 |
    37 | 38 |

    req attributes

    39 |
      40 | <% 41 | for x in dir(req): 42 | if '__' not in x: %>
    • <%! x %>
    • 43 | <% 44 | 45 | %> 46 |
    47 | 48 |

    resp attributes

    49 |
      50 | <% 51 | for x in dir(resp): 52 | if '__' not in x: %>
    • <%! x %>
    • 53 | <% 54 | %> 55 |
    56 |

    locals() items

    57 |
      58 | <% 59 | loc = locals() 60 | for x in loc: 61 | %>
    • <%! x %> is <%! loc[x] %>
    • 62 | <% 63 | %> 64 |
    65 |

    globals() items

    66 |
      67 | <% 68 | glob = globals() 69 | for x in glob: 70 | %>
    • <%! x %> is <%! glob[x] %>
    • 71 | <% 72 | %> 73 |
    74 |

    _node attributes

    75 |
      76 | <% 77 | for x in dir(_node): 78 | if '__' not in x: %>
    • <%! x %>
    • 79 | <% 80 | %> 81 |
    82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/logging/slf4j/SimpleLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package org.nodel.logging.slf4j; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.slf4j.ILoggerFactory; 8 | import org.slf4j.Logger; 9 | 10 | public class SimpleLoggerFactory implements ILoggerFactory { 11 | 12 | /** 13 | * (private to enforce singleton useage) 14 | */ 15 | private SimpleLoggerFactory() { 16 | } 17 | 18 | private static Map _loggers = new HashMap(); 19 | 20 | @Override 21 | public Logger getLogger(String name) { 22 | synchronized(_loggers) { 23 | 24 | SimpleLogger existing = _loggers.get(name); 25 | 26 | if (existing == null) { 27 | existing = new SimpleLogger(name); 28 | _loggers.put(name, existing); 29 | } 30 | 31 | return existing; 32 | } 33 | } 34 | 35 | /** 36 | * Returns a thread-safe snapshot of all the loggers. 37 | */ 38 | public ArrayList getLoggers() { 39 | synchronized(_loggers) { 40 | return new ArrayList<>(_loggers.values()); 41 | } 42 | } 43 | 44 | /** 45 | * Triggers a maintenance request on all the loggers 46 | */ 47 | public void requestMaintenance() { 48 | synchronized (_loggers) { 49 | for (SimpleLogger logger : _loggers.values()) { 50 | logger.requestMaintenance(); 51 | } 52 | } 53 | } 54 | 55 | /** 56 | * (singleton, thread-safe, non-blocking) 57 | */ 58 | private static class Instance { 59 | private static final SimpleLoggerFactory INSTANCE = new SimpleLoggerFactory(); 60 | } 61 | 62 | /** 63 | * A convenience method for the Nodel framework to return the shared instance (instead of via factory) 64 | */ 65 | public static SimpleLoggerFactory shared() { 66 | return Instance.INSTANCE; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/Version.java: -------------------------------------------------------------------------------- 1 | package org.nodel; 2 | 3 | import java.io.InputStream; 4 | 5 | import org.nodel.io.Stream; 6 | import org.nodel.reflection.Serialisation; 7 | import org.nodel.reflection.Value; 8 | 9 | /** 10 | * Example: 11 | * { "project" : "nodel-framework-java", 12 | * "branch" : "Stable", 13 | * "version" : "2.0.10-stable_r381", 14 | * "id" : "d13377df0031+ (Stable) tip", 15 | * "host" : "THEBUILDSERVER", 16 | * "date" : "25-Feb-2015 13:43:35" } 17 | */ 18 | 19 | public class Version { 20 | 21 | @Value(name = "project", order = 1) 22 | public String project = "unset"; 23 | 24 | @Value(name = "branch", order = 2) 25 | public String branch = "unset"; 26 | 27 | @Value(name = "version", order = 3) 28 | public String version = "unset"; 29 | 30 | @Value(name = "id", order = 4) 31 | public String id = "unset"; 32 | 33 | @Value(name = "date", order = 5) 34 | public String date = "unset"; 35 | 36 | /** 37 | * Extracts a version object. Should only be used once. 38 | */ 39 | private static Version extractVersion() { 40 | Version result = null; 41 | InputStream is = null; 42 | 43 | try { 44 | is = Version.class.getResourceAsStream("build.json"); 45 | 46 | if (is != null) { 47 | String versionStr = Stream.readFully(is); 48 | result = (Version) Serialisation.deserialise(Version.class, versionStr); 49 | } 50 | } catch (Exception exc) { 51 | // ignore 52 | } finally { 53 | Stream.safeClose(is); 54 | } 55 | 56 | return (result != null ? result : new Version()); 57 | } 58 | 59 | /** 60 | * (singleton, thread-safe, non-blocking) 61 | */ 62 | private static class Instance { 63 | 64 | private static final Version INSTANCE = extractVersion(); 65 | 66 | } 67 | 68 | /** 69 | * Returns the singleton instance of this class. 70 | */ 71 | public static Version shared() { 72 | return Instance.INSTANCE; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/webserver/WebServerPluginInfo.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.webserver; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Webserver 6 | * %% 7 | * Copyright (C) 2012 - 2015 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | /** 37 | * @author Paul S. Hawke (paul.hawke@gmail.com) On: 9/14/13 at 8:09 AM 38 | */ 39 | public interface WebServerPluginInfo { 40 | 41 | String[] getIndexFilesForMimeType(String mime); 42 | 43 | String[] getMimeTypes(); 44 | 45 | WebServerPlugin getWebServerPlugin(String mimeType); 46 | } 47 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/util/IHandler.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.util; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | /** 37 | * Defines a generic handler that returns an object of type O when given an 38 | * object of type I. 39 | * 40 | * @author LordFokas 41 | * @param 42 | * The input type. 43 | * @param 44 | * The output type. 45 | */ 46 | public interface IHandler { 47 | 48 | public O handle(I input); 49 | } 50 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/threading/IAsyncRunner.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.threading; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | import org.nanohttpd.protocols.http.ClientHandler; 37 | 38 | /** 39 | * Pluggable strategy for asynchronously executing requests. 40 | */ 41 | public interface IAsyncRunner { 42 | 43 | void closeAll(); 44 | 45 | void closed(ClientHandler clientHandler); 46 | 47 | void exec(ClientHandler code); 48 | } 49 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/host/LogEntry.java: -------------------------------------------------------------------------------- 1 | package org.nodel.host; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import org.joda.time.DateTime; 10 | import org.nodel.SimpleName; 11 | import org.nodel.reflection.Value; 12 | 13 | /** 14 | * Used for feedback by dynamic nodes. 15 | */ 16 | public class LogEntry { 17 | 18 | public enum Source { 19 | local, remote, unbound; 20 | } 21 | 22 | public enum Type { 23 | action, event, actionBinding, eventBinding; 24 | } 25 | 26 | /** 27 | * The sequence number. 28 | */ 29 | @Value(name = "seq", title = "Sequence", desc = "The sequence number.", order = 1) 30 | public long seq; 31 | 32 | /** 33 | * The time stamp. 34 | */ 35 | @Value(name = "timestamp", title = "Timestamp", desc = "A universal timestamp.", order = 2) 36 | public DateTime timestamp; 37 | 38 | /** 39 | * The source. 40 | */ 41 | @Value(name = "source", title = "Source", desc = "The source of this event.", order = 3) 42 | public Source source; 43 | 44 | /** 45 | * The type. 46 | */ 47 | @Value(name = "type", title = "Type", desc = "The event type.", order = 4) 48 | public Type type; 49 | 50 | /** 51 | * The related event/action alias. 52 | */ 53 | @Value(name = "alias", title = "Alias", desc = "The related event/action alias.", order = 5) 54 | public SimpleName alias; 55 | 56 | /** 57 | * The argument. 58 | */ 59 | @Value(name = "arg", title = "Argument", desc = "An argument.", required = false, order = 6) 60 | public Object arg; 61 | 62 | public LogEntry(long seq, DateTime timestamp, Source source, Type type, SimpleName alias, Object arg) { 63 | this.seq = seq; 64 | this.timestamp = timestamp; 65 | this.source = source; 66 | this.type = type; 67 | this.alias = alias; 68 | this.arg = arg; 69 | } 70 | 71 | } // (class) -------------------------------------------------------------------------------- /nodel-windows/service/install_as_service.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | SET RELEASE=nodelhost-dev-2.1.1-rev238 3 | echo. Nodel Host Windows Service installer 4 | echo. 5 | echo. (Press Ctrl-C to stop at any time) 6 | echo. 7 | 8 | rem Make sure Java.exe can be run 9 | where java > nul 10 | if ERRORLEVEL 1 goto NoJava 11 | 12 | echo Checking Java architechture... 13 | pause 14 | 15 | java -d64 -version 2> nul 16 | if ERRORLEVEL 1 goto GotJava86 17 | if ERRORLEVEL 0 goto GotJava64 18 | 19 | 20 | :GotJava86 21 | echo (Java 32-bit) 22 | echo Establishing 32-bit Java service wrapper... 23 | pause 24 | copy NodelHostsvc.exe.x86 ..\NodelHostsvc.exe 25 | 26 | goto CopyJAR 27 | 28 | :GotJava64 29 | echo (Java 64-bit) 30 | echo Establishing 64-bit Java service wrapper... 31 | pause 32 | copy NodelHostsvc.exe.x64 ..\NodelHostsvc.exe 33 | 34 | goto CopyJAR 35 | 36 | 37 | :CopyJAR 38 | echo Copying versioned JAR to static JAR for static entry-point... (%RELEASE%.jar) 39 | copy ..\%RELEASE%.jar ..\nodelhost.jar /Y 40 | echo ...copy done! 41 | echo. 42 | 43 | 44 | 45 | echo Stopping any existing nodel services... 46 | pause 47 | ..\NodelHostsvc.exe //SS 48 | echo ...stop done! 49 | echo. 50 | 51 | echo Registering the (new) "Nodel Host" service... 52 | pause 53 | ..\NodelHostsvc.exe //IS --DisplayName "Nodel Host" --Description "(see github.com/museumsvictoria/nodel)" --Startup auto --StartMode jvm --StartClass org.nodel.nodelhost.Service --StartMethod start --StopMode jvm --StopClass org.nodel.nodelhost.Service --StopMethod stop --LogPath .\logs --Classpath nodelhost.jar 54 | echo ...service registration complete! 55 | echo. 56 | 57 | echo Starting the "Nodel Host" service... 58 | pause 59 | ..\NodelHostsvc.exe //ES 60 | echo ...service start done! 61 | echo. 62 | 63 | echo No more steps. 64 | pause 65 | 66 | GOTO END 67 | 68 | :NoJava 69 | echo Could not detect the Java platform. Please download from https://java.com/en/download/. 70 | pause 71 | GOTO END 72 | 73 | :NoNodelHostJar 74 | echo Please ensure latest version of Nodel Host release exists in "latestVersion" folder (e.g. "%RELEASE%.jar") 75 | echo (one can be downloaded from https://github.com/museumsvictoria/nodel) 76 | pause 77 | GOTO END 78 | 79 | :End -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/Exceptions.java: -------------------------------------------------------------------------------- 1 | package org.nodel; 2 | 3 | import org.nodel.reflection.Serialisation; 4 | import org.nodel.reflection.Value; 5 | 6 | /* 7 | * Convenience functions for dealing with Exceptions particularly in logs, etc. 8 | */ 9 | public class Exceptions { 10 | 11 | /** 12 | * Forms part of an exception graph. 13 | */ 14 | public static class ExceptionSummary { 15 | 16 | @Value(name = "name", order = 1) 17 | public String name; 18 | 19 | @Value(name = "msg", order = 2) 20 | public String msg; 21 | 22 | @Value(name = "cause", order = 3) 23 | public ExceptionSummary cause; 24 | 25 | } 26 | 27 | /** 28 | * Produces an exception graph that can be used to format a stack-trace. 29 | */ 30 | public static ExceptionSummary getExceptionGraph(Throwable th) { 31 | if (th == null) 32 | throw new IllegalArgumentException("An exception must be provided."); 33 | 34 | ExceptionSummary summary = new ExceptionSummary(); 35 | 36 | Throwable currentThrowable = th; 37 | ExceptionSummary currentSummary = summary; 38 | 39 | // (avoid stack overflow) 40 | int level = 0; 41 | 42 | while(currentThrowable != null) { 43 | currentSummary.name = currentThrowable.getClass().getName(); 44 | currentSummary.msg = currentThrowable.getMessage(); 45 | 46 | if (currentThrowable.getCause() == null || level > 128) 47 | break; 48 | 49 | currentThrowable = currentThrowable.getCause(); 50 | currentSummary.cause = new ExceptionSummary(); 51 | 52 | currentSummary = currentSummary.cause; 53 | } // (while) 54 | 55 | return summary; 56 | } 57 | 58 | /** 59 | * A string representation of 'getExceptionGraph()' 60 | */ 61 | public static String formatExceptionGraph(Throwable th) { 62 | ExceptionSummary result = getExceptionGraph(th); 63 | return Serialisation.serialise(result); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/util/IFactoryThrowing.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.util; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | /** 37 | * Represents a factory that can throw an exception instead of actually creating 38 | * an object 39 | * 40 | * @author LordFokas 41 | * @param 42 | * The Type of object to create 43 | * @param 44 | * The base Type of exceptions that can be thrown 45 | */ 46 | public interface IFactoryThrowing { 47 | 48 | T create() throws E; 49 | } 50 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/DateTimes.java: -------------------------------------------------------------------------------- 1 | package org.nodel; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Mainly contains DateTime convenience functions. 11 | */ 12 | public class DateTimes { 13 | 14 | /** 15 | * Formats a duration (in millis) in a short variably 16 | * precise format. e.g. '2d 1h', '2m 1s', '2m 10s' 17 | */ 18 | public static String formatShortDuration(long duration) { 19 | 20 | long value = Math.abs(duration); 21 | 22 | long days = (value / 3600 / 1000) / 24; 23 | long hours = (value / 3600 / 1000) % 24; 24 | long minutes = (value / 1000 / 60) % 60; 25 | long seconds = (value / 1000) % 60; 26 | long millis = value % 1000; 27 | 28 | String signPart = (duration < 0 ? "-" : ""); 29 | 30 | if (days > 0) 31 | return signPart + days + "d " + hours + "h"; 32 | 33 | if (hours > 0) 34 | return signPart + hours + "h " + minutes + "m"; 35 | 36 | if (minutes > 0) 37 | return signPart + minutes + "m " + seconds + "s"; 38 | 39 | if (seconds > 0) 40 | return signPart + seconds + "s " + millis + "ms"; 41 | 42 | else 43 | return signPart + millis + "ms"; 44 | } // (method) 45 | 46 | /** 47 | * Returns a period between two timestamps (in nanos). 48 | * Used with 'System.nanoTime()' as a base. 49 | */ 50 | public static String formatPeriod(long startNanos, long stopNanos) { 51 | return DateTimes.formatShortDuration((stopNanos - startNanos) / 1000000); 52 | } // (method) 53 | 54 | /** 55 | * Returns a period between now and a given timestamp (in nanos). 56 | * Used with 'System.nanoTime()' as a base. 57 | */ 58 | public static String formatPeriod(long startNanos) { 59 | return DateTimes.formatShortDuration((System.nanoTime() - startNanos) / 1000000); 60 | } // (method) 61 | 62 | } // (class) 63 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/tempfiles/ITempFileManager.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.tempfiles; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | /** 37 | * Temp file manager. 38 | *

    39 | *

    40 | * Temp file managers are created 1-to-1 with incoming requests, to create and 41 | * cleanup temporary files created as a result of handling the request. 42 | *

    43 | */ 44 | public interface ITempFileManager { 45 | 46 | void clear(); 47 | 48 | public ITempFile createTempFile(String filename_hint) throws Exception; 49 | } 50 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/core/NodelPoint.java: -------------------------------------------------------------------------------- 1 | package org.nodel.core; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import org.nodel.SimpleName; 10 | 11 | /** 12 | * Stores a "node name" , "event" / "action" key. 13 | * For use in maps or lists; performs Nodel name reduction. 14 | */ 15 | public class NodelPoint { 16 | 17 | /** 18 | * (see 'getNode') 19 | */ 20 | private SimpleName _node; 21 | 22 | /** 23 | * (see 'getConnection') 24 | */ 25 | private SimpleName _point; 26 | 27 | /** 28 | * (private constructor) 29 | */ 30 | private NodelPoint(SimpleName node, SimpleName point) { 31 | _node = node; 32 | _point = point; 33 | } 34 | 35 | /** 36 | * Creates a new key. 37 | */ 38 | public static NodelPoint create(String nodeName, String pointName) { 39 | return new NodelPoint(new SimpleName(nodeName), new SimpleName(pointName)); 40 | } 41 | 42 | /** 43 | * Creates a new key. 44 | */ 45 | public static NodelPoint create(SimpleName node, SimpleName point) { 46 | return new NodelPoint(node, point); 47 | } 48 | 49 | /** 50 | * Gets the node. 51 | */ 52 | public SimpleName getNode() { 53 | return _node; 54 | } 55 | 56 | /** 57 | * Gets the connection. 58 | */ 59 | public SimpleName getPoint() { 60 | return _point; 61 | } 62 | 63 | @Override 64 | public boolean equals(Object obj) { 65 | if (obj == null || !(obj instanceof NodelPoint)) 66 | return false; 67 | 68 | NodelPoint other = (NodelPoint) obj; 69 | 70 | return _node.equals(other._node) && _point.equals(other._point); 71 | } // (method) 72 | 73 | @Override 74 | public int hashCode() { 75 | return _node.hashCode() ^ _point.hashCode(); 76 | } // (method) 77 | 78 | @Override 79 | public String toString() { 80 | return _node + "." + _point; 81 | } 82 | 83 | } // (class) -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/Strings.java: -------------------------------------------------------------------------------- 1 | package org.nodel; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Convenience methods for Strings. 11 | */ 12 | public class Strings { 13 | 14 | /** 15 | * An empty array of strings. 16 | */ 17 | public static final String[] EmptyArray = new String[] {}; 18 | 19 | /** 20 | * (use 'isEmpty' instead) 21 | */ 22 | @Deprecated 23 | public static boolean isNullOrEmpty(String value) { 24 | return isEmpty(value); 25 | } 26 | 27 | /** 28 | * Returns true if the value is strictly null or has length zero. 29 | */ 30 | public static boolean isEmpty(String value) { 31 | return value == null || value.length() == 0; 32 | } 33 | 34 | /** 35 | * Returns true if the value is null or empty (or full of common whitespace), false otherwise. 36 | */ 37 | public static boolean isBlank(String value) { 38 | if (value == null) 39 | return true; 40 | 41 | // check length... 42 | int len = value.length(); 43 | 44 | if (len == 0) 45 | return true; 46 | 47 | // ...and then for any non common-whitespace, incl. 0xa0 NO-BREAK SPACE 48 | for (int a = 0; a < len; a++) { 49 | char c = value.charAt(a); 50 | 51 | if (c != ' ' && c != '\t' && c != '\r' && c != '\n' && !Character.isSpaceChar(c)) 52 | return false; 53 | } 54 | 55 | // was empty or all common whitespace 56 | return true; 57 | } 58 | 59 | /** 60 | * A safe, simple alphabetical compare function. 61 | */ 62 | public static int compare(String name1, String name2) { 63 | if (name1 == null && name2 == null) 64 | return 0; 65 | 66 | if (name1 == null) 67 | return 1; 68 | 69 | if (name2 == null) 70 | return -1; 71 | 72 | return name1.compareTo(name2); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/tempfiles/ITempFile.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.tempfiles; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | import java.io.OutputStream; 37 | 38 | /** 39 | * A temp file. 40 | *

    41 | *

    42 | * Temp files are responsible for managing the actual temporary storage and 43 | * cleaning themselves up when no longer needed. 44 | *

    45 | */ 46 | public interface ITempFile { 47 | 48 | public void delete() throws Exception; 49 | 50 | public String getName(); 51 | 52 | public OutputStream open() throws Exception; 53 | } 54 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/sockets/DefaultServerSocketFactory.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.sockets; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | import java.io.IOException; 37 | import java.net.ServerSocket; 38 | 39 | import org.nanohttpd.util.IFactoryThrowing; 40 | 41 | /** 42 | * Creates a normal ServerSocket for TCP connections 43 | */ 44 | public class DefaultServerSocketFactory implements IFactoryThrowing { 45 | 46 | @Override 47 | public ServerSocket create() throws IOException { 48 | return new ServerSocket(); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/webserver/WebServerPlugin.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.webserver; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Webserver 6 | * %% 7 | * Copyright (C) 2012 - 2015 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | import java.io.File; 37 | import java.util.Map; 38 | 39 | import org.nanohttpd.protocols.http.IHTTPSession; 40 | import org.nanohttpd.protocols.http.response.Response; 41 | 42 | /** 43 | * @author Paul S. Hawke (paul.hawke@gmail.com) On: 9/14/13 at 8:09 AM 44 | */ 45 | public interface WebServerPlugin { 46 | 47 | boolean canServeUri(String uri, File rootDir); 48 | 49 | void initialize(Map commandLineOptions); 50 | 51 | Response serveFile(String uri, Map headers, IHTTPSession session, File file, String mimeType); 52 | } 53 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/host/ParameterBindings.java: -------------------------------------------------------------------------------- 1 | package org.nodel.host; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.util.HashMap; 10 | import java.util.LinkedHashMap; 11 | import java.util.Map; 12 | 13 | import org.nodel.SimpleName; 14 | import org.nodel.reflection.Serialisation; 15 | 16 | /** 17 | * The dynamic node's full parameter map. 18 | */ 19 | public class ParameterBindings extends HashMap { 20 | 21 | private static final long serialVersionUID = 9052202331768703250L; 22 | 23 | public static ParameterBindings Empty = new ParameterBindings(); 24 | 25 | public static ParameterBindings Example; 26 | 27 | static { 28 | Example = new ParameterBindings(); 29 | Example.put(new SimpleName(ParameterBinding.ExampleName), ParameterBinding.Example); 30 | } 31 | 32 | public ParameterBinding get(SimpleName key) { 33 | return super.get(key); 34 | } 35 | 36 | public Map asSchema() { 37 | Map schema = new LinkedHashMap(); 38 | schema.put("type", "object"); 39 | schema.put("title", "Parameters"); 40 | 41 | Map properties = new LinkedHashMap(); 42 | 43 | schema.put("properties", properties); 44 | for (Map.Entry entry : this.entrySet()) { 45 | String paramName = entry.getKey().getReducedName(); 46 | ParameterBinding paramBinding = entry.getValue(); 47 | Map paramSchema = paramBinding.schema; 48 | 49 | if (paramSchema == null) 50 | paramSchema = new HashMap(); 51 | 52 | paramSchema.put("title", paramBinding.title); 53 | paramSchema.put("desc", paramBinding.desc); 54 | paramSchema.put("group", paramBinding.group); 55 | paramSchema.put("order", paramBinding.order); 56 | properties.put(paramName, paramSchema); 57 | } // (for) 58 | 59 | return schema; 60 | } // (method) 61 | 62 | public String toString() { 63 | return Serialisation.serialise(this); 64 | } 65 | 66 | // public 67 | 68 | } // (class) 69 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/net/HTTPSimpleResponse.java: -------------------------------------------------------------------------------- 1 | package org.nodel.net; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | 7 | import org.nodel.SimpleName; 8 | 9 | /** 10 | * For message-based HTTP response (non-streams). 11 | * Headers are stored as strings or list of strings. 12 | */ 13 | @SuppressWarnings("serial") 14 | public class HTTPSimpleResponse extends HashMap> { 15 | 16 | /** 17 | * The HTTP status code part e.g. 200 18 | */ 19 | public int statusCode; 20 | 21 | /** 22 | * The HTTP reason phrase, e.g. 'OK' 23 | */ 24 | public String reasonPhrase; 25 | 26 | /** 27 | * The content. 28 | */ 29 | public String content; 30 | 31 | /** 32 | * Adds a header, allowing for multiple values for the same name 33 | */ 34 | public void addHeader(Object headerName, String value) { 35 | SimpleName simpleName = SimpleName.intoSimple(headerName); 36 | 37 | List list = this.get(simpleName); 38 | if (list == null) { 39 | list = new ArrayList(); 40 | this.put(simpleName, list); 41 | } 42 | 43 | list.add(value); 44 | } 45 | 46 | /** 47 | * ('get' and 'getAll' do the same) 48 | */ 49 | @Override 50 | public List get(Object headerName) { 51 | return super.get(SimpleName.intoSimple(headerName)); 52 | } 53 | 54 | /** 55 | * Returns the first value of a given header 56 | */ 57 | public String getFirstHeader(Object headerName) { 58 | List result = this.get(headerName); 59 | 60 | if (result == null) 61 | return null; 62 | 63 | return result.get(0); 64 | } 65 | 66 | /** 67 | * Returns the last value of a given header 68 | */ 69 | public String getLastHeader(Object headerName) { 70 | List result = this.get(headerName); 71 | 72 | if (result == null) 73 | return null; 74 | 75 | return result.get(result.size() - 1); 76 | } 77 | 78 | @Override 79 | public String toString() { 80 | return String.format("[statusCode:%s; reasonPhrase:[%s]; %s header%s; %s]", 81 | statusCode, reasonPhrase, this.size(), this.size() != 1 ? "s" : "", 82 | content.length() == 0 ? "blank content" : "content length " + content.length()); 83 | } 84 | 85 | } -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/core/LoopbackChannelServer.java: -------------------------------------------------------------------------------- 1 | package org.nodel.core; 2 | 3 | import org.nodel.diagnostics.Diagnostics; 4 | import org.nodel.diagnostics.LongSharableMeasurementProvider; 5 | import org.nodel.diagnostics.SharableMeasurementProvider; 6 | 7 | /* 8 | * This Source Code Form is subject to the terms of the Mozilla Public 9 | * License, v. 2.0. If a copy of the MPL was not distributed with this 10 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 11 | */ 12 | 13 | /** 14 | * When nodes live in the same runtime, this class is used for radpid node messaging instead 15 | * of a networking stack. 16 | */ 17 | public class LoopbackChannelServer extends ChannelServer { 18 | 19 | /** 20 | * Only need one of these for all send/receive client/server combinations as they're connected symmetrically. 21 | * (diagnostics) 22 | */ 23 | private static SharableMeasurementProvider s_counterMessages = new LongSharableMeasurementProvider(); 24 | 25 | /** 26 | * (diagnostics) 27 | */ 28 | static { 29 | Diagnostics.shared().registerCounter("Nodel loopback channel.Messages", s_counterMessages, true); 30 | 31 | // measuring data rate is not needed as only references are passed around, not the data itself. 32 | } 33 | 34 | private static LoopbackChannelServer staticInstance; 35 | 36 | public LoopbackChannelServer(NodelServers nodelServer) { 37 | super(nodelServer); 38 | 39 | staticInstance = this; 40 | } 41 | 42 | @Override 43 | protected void sendMessage(final ChannelMessage message) { 44 | s_counterMessages.incr(); 45 | 46 | // use thread-pool to avoid deep dive into client-side stack 47 | s_threadPool.execute(new Runnable() { 48 | 49 | @Override 50 | public void run() { 51 | LoopbackChannelClient.instance().receiveMessage(message); 52 | } 53 | 54 | }); 55 | } 56 | 57 | /** 58 | * Used by peer LoopbackChannelClient. 59 | */ 60 | public void receiveMessage(ChannelMessage message) { 61 | super.handleMessage(message); 62 | } 63 | 64 | @Override 65 | public void start() { 66 | // nothing required here 67 | } 68 | 69 | /** 70 | * Returns an instance which can be shared. This method is likely to block. 71 | */ 72 | public static LoopbackChannelServer instance() { 73 | return staticInstance; 74 | } // (method) 75 | 76 | } // (class) 77 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/websockets/OpCode.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.websockets; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Websocket 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | public enum OpCode { 37 | Continuation(0), 38 | Text(1), 39 | Binary(2), 40 | Close(8), 41 | Ping(9), 42 | Pong(10); 43 | 44 | public static OpCode find(byte value) { 45 | for (OpCode opcode : values()) { 46 | if (opcode.getValue() == value) { 47 | return opcode; 48 | } 49 | } 50 | return null; 51 | } 52 | 53 | private final byte code; 54 | 55 | private OpCode(int code) { 56 | this.code = (byte) code; 57 | } 58 | 59 | public byte getValue() { 60 | return this.code; 61 | } 62 | 63 | public boolean isControlFrame() { 64 | return this == Close || this == Ping || this == Pong; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/request/Method.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.request; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | /** 37 | * HTTP Request methods, with the ability to decode a String back 38 | * to its enum value. 39 | */ 40 | public enum Method { 41 | GET, 42 | PUT, 43 | POST, 44 | DELETE, 45 | HEAD, 46 | OPTIONS, 47 | TRACE, 48 | CONNECT, 49 | PATCH, 50 | PROPFIND, 51 | PROPPATCH, 52 | MKCOL, 53 | MOVE, 54 | COPY, 55 | LOCK, 56 | UNLOCK, 57 | NOTIFY, 58 | SUBSCRIBE; 59 | 60 | public static Method lookup(String method) { 61 | if (method == null) 62 | return null; 63 | 64 | try { 65 | return valueOf(method); 66 | } catch (IllegalArgumentException e) { 67 | // TODO: Log it? 68 | return null; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/diagnostics/CountableOutputStream.java: -------------------------------------------------------------------------------- 1 | package org.nodel.diagnostics; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.io.IOException; 10 | import java.io.OutputStream; 11 | 12 | import org.nodel.io.Stream; 13 | 14 | /** 15 | * Allows for data counting of underlying stream. 16 | */ 17 | public class CountableOutputStream extends OutputStream { 18 | 19 | private SharableMeasurementProvider total; 20 | 21 | private SharableMeasurementProvider ops; 22 | 23 | private OutputStream base; 24 | 25 | public CountableOutputStream(OutputStream base, SharableMeasurementProvider ops, SharableMeasurementProvider total) { 26 | this.base = base; 27 | this.ops = ops; 28 | this.total = total; 29 | } // (init) 30 | 31 | /** 32 | * The total amount of data written. 33 | */ 34 | public long getTotal() { 35 | return this.total.getMeasurement(); 36 | } 37 | 38 | /** 39 | * Records the number of write operations 40 | */ 41 | public long getOps() { 42 | return this.ops.getMeasurement(); 43 | } 44 | 45 | /** 46 | * The underlying stream. 47 | */ 48 | public OutputStream getBase() { 49 | return this.base; 50 | } 51 | 52 | /** 53 | * {@inheritDoc} 54 | */ 55 | @Override 56 | public void write(int b) throws IOException { 57 | this.ops.incr(); 58 | this.total.add(8); 59 | 60 | this.base.write(b); 61 | } 62 | 63 | /** 64 | * {@inheritDoc} 65 | */ 66 | @Override 67 | public void write(byte b[]) throws IOException { 68 | this.ops.incr(); 69 | this.total.add(b.length * 8); 70 | 71 | this.base.write(b); 72 | } 73 | 74 | 75 | /** 76 | * {@inheritDoc} 77 | */ 78 | @Override 79 | public void write(byte b[], int off, int len) throws IOException { 80 | this.ops.incr(); 81 | this.total.add(len * 8); 82 | 83 | this.base.write(b, off, len); 84 | } 85 | 86 | @Override 87 | public void flush() throws IOException { 88 | this.base.flush(); 89 | } 90 | 91 | /** 92 | * {@inheritDoc} 93 | */ 94 | @Override 95 | public void close() throws IOException { 96 | Stream.safeClose(base); 97 | } 98 | 99 | } // (class) 100 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/websockets/CloseCode.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.websockets; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Websocket 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | public enum CloseCode { 37 | NormalClosure(1000), 38 | GoingAway(1001), 39 | ProtocolError(1002), 40 | UnsupportedData(1003), 41 | NoStatusRcvd(1005), 42 | AbnormalClosure(1006), 43 | InvalidFramePayloadData(1007), 44 | PolicyViolation(1008), 45 | MessageTooBig(1009), 46 | MandatoryExt(1010), 47 | InternalServerError(1011), 48 | TLSHandshake(1015); 49 | 50 | public static CloseCode find(int value) { 51 | for (CloseCode code : values()) { 52 | if (code.getValue() == value) { 53 | return code; 54 | } 55 | } 56 | return null; 57 | } 58 | 59 | private final int code; 60 | 61 | private CloseCode(int code) { 62 | this.code = code; 63 | } 64 | 65 | public int getValue() { 66 | return this.code; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/tempfiles/DefaultTempFileManagerFactory.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.tempfiles; 2 | 3 | /* 4 | * ALTERED FROM ORIGINAL 5 | * 6 | * #%L 7 | * NanoHttpd-Core 8 | * %% 9 | * Copyright (C) 2012 - 2016 nanohttpd 10 | * %% 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, this 15 | * list of conditions and the following disclaimer. 16 | * 17 | * 2. Redistributions in binary form must reproduce the above copyright notice, 18 | * this list of conditions and the following disclaimer in the documentation 19 | * and/or other materials provided with the distribution. 20 | * 21 | * 3. Neither the name of the nanohttpd nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software without 23 | * specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 29 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 33 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 34 | * OF THE POSSIBILITY OF SUCH DAMAGE. 35 | * #L% 36 | */ 37 | 38 | import org.nanohttpd.util.IFactory; 39 | 40 | import java.io.File; 41 | 42 | /** 43 | * Default strategy for creating and cleaning up temporary files. 44 | */ 45 | public class DefaultTempFileManagerFactory implements IFactory { 46 | 47 | /** 48 | * (not original) 49 | */ 50 | private final File _tmpdir; 51 | 52 | /** 53 | * (different from original nanohttpd code, only checking temporary folder existence once, ) 54 | */ 55 | public DefaultTempFileManagerFactory() { 56 | _tmpdir = new File(System.getProperty("java.io.tmpdir")); 57 | if (!_tmpdir.exists()) 58 | _tmpdir.mkdirs(); 59 | } 60 | 61 | @Override 62 | public ITempFileManager create() { 63 | return new DefaultTempFileManager(_tmpdir); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/core/NodeAddress.java: -------------------------------------------------------------------------------- 1 | package org.nodel.core; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | /** 10 | * Deals with equality, etc. for Node addresses for use in Map, Lists, etc. 11 | * 12 | * 'InetSocketAddress' was not suitable as it deals with address resolution which 13 | * is dealt with in other parts of Nodel. 14 | */ 15 | public class NodeAddress { 16 | 17 | /** 18 | * Represents an in-process node. 19 | */ 20 | public final static NodeAddress IN_PROCESS = new NodeAddress("internal", 0); 21 | 22 | /** 23 | * (see 'getHost()') 24 | */ 25 | private String _host; 26 | 27 | /** 28 | * (see 'getPort()') 29 | */ 30 | private int _port; 31 | 32 | /** 33 | * (see 'getPort()') 34 | */ 35 | private String _reducedHost; 36 | 37 | /** 38 | * (private constructor) 39 | */ 40 | private NodeAddress(String host, int port) { 41 | if (host == null) 42 | throw new IllegalArgumentException("Host cannot be null"); 43 | 44 | if (port < 0 || port > 0xFFFF) 45 | throw new IllegalArgumentException("Port out of range - " + port); 46 | 47 | _host = host; 48 | _port = port; 49 | 50 | _reducedHost = host.trim().toLowerCase(); 51 | } 52 | 53 | /** 54 | * Creates a new Nodel address. 55 | */ 56 | public static NodeAddress create(String host, int port) { 57 | return new NodeAddress(host, port); 58 | } // (method) 59 | 60 | /** 61 | * Returns the host part. 62 | */ 63 | public String getHost() { 64 | return _host; 65 | } 66 | 67 | /** 68 | * Returns the port part. 69 | */ 70 | public int getPort() { 71 | return _port; 72 | } 73 | 74 | @Override 75 | public boolean equals(Object obj) { 76 | if (obj == null || !(obj instanceof NodeAddress)) 77 | return false; 78 | 79 | NodeAddress other = (NodeAddress) obj; 80 | 81 | return _reducedHost.equals(other._reducedHost) && _port == other._port; 82 | } // (method) 83 | 84 | @Override 85 | public int hashCode() { 86 | return _reducedHost.hashCode() ^ _port; 87 | } // (method) 88 | 89 | /** 90 | * Returns the reduced version of the name. 91 | */ 92 | public String toString() { 93 | return String.format("\"%s:%s\"", _reducedHost, _port); 94 | } 95 | 96 | } // (class) 97 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/webserver/InternalRewrite.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.webserver; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Webserver 6 | * %% 7 | * Copyright (C) 2012 - 2015 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | import java.io.ByteArrayInputStream; 37 | import java.util.Map; 38 | 39 | import org.nanohttpd.protocols.http.NanoHTTPD; 40 | import org.nanohttpd.protocols.http.response.Response; 41 | import org.nanohttpd.protocols.http.response.Status; 42 | 43 | /** 44 | * @author Paul S. Hawke (paul.hawke@gmail.com) On: 9/15/13 at 2:52 PM 45 | */ 46 | public class InternalRewrite extends Response { 47 | 48 | private final String uri; 49 | 50 | private final Map headers; 51 | 52 | public InternalRewrite(Map headers, String uri) { 53 | super(Status.OK, NanoHTTPD.MIME_HTML, new ByteArrayInputStream(new byte[0]), 0); 54 | this.headers = headers; 55 | this.uri = uri; 56 | } 57 | 58 | public Map getHeaders() { 59 | return this.headers; 60 | } 61 | 62 | public String getUri() { 63 | return this.uri; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/websockets/WebSocketException.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.websockets; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Websocket 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | import java.io.IOException; 37 | 38 | public class WebSocketException extends IOException { 39 | 40 | private static final long serialVersionUID = 1L; 41 | 42 | private final CloseCode code; 43 | 44 | private final String reason; 45 | 46 | public WebSocketException(CloseCode code, String reason) { 47 | this(code, reason, null); 48 | } 49 | 50 | public WebSocketException(CloseCode code, String reason, Exception cause) { 51 | super(code + ": " + reason, cause); 52 | this.code = code; 53 | this.reason = reason; 54 | } 55 | 56 | public WebSocketException(Exception cause) { 57 | this(CloseCode.InternalServerError, cause.toString(), cause); 58 | } 59 | 60 | public CloseCode getCode() { 61 | return this.code; 62 | } 63 | 64 | public String getReason() { 65 | return this.reason; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/json/HTTPTokener.java: -------------------------------------------------------------------------------- 1 | package org.nodel.json; 2 | 3 | /* 4 | Copyright (c) 2002 JSON.org 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | The Software shall be used for Good, not Evil. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | */ 26 | 27 | /** 28 | * The HTTPTokener extends the JSONTokener to provide additional methods 29 | * for the parsing of HTTP headers. 30 | * @author JSON.org 31 | * @version 2012-11-13 32 | */ 33 | public class HTTPTokener extends JSONTokener { 34 | 35 | /** 36 | * Construct an HTTPTokener from a string. 37 | * @param string A source string. 38 | */ 39 | public HTTPTokener(String string) { 40 | super(string); 41 | } 42 | 43 | 44 | /** 45 | * Get the next token or string. This is used in parsing HTTP headers. 46 | * @throws JSONException 47 | * @return A String. 48 | */ 49 | public String nextToken() throws JSONException { 50 | char c; 51 | char q; 52 | StringBuffer sb = new StringBuffer(); 53 | do { 54 | c = next(); 55 | } while (Character.isWhitespace(c)); 56 | if (c == '"' || c == '\'') { 57 | q = c; 58 | for (;;) { 59 | c = next(); 60 | if (c < ' ') { 61 | throw syntaxError("Unterminated string."); 62 | } 63 | if (c == q) { 64 | return sb.toString(); 65 | } 66 | sb.append(c); 67 | } 68 | } 69 | for (;;) { 70 | if (c == 0 || Character.isWhitespace(c)) { 71 | return sb.toString(); 72 | } 73 | sb.append(c); 74 | c = next(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /nodel-jyhost/src/main/resources/org/nodel/jyhost/first_node.py: -------------------------------------------------------------------------------- 1 | '''This node pulls down the latest offical Nodel recipes. It is automatically created for convenience on first run and can be safely deleted or disabled once in production. Please see console and script for more information.''' 2 | 3 | GREETING = ''' 4 | 5 | This node clones the official nodel-recipes repository at: 6 | - github.com/museumsvictoria/github 7 | 8 | Once cloned, new nodes can be easily created or updated based on the latest recipes. 9 | 10 | Deleting this node does not delete the actual recipes repository. 11 | 12 | This node will refresh the recipes repository every 72 hours (differences only). 13 | 14 | ''' 15 | 16 | console.warn(GREETING) 17 | 18 | from org.nodel.jyhost import NodelHost 19 | from org.eclipse.jgit.api import Git 20 | from java.io import File 21 | 22 | DEFAULT_NAME = "nodel-official-recipes" 23 | DEFAULT_URI = "https://github.com/museumsvictoria/nodel-recipes" 24 | param_repository = Parameter({'title': 'Repository', 'schema': {'type': 'object', 'properties': { 25 | 'name': {'type': 'string', 'hint': DEFAULT_NAME, 'order': 1}, 26 | 'uri': {'type': 'string', 'hint': DEFAULT_URI, 'order': 2}}}}) 27 | 28 | # sync every 72 hours, first after 10 seconds 29 | Timer(lambda: lookup_local_action("SyncNow").call(), 72*3600, 10) 30 | 31 | # the internet address 32 | uri = DEFAULT_URI 33 | 34 | # the nodel-recipes repo folder 35 | folder = File(NodelHost.instance().recipes().getRoot(), DEFAULT_NAME) 36 | 37 | def main(): 38 | if param_repository != None: 39 | global uri, folder 40 | 41 | uri = param_repository.get('uri') or DEFAULT_URI 42 | name = param_repository.get('name') or DEFAULT_NAME 43 | folder = File(NodelHost.instance().recipes().getRoot(), name) 44 | 45 | console.info('Clone and pull folder: "%s"' % folder.getAbsolutePath()) 46 | 47 | def local_action_SyncNow(arg=None): 48 | sync() 49 | 50 | def sync(): 51 | clone_if_necessary() 52 | pull() 53 | 54 | def clone_if_necessary(): 55 | if folder.exists(): 56 | return 57 | 58 | console.info("Cloning %s..." % uri) 59 | 60 | try: 61 | git = None 62 | 63 | cmd = Git.cloneRepository() 64 | cmd.setURI(uri) 65 | cmd.setDirectory(folder) 66 | git = cmd.call() 67 | 68 | console.info("Cloning finished") 69 | 70 | finally: 71 | if git != None: git.close() 72 | 73 | def pull(): 74 | if not folder.exists(): 75 | console.warn('repo folder does not exist; yet to clone or network issues?') 76 | 77 | console.info("Pulling repository...") 78 | 79 | try: 80 | git = None 81 | git = Git.open(folder) 82 | git.pull().call() 83 | 84 | console.info("Pull finished") 85 | 86 | finally: 87 | if git != None: git.close() 88 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/diagnostics/CountableInputStream.java: -------------------------------------------------------------------------------- 1 | package org.nodel.diagnostics; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | 12 | import org.nodel.io.Stream; 13 | 14 | /** 15 | * Allows for data counting of underlying stream. 16 | */ 17 | public class CountableInputStream extends InputStream { 18 | 19 | private SharableMeasurementProvider total; 20 | 21 | private SharableMeasurementProvider ops; 22 | 23 | private InputStream base; 24 | 25 | public CountableInputStream(InputStream base, SharableMeasurementProvider ops, SharableMeasurementProvider total) { 26 | this.base = base; 27 | this.ops = ops; 28 | this.total = total; 29 | } // (init) 30 | 31 | /** 32 | * The total amount of data written. 33 | */ 34 | public long getTotal() { 35 | return this.total.getMeasurement(); 36 | } 37 | 38 | /** 39 | * Records the number of write operations 40 | */ 41 | public long getOps() { 42 | return this.ops.getMeasurement(); 43 | } 44 | 45 | /** 46 | * The underlying stream. 47 | */ 48 | public InputStream getBase() { 49 | return this.base; 50 | } 51 | 52 | /** 53 | * {@inheritDoc} 54 | */ 55 | @Override 56 | public int read() throws IOException { 57 | this.ops.incr(); 58 | 59 | int b = base.read(); 60 | 61 | if (b >= 0) 62 | this.total.add(8); 63 | 64 | return b; 65 | } 66 | 67 | /** 68 | * {@inheritDoc} 69 | */ 70 | @Override 71 | public int read(byte b[]) throws IOException { 72 | this.ops.incr(); 73 | 74 | int count = base.read(b); 75 | 76 | if (count > 0) 77 | this.total.add(count); 78 | 79 | return count; 80 | } 81 | 82 | /** 83 | * {@inheritDoc} 84 | */ 85 | @Override 86 | public int read(byte b[], int off, int len) throws IOException { 87 | this.ops.incr(); 88 | 89 | int count = base.read(b, off, len); 90 | 91 | if (count > 0) 92 | this.total.add(count * 8); 93 | 94 | return count; 95 | } 96 | 97 | /** 98 | * {@inheritDoc} 99 | */ 100 | @Override 101 | public void close() throws IOException { 102 | Stream.safeClose(base); 103 | } 104 | 105 | } // (class) 106 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/UUIDs.java: -------------------------------------------------------------------------------- 1 | package org.nodel; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.util.UUID; 10 | 11 | public class UUIDs { 12 | 13 | /** 14 | * Takes a normal UUID string or URL friendly/compressed string. 15 | */ 16 | public static UUID fromString(String str) { 17 | UUID result; 18 | 19 | if (str.indexOf('-') >= 0) { 20 | // normal UUID format 21 | result = UUID.fromString(str); 22 | 23 | } else { 24 | // compressed UUID format 25 | 26 | // pad if necessary 27 | int delta = (3 - str.length() % 3); 28 | 29 | String rawbase64; 30 | if (delta == 1) 31 | rawbase64 = str + "="; 32 | else if (delta == 2) 33 | rawbase64 = str + "=="; 34 | else 35 | rawbase64 = str; 36 | 37 | // replace URL friendly codes 38 | rawbase64.replace('-', '+'); 39 | rawbase64.replace('_', '/'); 40 | 41 | byte[] binaryUUID = Base64.decode(rawbase64); 42 | if (binaryUUID.length != 16) 43 | throw new IllegalArgumentException("UUID is not exactly 16 bytes"); 44 | 45 | result = uuidFromBytes(binaryUUID); 46 | } 47 | 48 | return result; 49 | } // (method) 50 | 51 | /** 52 | * Returns a compressed and URL friendly string for a UUID. 53 | */ 54 | public static String toCompressedString(UUID uuid) { 55 | long msb = uuid.getMostSignificantBits(); 56 | long lsb = uuid.getLeastSignificantBits(); 57 | 58 | byte[] data = new byte[16]; 59 | 60 | for (int a = 7; a >= 0; a--) { 61 | data[a] = (byte) (msb & 0xff); 62 | msb >>>= 8; 63 | } // (for) 64 | 65 | for (int a = 15; a >= 8; a--) { 66 | data[a] = (byte) (lsb & 0xff); 67 | lsb >>>= 8; 68 | } // (for) 69 | 70 | String rawbase64 = Base64.encode(data); 71 | 72 | // drop the padding ('==') 73 | // and use URL friendly characters 74 | rawbase64 = rawbase64.substring(0, rawbase64.length() - 2); 75 | rawbase64.replace('+', '-'); 76 | rawbase64.replace('/', '_'); 77 | 78 | return rawbase64; 79 | } // (method) 80 | 81 | private static UUID uuidFromBytes(byte[] data) { 82 | long msb = 0; 83 | long lsb = 0; 84 | 85 | for (int i = 0; i < 8; i++) 86 | msb = (msb << 8) | (data[i] & 0xff); 87 | for (int i = 8; i < 16; i++) 88 | lsb = (lsb << 8) | (data[i] & 0xff); 89 | 90 | UUID result = new UUID(msb, lsb); 91 | return result; 92 | } // (method) 93 | 94 | } // (class) 95 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/reflection/Value.java: -------------------------------------------------------------------------------- 1 | package org.nodel.reflection; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.lang.annotation.ElementType; 10 | import java.lang.annotation.Retention; 11 | import java.lang.annotation.RetentionPolicy; 12 | import java.lang.annotation.Target; 13 | 14 | /** 15 | * An annotation used to represent JSON fields 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target({ElementType.FIELD, ElementType.METHOD}) 19 | public @interface Value { 20 | 21 | /** 22 | * The strict name/id/alias to use for the value. 23 | */ 24 | public String name(); 25 | 26 | /** 27 | * A short title for the value. 28 | */ 29 | public String title() default ""; 30 | 31 | /** 32 | * The field order. 33 | */ 34 | public double order() default 0; 35 | 36 | /** 37 | * Is the default value for a given class. 38 | */ 39 | public boolean treatAsDefaultValue() default false; 40 | 41 | /** 42 | * Options or allowed / suggested values. 43 | */ 44 | public String[] suggestions() default {}; 45 | 46 | /** 47 | * Options or allowed / suggested values. 48 | */ 49 | public String desc() default ""; 50 | 51 | /** 52 | * Required field? 53 | */ 54 | public boolean required() default true; 55 | 56 | /** 57 | * Whether or not this is considered an advanced field. 58 | */ 59 | public boolean advanced() default false; 60 | 61 | /** 62 | * Holds if generics are being used. 63 | * 'Type A' would apply to Lists and Map keys. 64 | */ 65 | public Class genericClassA() default Object.class; 66 | 67 | /** 68 | * Holds if generics are being used. 69 | * 'Type B' would apply to Map values. 70 | */ 71 | public Class genericClassB() default Object.class; 72 | 73 | /** 74 | * Don't expose this field in schema views. 75 | * 76 | * @return 77 | */ 78 | public boolean hidden() default false; 79 | 80 | /** 81 | * The MIME type for the value. 82 | * TODO: reserved only; not supported 83 | */ 84 | public String contentType() default ""; 85 | 86 | /** 87 | * Allows the 'format' to be overridden. 88 | */ 89 | public String format() default ""; 90 | 91 | /** 92 | * For arrays, the minimum number of items allowed OR -1 for any number. 93 | */ 94 | public int minItems() default -1; 95 | 96 | /** 97 | * For arrays, the maximum number of items allowed OR -1 for any number. 98 | */ 99 | public int maxItems() default -1; 100 | 101 | } // (class) 102 | -------------------------------------------------------------------------------- /nodel-jyhost/src/main/java/org/slf4j/impl/JDK14LoggingHandler.java: -------------------------------------------------------------------------------- 1 | package org.slf4j.impl; 2 | 3 | import java.io.InputStream; 4 | import java.util.logging.FileHandler; 5 | import java.util.logging.Handler; 6 | import java.util.logging.Level; 7 | import java.util.logging.LogManager; 8 | import java.util.logging.LogRecord; 9 | 10 | import org.nodel.io.Stream; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | /** 15 | * Funnels all legacy Java logging (java.util.logging) through to the SLF logger. 16 | */ 17 | public class JDK14LoggingHandler extends Handler { 18 | 19 | FileHandler _fileHandler; 20 | 21 | private static Logger s_logger = LoggerFactory.getLogger("jdk14_logging"); 22 | 23 | public JDK14LoggingHandler() { 24 | s_logger.info("java.util.logging framework activity present; DEBUG level filtering"); 25 | } 26 | 27 | @Override 28 | public void publish(LogRecord record) { 29 | // must be DEBUG or finer 30 | if (!s_logger.isDebugEnabled()) 31 | return; 32 | 33 | Throwable th = record.getThrown(); 34 | 35 | Level level = record.getLevel(); 36 | 37 | String comment = String.format("%s [%s] %s", level, record.getLoggerName(), record.getMessage()); 38 | 39 | int intLevel = level.intValue(); 40 | 41 | if (intLevel <= Level.FINE.intValue()) { 42 | if (th == null) 43 | s_logger.debug(comment); 44 | else 45 | s_logger.debug(comment, th); 46 | } else if (intLevel <= Level.INFO.intValue()) { 47 | if (th == null) 48 | s_logger.info(comment); 49 | else 50 | s_logger.info(comment, th); 51 | } else if (intLevel <= Level.WARNING.intValue()) { 52 | if (th == null) 53 | s_logger.warn(comment); 54 | else 55 | s_logger.warn(comment, th); 56 | } else { 57 | if (th == null) 58 | s_logger.error(comment); 59 | else 60 | s_logger.error(comment, th); 61 | } 62 | } 63 | 64 | @Override 65 | public void flush() { 66 | // nothing to do 67 | } 68 | 69 | @Override 70 | public void close() throws SecurityException { 71 | // nothing to do 72 | } 73 | 74 | /** 75 | * Relates to java.util.logging framework 76 | */ 77 | public static void init() { 78 | InputStream is = null; 79 | 80 | try { 81 | is = JDK14LoggingHandler.class.getResourceAsStream("jdk14_logging.properties"); 82 | LogManager.getLogManager().readConfiguration(is); 83 | 84 | } catch (Exception exc) { 85 | s_logger.warn("Could not initialise java.util.logging framework", exc); 86 | 87 | } finally { 88 | Stream.safeClose(is); 89 | } 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/response/ChunkedOutputStream.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.response; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | import java.io.FilterOutputStream; 37 | import java.io.IOException; 38 | import java.io.OutputStream; 39 | 40 | /** 41 | * Output stream that will automatically send every write to the wrapped 42 | * OutputStream according to chunked transfer: 43 | * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1 44 | */ 45 | public class ChunkedOutputStream extends FilterOutputStream { 46 | 47 | public ChunkedOutputStream(OutputStream out) { 48 | super(out); 49 | } 50 | 51 | @Override 52 | public void write(int b) throws IOException { 53 | byte[] data = { 54 | (byte) b 55 | }; 56 | write(data, 0, 1); 57 | } 58 | 59 | @Override 60 | public void write(byte[] b) throws IOException { 61 | write(b, 0, b.length); 62 | } 63 | 64 | @Override 65 | public void write(byte[] b, int off, int len) throws IOException { 66 | if (len == 0) 67 | return; 68 | out.write(String.format("%x\r\n", len).getBytes()); 69 | out.write(b, off, len); 70 | out.write("\r\n".getBytes()); 71 | } 72 | 73 | public void finish() throws IOException { 74 | out.write("0\r\n\r\n".getBytes()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/discovery/NameServicesChannelMessage.java: -------------------------------------------------------------------------------- 1 | package org.nodel.discovery; 2 | 3 | import java.net.DatagramPacket; 4 | import java.net.SocketAddress; 5 | 6 | /* 7 | * This Source Code Form is subject to the terms of the Mozilla Public 8 | * License, v. 2.0. If a copy of the MPL was not distributed with this 9 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 10 | */ 11 | 12 | import java.util.List; 13 | 14 | import org.nodel.io.UTF8Charset; 15 | import org.nodel.reflection.Serialisation; 16 | import org.nodel.reflection.Value; 17 | 18 | /** 19 | * The simple packet that is used in multicast discovery. 20 | */ 21 | public class NameServicesChannelMessage { 22 | 23 | /** 24 | * (client to server) 25 | * Indicates a discovery is wanting to be made, listing the nodes using pattern matching e.g. '*' for everything. 26 | */ 27 | @Value(name = "discovery", genericClassA = String.class, order = 1) 28 | public List discovery; 29 | 30 | /** 31 | * (client to server) 32 | * Indicates the types requested as part of the discovery. 33 | */ 34 | @Value(name = "type", genericClassA = String.class, order = 2) 35 | public List types; 36 | 37 | /** 38 | * (server to client) 39 | * Indicates the nodes that are present. 40 | */ 41 | @Value(name = "present", genericClassA = String.class, order = 3) 42 | public List present; 43 | 44 | /** 45 | * (server to client) 46 | * Indicates the addresses of all the node listed in 'present' field. 47 | */ 48 | @Value(name = "addresses", genericClassA = String.class, order = 4) 49 | public List addresses; 50 | 51 | /** 52 | * Holds the agent in use, e.g. 'Nodel-v2-javawindows'. 53 | * (optional) 54 | * (server to client) 55 | * (client to server) 56 | */ 57 | @Value(name = "agent", order = 5) 58 | public String agent; 59 | 60 | /** 61 | * (server to client) 62 | * Used to stagger responses. 63 | */ 64 | @Value(name = "delay", order = 6) 65 | public Integer delay; 66 | 67 | @Override 68 | public String toString() { 69 | return Serialisation.serialise(this); 70 | } 71 | 72 | /** 73 | * Converts into a packet. 74 | */ 75 | public DatagramPacket intoPacket(SocketAddress to) { 76 | byte[] bytes = Serialisation.serialise(this).getBytes(UTF8Charset.instance()); 77 | 78 | DatagramPacket packet = new DatagramPacket(bytes, bytes.length); 79 | packet.setSocketAddress(to); 80 | 81 | return packet; 82 | } 83 | 84 | /** 85 | * Constructs from a DatagramPacket. 86 | */ 87 | public static NameServicesChannelMessage fromPacket(DatagramPacket dp) { 88 | String packetString = new String(dp.getData(), 0, dp.getLength(), UTF8Charset.instance()); 89 | 90 | return (NameServicesChannelMessage) Serialisation.coerceFromJSON(NameServicesChannelMessage.class, packetString); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /toolkit-util/ProcessSandbox/ProcessSandbox.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A2FE9439-1523-48AD-8316-A091E1F95559} 8 | Exe 9 | Properties 10 | ProcessSandbox 11 | ProcessSandbox 12 | v4.0 13 | 512 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | ProcessSandbox.Program 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/core/ChannelMessage.java: -------------------------------------------------------------------------------- 1 | package org.nodel.core; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.util.Map; 10 | 11 | import org.nodel.reflection.Serialisation; 12 | import org.nodel.reflection.Value; 13 | 14 | /** 15 | * Represents a nodel message within a nodel channel. 16 | */ 17 | public class ChannelMessage { 18 | 19 | /** 20 | * FROM SERVER: The node this message is being addressed to. 21 | * FROM CLIENT: The node this message originated from. 22 | */ 23 | @Value(name = "node", order = 1) 24 | public String node; 25 | 26 | /** 27 | * FROM SERVER: The node's events registered to listen to in the channel. 28 | * FROM CLIENT: The node's events registered to listen to in the channel. 29 | */ 30 | @Value(name = "events", order = 4) 31 | public String[] events; 32 | 33 | /** 34 | * FROM CLIENT: Registering for interests (actions) 35 | * FROM SERVER: The actions 36 | */ 37 | @Value(name = "actions", order = 3) 38 | public String[] actions; 39 | 40 | /** 41 | * Node's self, its actions' and events' schema 42 | */ 43 | public Map schema; 44 | 45 | /** 46 | * The action to call. 47 | * (client req.) 48 | */ 49 | @Value(name = "action", order = 6) 50 | public String action; 51 | 52 | /** 53 | * A provide argument 54 | * (client req. or server resp.) 55 | */ 56 | @Value(name = "arg", order = 7) 57 | public Object arg; 58 | 59 | /** 60 | * The event that occurred 61 | * (server resp.) 62 | */ 63 | @Value(name = "event", order = 8) 64 | public String event; 65 | 66 | public enum Announcement { 67 | Moved 68 | } 69 | 70 | /** 71 | * General purpose (non error) announcements e.g. "Moved" 72 | */ 73 | @Value(name = "announcement", order = 8.5) 74 | public Announcement announcement; 75 | 76 | /** 77 | * A short error category. 78 | * (server resp.) 79 | */ 80 | @Value(name = "error", order = 9) 81 | public String error; 82 | 83 | /** 84 | * Reveals all nodes within this channel. 85 | * e.g. '*' reveal all 86 | * (client req.) 87 | */ 88 | @Value(name = "reveal", order = 12) 89 | public String[] reveal; 90 | 91 | /** 92 | * (used by 'toString()') 93 | */ 94 | private String string; 95 | 96 | /** 97 | * Returns a JSON-formatted version of this message. 98 | */ 99 | public String toString() { 100 | if (this.string == null) 101 | this.string = Serialisation.serialise(this); 102 | 103 | return this.string; 104 | } 105 | 106 | } // (class) 107 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/util/ServerRunner.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.util; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Webserver 6 | * %% 7 | * Copyright (C) 2012 - 2015 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | import java.io.IOException; 37 | import java.util.logging.Level; 38 | import java.util.logging.Logger; 39 | 40 | import org.nanohttpd.protocols.http.NanoHTTPD; 41 | 42 | public class ServerRunner { 43 | 44 | /** 45 | * logger to log to. 46 | */ 47 | private static final Logger LOG = Logger.getLogger(ServerRunner.class.getName()); 48 | 49 | public static void executeInstance(NanoHTTPD server) { 50 | try { 51 | server.start(NanoHTTPD.SOCKET_READ_TIMEOUT, false); 52 | } catch (IOException ioe) { 53 | System.err.println("Couldn't start server:\n" + ioe); 54 | System.exit(-1); 55 | } 56 | System.out.println("Listening to " + server.getListeningPort()); 57 | System.out.println("Server started, Hit Enter to stop.\n"); 58 | 59 | try { 60 | System.in.read(); 61 | } catch (Throwable ignored) { 62 | } 63 | 64 | server.stop(); 65 | System.out.println("Server stopped.\n"); 66 | } 67 | 68 | public static void run(Class serverClass) { 69 | try { 70 | executeInstance(serverClass.newInstance()); 71 | } catch (Exception e) { 72 | ServerRunner.LOG.log(Level.SEVERE, "Could not create server", e); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /nodel-jyhost/src/main/java/org/nodel/jyhost/ExamplePySp.java: -------------------------------------------------------------------------------- 1 | package org.nodel.jyhost; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.io.PrintWriter; 10 | import java.io.StringWriter; 11 | 12 | public class ExamplePySp { 13 | 14 | /** 15 | * Generate an example script file. 16 | */ 17 | public static String generateExamplePage() { 18 | StringWriter sw = new StringWriter(); 19 | PrintWriter pw = new PrintWriter(sw); 20 | 21 | // embed version info 22 | pw.format("<%%\r\n# Nodel auto-generated example PySp (server-side script) that applies to version v%s or later.%n%%>", Launch.VERSION); 23 | pw.println(""); 24 | pw.println(""); 25 | pw.println(""); 26 | pw.println(""); 27 | pw.println("

    Raw node name is <%= _node.getName() %>."); 28 | pw.println(); 29 | pw.println("

    HTML friendly node description is <%# _node.getDesc() %>."); 30 | pw.println(); 31 | pw.println("

    ipAddress parameter is <%# param_ipAddress %>."); 32 | pw.println(); 33 | pw.println("

    Useful Python variables

    "); 34 | pw.println(); 35 | pw.println("

    _ctx.req() attributes:"); 36 | pw.println("

      "); 37 | pw.println("<%"); 38 | pw.println("for x in dir(_ctx.req()):"); 39 | pw.println(" if '__' not in x: %>
    • <%# x %>
    • "); 40 | pw.println("<%"); 41 | pw.println("%>"); 42 | pw.println("
    "); 43 | pw.println(); 44 | pw.println("

    _ctx.resp() attributes:"); 45 | pw.println("

      "); 46 | pw.println("<%"); 47 | pw.println("for x in dir(_ctx.resp()):"); 48 | pw.println(" if '__' not in x: %>
    • <%# x %>
    • "); 49 | pw.println("<%"); 50 | pw.println("%>"); 51 | pw.println("
    "); 52 | pw.println("

    locals attributes:"); 53 | pw.println("

      "); 54 | pw.println("<%"); 55 | pw.println("for x in dir(locals):"); 56 | pw.println(" if '__' not in x: %>
    • <%# x %>
    • "); 57 | pw.println("<%"); 58 | pw.println("%>"); 59 | pw.println("
    "); 60 | pw.println(); 61 | pw.println("

    _node attributes:"); 62 | pw.println("

      "); 63 | pw.println("<%"); 64 | pw.println("for x in dir(_node):"); 65 | pw.println(" if '__' not in x: %>
    • <%# x %>
    • "); 66 | pw.println("<%"); 67 | pw.println("%>"); 68 | pw.println("
    "); 69 | pw.println(); 70 | pw.println("

    _pysp is (can use '?_dump' querystring):
    "); 71 | pw.println("

    <%# _pysp %>
    "); 72 | pw.println(""); 73 | pw.println(""); 74 | 75 | return sw.toString(); 76 | } // (method) 77 | 78 | } 79 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/tempfiles/DefaultTempFile.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.tempfiles; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | import java.io.File; 37 | import java.io.FileOutputStream; 38 | import java.io.IOException; 39 | import java.io.OutputStream; 40 | 41 | import org.nanohttpd.protocols.http.NanoHTTPD; 42 | 43 | /** 44 | * Default strategy for creating and cleaning up temporary files. 45 | *

    46 | *

    47 | * By default, files are created by File.createTempFile() in the 48 | * directory specified. 49 | *

    50 | */ 51 | public class DefaultTempFile implements ITempFile { 52 | 53 | private final File file; 54 | 55 | private final OutputStream fstream; 56 | 57 | public DefaultTempFile(File tempdir) throws IOException { 58 | this.file = File.createTempFile("NanoHTTPD-", "", tempdir); 59 | this.fstream = new FileOutputStream(this.file); 60 | } 61 | 62 | @Override 63 | public void delete() throws Exception { 64 | NanoHTTPD.safeClose(this.fstream); 65 | if (!this.file.delete()) { 66 | throw new Exception("could not delete temporary file: " + this.file.getAbsolutePath()); 67 | } 68 | } 69 | 70 | @Override 71 | public String getName() { 72 | return this.file.getAbsolutePath(); 73 | } 74 | 75 | @Override 76 | public OutputStream open() throws Exception { 77 | return this.fstream; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/sockets/SecureServerSocketFactory.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.sockets; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | import java.io.IOException; 37 | import java.net.ServerSocket; 38 | 39 | import javax.net.ssl.SSLServerSocket; 40 | import javax.net.ssl.SSLServerSocketFactory; 41 | 42 | import org.nanohttpd.util.IFactoryThrowing; 43 | 44 | /** 45 | * Creates a new SSLServerSocket 46 | */ 47 | public class SecureServerSocketFactory implements IFactoryThrowing { 48 | 49 | private SSLServerSocketFactory sslServerSocketFactory; 50 | 51 | private String[] sslProtocols; 52 | 53 | public SecureServerSocketFactory(SSLServerSocketFactory sslServerSocketFactory, String[] sslProtocols) { 54 | this.sslServerSocketFactory = sslServerSocketFactory; 55 | this.sslProtocols = sslProtocols; 56 | } 57 | 58 | @Override 59 | public ServerSocket create() throws IOException { 60 | SSLServerSocket ss = null; 61 | ss = (SSLServerSocket) this.sslServerSocketFactory.createServerSocket(); 62 | if (this.sslProtocols != null) { 63 | ss.setEnabledProtocols(this.sslProtocols); 64 | } else { 65 | ss.setEnabledProtocols(ss.getSupportedProtocols()); 66 | } 67 | ss.setUseClientMode(false); 68 | ss.setWantClientAuth(false); 69 | ss.setNeedClientAuth(false); 70 | return ss; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nodel/discovery/UDPPacketRecycleQueue.java: -------------------------------------------------------------------------------- 1 | package org.nodel.discovery; 2 | 3 | /* 4 | * This Source Code Form is subject to the terms of the Mozilla Public 5 | * License, v. 2.0. If a copy of the MPL was not distributed with this 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 | */ 8 | 9 | import java.net.DatagramPacket; 10 | import java.util.concurrent.ConcurrentLinkedQueue; 11 | import java.util.concurrent.atomic.AtomicInteger; 12 | 13 | import org.nodel.Threads; 14 | 15 | /** 16 | * Used as a singleton to recycle memory hungry UDP packets / buffers 17 | */ 18 | public class UDPPacketRecycleQueue { 19 | 20 | private final static int PACKET_LENGTH = 65536; 21 | 22 | /** 23 | * The maximum number of packets to keep in this queue to avoid large memory 24 | * allocation that cannot be garbage collected. 25 | * 26 | * (roughly equals number of threads that'd be using the queue) 27 | */ 28 | private final static int MAX_PACKETS = 64; 29 | 30 | /** 31 | * Keeps track of the number of packets created (without using locks); 32 | */ 33 | private AtomicInteger _packetsCounter = new AtomicInteger(); 34 | 35 | /** 36 | * A fast lock-less queue 37 | */ 38 | private ConcurrentLinkedQueue _queue = new ConcurrentLinkedQueue(); 39 | 40 | /** 41 | * See 'instance()' 42 | */ 43 | private UDPPacketRecycleQueue() { 44 | } 45 | 46 | /** 47 | * Returns a ready-to-use packet. 48 | */ 49 | public DatagramPacket getReadyToUsePacket() { 50 | // 'poll' actually removes a packet or returns null if none available 51 | DatagramPacket packet = _queue.poll(); 52 | 53 | if (packet == null) { 54 | int count = _packetsCounter.incrementAndGet(); 55 | 56 | // make sure we haven't created too many packets 57 | // (lock-less) 58 | if (count > MAX_PACKETS) { 59 | _packetsCounter.decrementAndGet(); 60 | 61 | while (packet == null) { 62 | // highly unexpected situation so just 63 | // spin while we wait for packets to come back 64 | Threads.sleep(200); 65 | 66 | packet = _queue.poll(); 67 | } 68 | } else { 69 | // create a new one and return it 70 | byte[] buffer = new byte[PACKET_LENGTH]; 71 | packet = new DatagramPacket(buffer, PACKET_LENGTH); 72 | 73 | return packet; 74 | } 75 | } 76 | 77 | // reset the packet length field of a pre-created packet 78 | packet.setLength(PACKET_LENGTH); 79 | 80 | return packet; 81 | } 82 | 83 | /** 84 | * Releases a packet back into the recycle queue. 85 | */ 86 | public void returnPacket(DatagramPacket packet) { 87 | _queue.offer(packet); 88 | } 89 | 90 | /** 91 | * (singleton, thread-safe, non-blocking) 92 | */ 93 | private static class Instance { 94 | 95 | private static final UDPPacketRecycleQueue INSTANCE = new UDPPacketRecycleQueue(); 96 | 97 | } 98 | 99 | /** 100 | * Returns the singleton instance of this class. 101 | */ 102 | public static UDPPacketRecycleQueue instance() { 103 | return Instance.INSTANCE; 104 | } 105 | 106 | } // (class) 107 | -------------------------------------------------------------------------------- /nodel-framework/src/main/java/org/nanohttpd/protocols/http/content/Cookie.java: -------------------------------------------------------------------------------- 1 | package org.nanohttpd.protocols.http.content; 2 | 3 | /* 4 | * #%L 5 | * NanoHttpd-Core 6 | * %% 7 | * Copyright (C) 2012 - 2016 nanohttpd 8 | * %% 9 | * Redistribution and use in source and binary forms, with or without modification, 10 | * are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, this 13 | * list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of the nanohttpd nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 32 | * OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * #L% 34 | */ 35 | 36 | import java.text.SimpleDateFormat; 37 | import java.util.Calendar; 38 | import java.util.Locale; 39 | import java.util.TimeZone; 40 | 41 | /** 42 | * A simple cookie representation. This is old code and is flawed in many ways. 43 | * 44 | * @author LordFokas 45 | */ 46 | public class Cookie { 47 | 48 | public static String getHTTPTime(int days) { 49 | Calendar calendar = Calendar.getInstance(); 50 | SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); 51 | dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); 52 | calendar.add(Calendar.DAY_OF_MONTH, days); 53 | return dateFormat.format(calendar.getTime()); 54 | } 55 | 56 | private final String n, v, e; 57 | 58 | public Cookie(String name, String value) { 59 | this(name, value, 30); 60 | } 61 | 62 | public Cookie(String name, String value, int numDays) { 63 | this.n = name; 64 | this.v = value; 65 | this.e = getHTTPTime(numDays); 66 | } 67 | 68 | public Cookie(String name, String value, String expires) { 69 | this.n = name; 70 | this.v = value; 71 | this.e = expires; 72 | } 73 | 74 | public String getHTTPHeader() { 75 | String fmt = "%s=%s; expires=%s"; 76 | return String.format(fmt, this.n, this.v, this.e); 77 | } 78 | } 79 | --------------------------------------------------------------------------------