diff --git a/LICENSE-2.0.txt b/LICENSE-2.0.txt
new file mode 100644
index 0000000..e8a31d8
--- /dev/null
+++ b/LICENSE-2.0.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2013 Mark Masse
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a5d96d2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,92 @@
+
+
+
+
+#WRML#
+
+WRML, the Web Resource Modeling Language, is an open source software project (http://www.wrml.org) focused on providing REST API standards, frameworks, and tools to support the development of web-oriented, client-server applications.
+
+*Getting started* with WRML means something a little bit different to each role involved in the creation of REST APIs.
+
+To those wanting to get started with the tools and find a link to download an installer (from an app store) or use a JS web app for REST API design - that documentation is still a work in progress.
+
+The remainder of this README is intended for developers or other folks wanting to download, build, install, and run WRML.
+
+Before you install WRML
+-----------------------
+
+From a console/terminal window, verify that *Java 7* is installed:
+
+ $> java -version
+
+Which should display something like this (with a "1.7.0" or higher version number):
+
+ java version "1.7.0"
+ Java(TM) SE Runtime Environment (build 1.7.0-b147)
+ Java HotSpot(TM) 64-Bit Server VM (build 21.0-b17, mixed mode)
+
+If not, it can be downloaded from: http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
+
+Also verify that *Maven 3* is installed:
+
+ $> mvn -version
+
+Which should display something like this:
+
+ Apache Maven 3.0.5 (r01de14724cdef164cd33c7c8c2fe155faf9602da; 2013-02-19 05:51:28-0800)
+
+If not, it can be downloaded from: http://maven.apache.org/download.cgi
+
+Download WRML
+-------------
+
+ $> git clone git@github.com:espn/WRML.git
+
+Or download the ZIP file from: https://github.com/espn/WRML
+
+Install WRML
+------------
+
+From the root directory (WRML_HOME) run maven's install command.
+
+ $> mvn install
+
+Please note that the first time you run this command, it may download several of WRML's dependencies and install them into your system's local maven repository.
+
+Configure WRML
+--------------
+
+Edit the WRML configuration file (wrml.json) to match your local environment. In the example below, these two lines are the important ones to match to your system:
+
+File Service Root Directory
+---------------------------
+This setting specifies the root directory for WRML Models (stored as JSON files on disk).
+
+ "rootDirectory" : "E:/wrml/models/"
+
+Schema Loader Schema Directory
+------------------------------
+
+This setting specifies the root directory for WRML Schemas (compiled as Java interfaces).
+
+ "schemaClassRootDirectory" : "E:/wrml/schemas"
+
+For those having problems starting WRML, please confirm that the "slash" leaning direction of the folder/directory paths match the conventions of your OS. In java config files, the "/" forward slash should work cross-platform, but the java commands listed below contain path's like "..\core\target\core-1.0-SNAPSHOT.jar;" which are both Windows-centric (backslashes) and relative to the WRML_HOME/bin folder.
+
+In lieu of an installer, please adjust config and script files according to match your environment.
+
+#WRML Tools#
+
+##Werminal - WRML Model Editor##
+
+See the Werminal /cli project README.
+
+For more about the Werminal app, please consult the "Werminal Masters Handbook": http://www.wrml.org/werminal/WerminalMastersHandbook.pdf
+
+##WRML Web Application##
+
+In progress as of the Jean Grey sprint.
+
+
+#License#
+WRML is copyright (C) 2012-2013 Mark Masse (OSS project WRML.org). WRML is licensed under the Apache License, Version 2.0. You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
diff --git a/Werminal.json b/Werminal.json
new file mode 100644
index 0000000..e35bb45
--- /dev/null
+++ b/Werminal.json
@@ -0,0 +1,290 @@
+{
+ "title" : "Werminal",
+ "schemaUriHistoryList" : [
+ "http://schema.api.wrml.org/org/wrml/runtime/service/apiDesigner/AutoLinkFunction",
+ "http://schema.api.wrml.org/org/wrml/model/rest/FiledApi",
+ "http://schema.api.wrml.org/org/wrml/model/Filed",
+ "http://schema.api.wrml.org/org/wrml/model/rest/LinkRelation",
+ "http://schema.api.wrml.org/org/wrml/test/wizard/Spell",
+ "http://schema.api.wrml.org/org/wrml/test/wizard/Guild",
+ "http://schema.api.wrml.org/org/wrml/model/rest/Api",
+ "http://schema.api.wrml.org/org/wrml/model/schema/Schema",
+ "http://schema.api.wrml.org/org/wrml/model/MaybeReadOnly",
+ "http://schema.api.wrml.org/org/wrml/model/Versioned",
+ "http://schema.api.wrml.org/org/wrml/model/Tagged",
+ "http://schema.api.wrml.org/org/wrml/model/Thumbnailed",
+ "http://schema.api.wrml.org/org/wrml/model/UniquelyNamed",
+ "http://schema.api.wrml.org/org/wrml/runtime/service/apiDesigner/ApiDesignerHome",
+ "http://schema.api.wrml.org/org/wrml/model/Virtual",
+ "http://schema.api.wrml.org/org/wrml/model/schema/Slot",
+ "http://schema.api.wrml.org/org/wrml/model/Named",
+ "http://schema.api.wrml.org/org/wrml/model/Titled",
+ "http://schema.api.wrml.org/org/wrml/model/Described",
+ "http://schema.api.wrml.org/org/wrml/model/schema/LinkValue",
+ "http://schema.api.wrml.org/org/wrml/model/schema/Primitive",
+ "http://schema.api.wrml.org/org/wrml/model/schema/Inextensible",
+ "http://schema.api.wrml.org/org/wrml/model/schema/Value",
+ "http://schema.api.wrml.org/org/wrml/test/wizard/Wizard",
+ "http://schema.api.wrml.org/org/wrml/model/rest/Document",
+ "http://schema.api.wrml.org/org/wrml/model/Abstract"
+ ],
+ "slotValueHistoryLists" : [
+ {
+ "slotValueEntries" : [
+ {
+ "name" : "uri",
+ "value" : "http://designer.api.wrml.org"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://design.api.wrml.org"
+ }
+ ],
+ "historyListSchemaUri" : "http://schema.api.wrml.org/org/wrml/runtime/service/apiDesigner/ApiDesignerHome"
+ },
+ {
+ "slotValueEntries" : [
+ {
+ "name" : "uri",
+ "value" : "http://design.api.wrml.org/functions/autoLink"
+ }
+ ],
+ "historyListSchemaUri" : "http://schema.api.wrml.org/org/wrml/runtime/service/apiDesigner/AutoLinkFunction"
+ },
+ {
+ "slotValueEntries" : [
+ {
+ "name" : "file",
+ "value" : "/Users/mark/Documents/WRML/models/apis/api.json"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://autoLink"
+ }
+ ],
+ "historyListSchemaUri" : "http://schema.api.wrml.org/org/wrml/model/rest/FiledApi"
+ },
+ {
+ "slotValueEntries" : [
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/test/wizard/Wizard"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://schema.api.wrml.org/org/wrml/test/wizard/Wizard"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/test/wizard/Spell"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://schema.api.wrml.org/org/wrml/test/wizard/Spell"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/test/wizard/Guild"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://schema.api.wrml.org/org/wrml/test/wizard/Guild"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/model/rest/Api"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://schema.api.wrml.org/org/wrml/model/rest/Api"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/model/rest/Document"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://schema.api.wrml.org/org/wrml/model/rest/Document"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/runtime/service/apiDesigner/ApiDesignerHome"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://schema.api.wrml.org/org/wrml/runtime/service/apiDesigner/ApiDesignerHome"
+ }
+ ],
+ "historyListSchemaUri" : "http://schema.api.wrml.org/org/wrml/model/schema/Schema"
+ },
+ {
+ "slotValueEntries" : [
+ {
+ "name" : "wizardId",
+ "value" : ""
+ },
+ {
+ "name" : "uri",
+ "value" : "http://wizard.example.api.wrml.org/wizards/merlin?rg=42"
+ },
+ {
+ "name" : "wizardId",
+ "value" : "merlin"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://wizard.example.api.wrml.org/wizards/harry?rg=42"
+ },
+ {
+ "name" : "wizardId",
+ "value" : "harry"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://wizard.example.api.wrml.org/wizards/harry"
+ }
+ ],
+ "historyListSchemaUri" : "http://schema.api.wrml.org/org/wrml/test/wizard/Wizard"
+ },
+ {
+ "slotValueEntries" : [
+ {
+ "name" : "uri",
+ "value" : "http://wizard.example.api.wrml.org"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://schema.api.wrml.org"
+ }
+ ],
+ "historyListSchemaUri" : "http://schema.api.wrml.org/org/wrml/model/rest/Api"
+ },
+ {
+ "slotValueEntries" : [
+ {
+ "name" : "id",
+ "value" : "7"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://wizard.example.api.wrml.org/guilds/7"
+ },
+ {
+ "name" : "id",
+ "value" : "42"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://wizard.example.api.wrml.org/guilds/42"
+ }
+ ],
+ "historyListSchemaUri" : "http://schema.api.wrml.org/org/wrml/test/wizard/Guild"
+ },
+ {
+ "slotValueEntries" : [
+ {
+ "name" : "spellId",
+ "value" : "lightningBolt"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://wizard.example.api.wrml.org/spells/lightningBolt"
+ },
+ {
+ "name" : "spellId",
+ "value" : "heal"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://wizard.example.api.wrml.org/spells/heal"
+ },
+ {
+ "name" : "spellId",
+ "value" : "tornado"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://wizard.example.api.wrml.org/spells/tornado"
+ },
+ {
+ "name" : "spellId",
+ "value" : "fireball"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://wizard.example.api.wrml.org/spells/fireball"
+ }
+ ],
+ "historyListSchemaUri" : "http://schema.api.wrml.org/org/wrml/test/wizard/Spell"
+ },
+ {
+ "slotValueEntries" : [
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/relation/self"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://relation.api.wrml.org/org/wrml/relation/self"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/test/wizard/spell"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://relation.api.wrml.org/org/wrml/test/wizard/spell"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/test/wizard/guild"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://relation.api.wrml.org/org/wrml/test/wizard/guild"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/test/wizard/primarySpell"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://relation.api.wrml.org/org/wrml/test/wizard/primarySpell"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/test/wizard/secondarySpell"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://relation.api.wrml.org/org/wrml/test/wizard/secondarySpell"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/test/wizard/rivalGuild"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://relation.api.wrml.org/org/wrml/test/wizard/rivalGuild"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/test/wizard/defaultGuild"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://relation.api.wrml.org/org/wrml/test/wizard/defaultGuild"
+ },
+ {
+ "name" : "uniqueName",
+ "value" : "org/wrml/test/wizard/defaultSpell"
+ },
+ {
+ "name" : "uri",
+ "value" : "http://relation.api.wrml.org/org/wrml/test/wizard/defaultSpell"
+ }
+ ],
+ "historyListSchemaUri" : "http://schema.api.wrml.org/org/wrml/model/rest/LinkRelation"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/cli/.gitignore b/cli/.gitignore
new file mode 100644
index 0000000..deb77c9
--- /dev/null
+++ b/cli/.gitignore
@@ -0,0 +1,12 @@
+target
+bin
+logs
+.classpath
+.project
+.settings
+dependency-reduced-pom.xml
+src/test/resources/fileSystemServiceRootDirectory/*
+!src/test/resources/fileSystemServiceRootDirectory/placeholder.txt
+src/test/resources/schemaClassRootDirectory/*
+!src/test/resources/schemaClassRootDirectory/placeholder.txt
+/wrml.json*
\ No newline at end of file
diff --git a/cli/README.md b/cli/README.md
new file mode 100644
index 0000000..36f777a
--- /dev/null
+++ b/cli/README.md
@@ -0,0 +1,66 @@
+
+
+
+
+Werminal
+================================
+
+Werminal is a terminal (command line) application for WRML model browsing and editing.
+
+Werminal can be used to create new models of _any_ type such as: Schemas, Teams, Players, Aliens, HomeScreens, Movies; whatever your application calls for.
+
+Werminal also enables you to open, edit, and save data (of any data type).
+
+Running Werminal
+================================
+
+Note that all the following examples are dependent on the `wrml-cli.jar` file. This file can be built from maven in the `cli` project:
+
+
+## Default ##
+
+To run Werminal with the default options, execute the `wrml-cli.jar` using the `java -jar` command:
+
+ java -jar cli/target/wrml-cli.jar
+
+This assumes that you have a WRML configuration file named `wrml.json` in either the current working directory or your user directory.
+
+## Specify -config
command line argument ##
+
+To run Werminal with a specified configuration file path using the `-config` program argument:
+
+ java -jar cli/target/wrml-cli.jar org.wrml.werminal.Werminal -config my/path/to/wrml.json
+
+or to specify the UNIX terminal mode:
+
+ java -jar cli/target/wrml-cli.jar org.wrml.werminal.Werminal -config my/path/to/wrml.json -unix
+
+## Specify wrmlConfiguration
JVM argument ##
+
+To run Werminal with a specific configuration file path using the `-DwrmlConfiguration` JVM argument:
+
+ java -DwrmlConfiguration=my/path/to/wrml.json -jar cli/target/wrml-cli.jar
+
+or to manually specify the CLI's main class:
+
+ java -DwrmlConfiguration=my/path/to/wrml.json -jar cli/target/wrml-cli.jar org.wrml.werminal.Werminal
+
+or to specify the UNIX terminal mode:
+
+ java -DwrmlConfiguration=my/path/to/wrml.json -jar cli/target/wrml-cli.jar org.wrml.werminal.Werminal -unix
+
+
+## Via Eclipse .launch Configuration ##
+
+1. In 'Run Configurations', choose 'New Java Application'.
+1. On the 'Main' tab, enter:
+ 1. Project: "`cli`"
+ 1. Main class: "`org.wrml.werminal.Werminal`"
+ 1. Check "Stop in main"
+1. [Optional] On the 'Arguments' tab, either the `-config` or `-DwrmlConfiguration` options described above.
+
+
+References
+===============
+
+For more about the Werminal app, please consult the "Werminal Masters Handbook": http://www.wrml.org/werminal/WerminalMastersHandbook.pdf
diff --git a/cli/cli.iml b/cli/cli.iml
new file mode 100644
index 0000000..03c7acb
--- /dev/null
+++ b/cli/cli.iml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cli/pom.xml b/cli/pom.xml
new file mode 100644
index 0000000..b74e0da
--- /dev/null
+++ b/cli/pom.xml
@@ -0,0 +1,151 @@
+
+ 4.0.0
+
+ org.wrml
+ wrml
+ 1.0-SNAPSHOT
+
+ cli
+ jar
+
+ WRML CLI (Werminal)
+ WRML Command Line Interface
+
+
+
+
+
+
+ com.mycila.maven-license-plugin
+ maven-license-plugin
+
+ true
+ src/main/resources/headers/JavaFileHeader-latest.txt
+
+ src/**/*.java
+
+ ${project.build.sourceEncoding}
+
+ src/main/resources/headers/JavaFileHeader-version-00.txt
+ src/main/resources/headers/JavaFileHeader-version-01.txt
+ src/main/resources/headers/JavaFileHeader-version-02.txt
+
+
+
+
+ test
+
+ check
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-eclipse-plugin
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ maven-assembly-plugin
+
+
+ jar-with-dependencies
+ package
+
+ single
+
+
+ wrml-cli
+ false
+
+ jar-with-dependencies
+
+
+
+ org.wrml.werminal.Werminal
+ true
+
+
+
+
+
+
+
+
+
+
+ ch.qos.logback
+ logback-classic
+
+
+ commons-cli
+ commons-cli
+
+
+ com.googlecode.lanterna
+ lanterna
+
+
+
+ org.codehaus.janino
+ janino
+ runtime
+
+
+ org.wrml
+ core
+
+
+ org.wrml.contrib.runtime.service
+ mongo
+
+
+
+ junit
+ junit
+ test
+
+
+ org.mockito
+ mockito-all
+ test
+
+
+ org.powermock
+ powermock-module-junit4
+ test
+
+
+ org.powermock
+ powermock-api-mockito
+ test
+
+
+ org.reflections
+ reflections
+ test
+
+
+
\ No newline at end of file
diff --git a/cli/src/main/java/org/wrml/werminal/OptionDescriptor.java b/cli/src/main/java/org/wrml/werminal/OptionDescriptor.java
new file mode 100644
index 0000000..b36dac1
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/OptionDescriptor.java
@@ -0,0 +1,112 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wrml.werminal;
+
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+
+public enum OptionDescriptor
+{
+
+ config("config", "config", true, "The WRML configuration file."),
+ unix("unix", "unix", false, "Runs the Werminal GUI app within a UNIX terminal."),
+ swing("swing", "swing", false, "Runs the Werminal GUI app within a Swing terminal emulator.");
+
+ public static final Options OPTIONS = new Options();
+
+ static
+ {
+
+ final OptionDescriptor[] optionDescriptors = OptionDescriptor.values();
+
+ for (final OptionDescriptor optionDescriptor : optionDescriptors)
+ {
+ OPTIONS.addOption(optionDescriptor.toOption());
+ }
+
+ }
+
+ private final String _Name;
+
+ private final String _LongName;
+
+ private final boolean _Parameterized;
+
+ private final String _Description;
+
+ private Option _Option;
+
+ private OptionDescriptor(final String name, final String longName, final boolean paramenterized,
+ final String description)
+ {
+
+ _Name = name;
+ _LongName = longName;
+ _Parameterized = paramenterized;
+ _Description = description;
+ }
+
+ public String getDescription()
+ {
+
+ return _Description;
+ }
+
+ public String getLongName()
+ {
+
+ return _LongName;
+ }
+
+ public String getName()
+ {
+
+ return _Name;
+ }
+
+ public boolean isParameterized()
+ {
+
+ return _Parameterized;
+ }
+
+ public Option toOption()
+ {
+
+ if (_Option == null)
+ {
+ _Option = new Option(getName(), getLongName(), isParameterized(), getDescription());
+ }
+ return _Option;
+ }
+
+ @Override
+ public String toString()
+ {
+
+ return _Name;
+ }
+}
\ No newline at end of file
diff --git a/cli/src/main/java/org/wrml/werminal/Werminal.java b/cli/src/main/java/org/wrml/werminal/Werminal.java
new file mode 100644
index 0000000..8aec96a
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/Werminal.java
@@ -0,0 +1,1011 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal;
+
+import com.googlecode.lanterna.gui.Component;
+import com.googlecode.lanterna.gui.GUIScreen;
+import com.googlecode.lanterna.gui.GUIScreen.Position;
+import com.googlecode.lanterna.gui.Theme;
+import com.googlecode.lanterna.gui.Window;
+import com.googlecode.lanterna.screen.Screen;
+import com.googlecode.lanterna.terminal.Terminal;
+import com.googlecode.lanterna.terminal.swing.SwingTerminal;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.wrml.model.Filed;
+import org.wrml.model.Model;
+import org.wrml.model.rest.Document;
+import org.wrml.model.rest.Method;
+import org.wrml.runtime.*;
+import org.wrml.runtime.format.application.schema.json.JsonSchemaLoader;
+import org.wrml.runtime.rest.ApiLoader;
+import org.wrml.runtime.rest.SystemApi;
+import org.wrml.runtime.schema.*;
+import org.wrml.runtime.syntax.SyntaxLoader;
+import org.wrml.util.PropertyUtil;
+import org.wrml.util.UniqueName;
+import org.wrml.werminal.action.*;
+import org.wrml.werminal.component.*;
+import org.wrml.werminal.dialog.*;
+import org.wrml.werminal.model.EntryModel;
+import org.wrml.werminal.model.SlotValueHistoryListModel;
+import org.wrml.werminal.model.WerminalModel;
+import org.wrml.werminal.terminal.TerminalApp;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppMenuWindow;
+import org.wrml.werminal.terminal.TerminalType;
+import org.wrml.werminal.theme.DefaultSplashTheme;
+import org.wrml.werminal.theme.DefaultWindowTheme;
+import org.wrml.werminal.theme.LightTheme;
+import org.wrml.werminal.util.History;
+import org.wrml.werminal.window.ModelWindow;
+import org.wrml.werminal.window.SplashWindow;
+
+import javax.swing.*;
+import java.io.File;
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.*;
+
+import static org.wrml.runtime.EngineConfiguration.WRML_CONFIGURATION_FILE_PATH_PROPERTY_NAME;
+
+
+/**
+ *
+ *
+ * {@code Werminal} is a terminal (command line) application for WRML model browsing and editing. See
+ * {@link OptionDescriptor} for a complete set of Wrml options.
+ *
+ * see {@link #main(String[])}.
+ *
+ *
+ * @see Lanterna, easy console text GUI library for Java
+ * @see Engine
+ * @see EngineConfiguration
+ * @see org.wrml.runtime.service.file.FileSystemService
+ * @see org.wrml.runtime.service.rest.RestService
+ * @see Model
+ * @see Keys
+ * @see org.wrml.model.rest.Api
+ * @see org.wrml.model.rest.Document
+ * @see org.wrml.model.schema.Schema
+ */
+public class Werminal extends TerminalApp
+{
+
+ public static final Logger LOG = LoggerFactory.getLogger(Werminal.class);
+
+ private static final String WERMINAL_MODEL_FILE_NAME = Werminal.class.getSimpleName() + ".json";
+
+ private final WerminalModel _WerminalModel;
+
+ private final Theme _DefaultSplashTheme;
+
+ private final Theme _DefaultMenuTheme;
+
+ private final Theme _LightTheme;
+
+ private final SplashWindow _SplashWindow;
+
+ private final TerminalAppMenuWindow _MainMenuWindow;
+
+ private final NewModelDialog _NewModelDialog;
+
+ private final OpenModelDialog _OpenModelDialog;
+
+ private final LoadApiDialog _LoadApiDialog;
+
+ private final PrintDialog _PrintDialog;
+
+ private final TerminalAppMenuWindow _ModelMenuWindow;
+
+ private final TerminalAppMenuWindow _ListMenuWindow;
+
+ private final WerminalAction _NewAction;
+
+ private final WerminalAction _OpenAction;
+
+ private final WerminalAction _NewConfirmationAction;
+
+ private final WerminalAction _OpenConfirmationAction;
+
+ private final WerminalAction _SetOriginAction;
+
+ private final WerminalAction _WrmlOrgAction;
+
+ private final WerminalAction _HelpGuideAction;
+
+ private final WerminalAction _ExitAction;
+
+ private final WerminalAction _SaveAction;
+
+ private final WerminalAction _PrintPreviewAction;
+
+ private final WerminalAction _PrintAction;
+
+ private final WerminalAction _PrintConfirmationAction;
+
+ private final WerminalAction _LoadAction;
+
+ private final WerminalAction _CancelAction;
+
+ private final WerminalAction _DeleteAction;
+
+ private final WerminalAction _ShowModelMenuAction;
+
+ private final WerminalAction _ShowListMenuAction;
+
+ private final CloseBeforeAction _CloseAction;
+
+ private final CloseBeforeAction _ClosingWrmlOrgAction;
+
+ private final Map _UnimplementedActions;
+
+ private final History _SchemaUriHistory;
+
+ private final SortedMap>> _SlotValueHistories;
+
+ private final SortedMap _SlotValueHistoryModels;
+
+
+ public Werminal(final WerminalModel werminalModel, final Context context, final TerminalType terminalType) throws Exception
+ {
+
+ super("Werminal", context, terminalType);
+
+ _WerminalModel = werminalModel;
+
+ final GUIScreen guiScreen = getGuiScreen();
+
+ final List schemaUriHistoryList = _WerminalModel.getSchemaUriHistoryList();
+
+ _SchemaUriHistory = new History<>(schemaUriHistoryList);
+
+ _SlotValueHistories = new TreeMap<>();
+ _SlotValueHistoryModels = new TreeMap<>();
+
+ final List slotValueHistoryLists = _WerminalModel.getSlotValueHistoryLists();
+ compileSlotValueHistoryLists(slotValueHistoryLists);
+
+ _UnimplementedActions = new HashMap();
+ _DefaultSplashTheme = new DefaultSplashTheme();
+ _DefaultMenuTheme = new DefaultWindowTheme();
+ _LightTheme = new LightTheme();
+
+ _CancelAction = new CancelAction(this);
+ _CloseAction = new CloseBeforeAction(this);
+ _DeleteAction = new DeleteAction(this);
+ _ExitAction = new ExitAction(this);
+ _NewAction = new NewAction(this);
+ _NewConfirmationAction = new NewConfirmationAction(this);
+ _OpenAction = new OpenAction(this);
+ _OpenConfirmationAction = new OpenConfirmationAction(this);
+ _SetOriginAction = new SetOriginAction(this);
+
+ _SaveAction = new SaveAction(this);
+
+ _PrintPreviewAction = new PrintPreviewAction(this);
+ _PrintAction = new PrintAction(this);
+ _PrintConfirmationAction = new PrintConfirmationAction(this);
+
+ _LoadAction = new LoadAction(this);
+
+ _ShowModelMenuAction = new ShowModelMenuAction(this);
+ _ShowListMenuAction = new ShowListMenuAction(this);
+ _HelpGuideAction = new HelpGuideAction(this);
+ _WrmlOrgAction = new WrmlOrgAction(this);
+
+ _ClosingWrmlOrgAction = new CloseBeforeAction(this, _WrmlOrgAction);
+
+ _SplashWindow = new SplashWindow(this);
+ _MainMenuWindow = new TerminalAppMenuWindow(this, "WRML - Werminal", new MainMenu(this),
+ new TerminalAppButtonPanel(_ExitAction));
+ _NewModelDialog = new NewModelDialog(this, "New Model", _NewConfirmationAction, _CancelAction);
+ _OpenModelDialog = new OpenModelDialog(this, "Open Model", _OpenConfirmationAction, _CancelAction);
+
+ _ModelMenuWindow = new TerminalAppMenuWindow(this, "", new ModelMenu(this), new TerminalAppButtonPanel(
+ _CloseAction));
+
+ _ListMenuWindow = new TerminalAppMenuWindow(this, "", new ListMenu(this), new TerminalAppButtonPanel(
+ _CloseAction));
+
+ _PrintDialog = new PrintDialog(this, "Print Model");
+ _LoadApiDialog = new LoadApiDialog(this, "Load REST API Metadata");
+
+ final URI metaSchemaUri = getContext().getSchemaLoader().getSchemaSchemaUri();
+ _NewModelDialog.setSchemaUri(metaSchemaUri);
+
+ for (final URI historySchemaUri : schemaUriHistoryList)
+ {
+ addToSchemaUriHistory(historySchemaUri);
+ }
+
+ final JsonSchemaLoader jsonSchemaLoader = context.getSchemaLoader().getJsonSchemaLoader();
+ final SortedSet loadedJsonSchemaUris = jsonSchemaLoader.getLoadedJsonSchemaUris();
+ for (final URI loadedJsonSchemaUri : loadedJsonSchemaUris)
+ {
+ addToSchemaUriHistory(loadedJsonSchemaUri);
+ }
+
+ final Screen screen = guiScreen.getScreen();
+ screen.startScreen();
+
+ final Terminal terminal = screen.getTerminal();
+ if (terminal instanceof SwingTerminal)
+ {
+ final JFrame frame = ((SwingTerminal) terminal).getJFrame();
+ frame.setTitle(getAppTitle());
+
+ // TODO: Do something fun with the JFrame. =)
+ }
+
+ showSplashWindow();
+
+ String errorMessage = null;
+
+ while (true)
+ {
+ try
+ {
+ showMainMenuBarWindow();
+ break;
+ }
+ catch (final Exception e)
+ {
+ errorMessage = "An unexpected error has occurred.";
+ showError(errorMessage, e);
+ LOG.error(errorMessage + " (" + e.getMessage() + ")", e);
+ }
+ }
+
+ screen.stopScreen();
+
+ schemaUriHistoryList.clear();
+ schemaUriHistoryList.addAll(_SchemaUriHistory.getElementSet());
+
+ getContext().saveModel(_WerminalModel);
+ }
+
+ /**
+ * Entry point to run the Werminal console app. To run Werminal, two parameters are required:
+ *
+ * -{@link OptionDescriptor#unix unix}
or -{@link OptionDescriptor#swing swing}
+ * -{@link OptionDescriptor#config config} path/to/wrml.json
+ *
+ * Example
+ * org.wrmlx.app.werminal.Werminal -{@link OptionDescriptor#swing swing} -{@link OptionDescriptor#config config} path/to/wrml.json
+ *
+ * Alternatively, the config file path can be specified with a variable: "
+ * -D{@link org.wrml.runtime.EngineConfiguration#WRML_CONFIGURATION_FILE_PATH_PROPERTY_NAME wrmlConfiguration}=path/to/wrml.json
+ *
+ *
+ * @param args - standard command line arguments; see {@link OptionDescriptor}.
+ */
+ public static void main(String[] args) throws Exception
+ {
+
+ final CommandLineParser parser = new GnuParser();
+ final CommandLine commandLine = parser.parse(OptionDescriptor.OPTIONS, args);
+ TerminalType terminalType = TerminalType.Swing;
+ if (commandLine.hasOption(OptionDescriptor.unix.getName()))
+ {
+ terminalType = TerminalType.Unix;
+ }
+
+ // Check the system property
+ String configurationFilePath = PropertyUtil.getSystemProperty(WRML_CONFIGURATION_FILE_PATH_PROPERTY_NAME);
+ if (configurationFilePath == null)
+ {
+ configurationFilePath = commandLine.getOptionValue(OptionDescriptor.config.getName());
+ }
+
+
+ final EngineConfiguration engineConfiguration = EngineConfiguration.load(configurationFilePath);
+ final Engine engine = new DefaultEngine();
+ engine.init(engineConfiguration);
+
+ final Context context = engine.getContext();
+ final SchemaLoader schemaLoader = context.getSchemaLoader();
+
+ final WerminalModel werminalModel;
+ final File appFile = FileUtils.getFile(WERMINAL_MODEL_FILE_NAME).getCanonicalFile();
+ if (appFile.exists() && appFile.isFile() && appFile.canRead())
+ {
+ final Keys keys = new KeysBuilder(schemaLoader.getTypeUri(Filed.class), appFile).toKeys();
+ final Dimensions dimensions = new DimensionsBuilder(schemaLoader.getTypeUri(WerminalModel.class))
+ .toDimensions();
+ werminalModel = context.getModel(keys, dimensions);
+ }
+ else
+ {
+ werminalModel = context.newModel(WerminalModel.class);
+ }
+ werminalModel.setTitle(Werminal.class.getSimpleName());
+ werminalModel.setFile(appFile);
+ new Werminal(werminalModel, context, terminalType);
+ }
+
+ public boolean addSlotValueToHistory(final URI historyListSchemaUri, final String slotName, final Object slotValue)
+ {
+
+ final Context context = getContext();
+ final SyntaxLoader syntaxLoader = context.getSyntaxLoader();
+ final String stringValue = syntaxLoader.formatSyntaxValue(slotValue);
+
+ final SlotValueHistoryListModel slotValueHistoryList;
+ if (!_SlotValueHistoryModels.containsKey(historyListSchemaUri))
+ {
+
+ slotValueHistoryList = context.newModel(SlotValueHistoryListModel.class);
+ slotValueHistoryList.setHistoryListSchemaUri(historyListSchemaUri);
+ _SlotValueHistoryModels.put(historyListSchemaUri, slotValueHistoryList);
+
+ final List slotValueHistoryLists = _WerminalModel.getSlotValueHistoryLists();
+ slotValueHistoryLists.add(slotValueHistoryList);
+ }
+ else
+ {
+ slotValueHistoryList = _SlotValueHistoryModels.get(historyListSchemaUri);
+ }
+
+ final SortedSet slotValueHistory = getSlotValueHistory(historyListSchemaUri, slotName);
+ if (!slotValueHistory.add(slotValue))
+ {
+ return false;
+ }
+
+ final List slotValueEntries = slotValueHistoryList.getSlotValueEntries();
+
+ final EntryModel entry = context.newModel(EntryModel.class);
+ entry.setName(slotName);
+ entry.setValue(stringValue);
+
+ slotValueEntries.add(entry);
+
+ return true;
+ }
+
+ public void addToSchemaUriHistory(final URI schemaUri)
+ {
+
+ if (schemaUri == null)
+ {
+ return;
+ }
+
+ final History schemaUriHistory = getSchemaUriHistory();
+ schemaUriHistory.add(schemaUri);
+
+ final NewModelDialog newModelDialog = getNewModelDialog();
+ final HistoryCheckListBox newModelDialogSchemaUriHistoryCheckBoxList = newModelDialog
+ .getSchemaUriHistoryCheckBoxList();
+
+ final OpenModelDialog openModelDialog = getOpenModelDialog();
+ final HistoryCheckListBox openModelDialogSchemaUriHistoryCheckBoxList = openModelDialog
+ .getSchemaUriHistoryCheckBoxList();
+
+ newModelDialogSchemaUriHistoryCheckBoxList.addItem(schemaUri);
+ openModelDialogSchemaUriHistoryCheckBoxList.addItem(schemaUri);
+
+ final SchemaLoader schemaLoader = getContext().getSchemaLoader();
+ if (schemaLoader.isPrototyped(schemaUri))
+ {
+ final Prototype prototype;
+ try
+ {
+ prototype = schemaLoader.getPrototype(schemaUri);
+ }
+ catch (final Exception e)
+ {
+ LOG.warn("Unable to add schema to history: " + schemaUri + ". Reason: " + e.getMessage());
+ return;
+ }
+
+ // Capture all related schema URIs in the history list
+
+ final Set relatedSchemaUris = prototype.getAllRelatedSchemaUris();
+ schemaUriHistory.addAll(relatedSchemaUris);
+
+ newModelDialogSchemaUriHistoryCheckBoxList.addItems(relatedSchemaUris);
+ openModelDialogSchemaUriHistoryCheckBoxList.addItems(relatedSchemaUris);
+
+ }
+
+ }
+
+ public URI createSchemaUri(final String simpleSchemaName)
+ {
+
+ final String systemUserName = System.getProperty("user.name");
+
+ final String appUserName = (systemUserName != null && !systemUserName.isEmpty()) ? systemUserName : "user "
+ + getClass().getSimpleName() + " wrml";
+ String userNamespace = StringUtils.replace(appUserName, " ", "/");
+ userNamespace = StringUtils.reverseDelimited(userNamespace, '/');
+
+ // TODO: Make the userNamespace an option or setting or preference (in the Werminal tool options dialog)
+
+ userNamespace = userNamespace.toLowerCase();
+
+ final UniqueName newSchemaUniqueName = new UniqueName("org/" + userNamespace, simpleSchemaName);
+ final URI schemaUri = URI.create(SystemApi.Schema.getUri().toString() + "/" + newSchemaUniqueName.toString());
+
+ return schemaUri;
+ }
+
+ public WerminalAction getCancelAction()
+ {
+
+ return _CancelAction;
+ }
+
+ public CloseBeforeAction getCloseAction()
+ {
+
+ return _CloseAction;
+ }
+
+ public CloseBeforeAction getClosingWrmlOrgAction()
+ {
+
+ return _ClosingWrmlOrgAction;
+ }
+
+ public Theme getDefaultMenuTheme()
+ {
+
+ return _DefaultMenuTheme;
+ }
+
+ public Theme getDefaultSplashTheme()
+ {
+
+ return _DefaultSplashTheme;
+ }
+
+ public WerminalAction getDeleteAction()
+ {
+
+ return _DeleteAction;
+ }
+
+ public WerminalAction getExitAction()
+ {
+
+ return _ExitAction;
+ }
+
+ public WerminalAction getHelpGuideAction()
+ {
+
+ return _HelpGuideAction;
+ }
+
+ public Theme getLightTheme()
+ {
+
+ return _LightTheme;
+ }
+
+ public TerminalAppMenuWindow getListMenuBarWindow()
+ {
+
+ return _ListMenuWindow;
+ }
+
+ public WerminalAction getLoadAction()
+ {
+
+ return _LoadAction;
+ }
+
+ public TerminalAppMenuWindow getMainMenuBarWindow()
+ {
+
+ return _MainMenuWindow;
+ }
+
+ public TerminalAppMenuWindow getModelMenuBarWindow()
+ {
+
+ return _ModelMenuWindow;
+ }
+
+ public WerminalAction getNewAction()
+ {
+
+ return _NewAction;
+ }
+
+ public WerminalAction getNewConfirmationAction()
+ {
+
+ return _NewConfirmationAction;
+ }
+
+ public NewModelDialog getNewModelDialog()
+ {
+
+ return _NewModelDialog;
+ }
+
+ public WerminalAction getOpenAction()
+ {
+
+ return _OpenAction;
+ }
+
+ public WerminalAction getOpenConfirmationAction()
+ {
+
+ return _OpenConfirmationAction;
+ }
+
+ public OpenModelDialog getOpenModelDialog()
+ {
+
+ return _OpenModelDialog;
+ }
+
+ public WerminalAction getPrintPreviewAction()
+ {
+
+ return _PrintPreviewAction;
+ }
+
+ public WerminalAction getSetOriginAction()
+ {
+
+ return _SetOriginAction;
+ }
+
+ public WerminalAction getPrintAction()
+ {
+
+ return _PrintAction;
+ }
+
+ public WerminalAction getPrintConfirmationAction()
+ {
+
+ return _PrintConfirmationAction;
+ }
+
+ public WerminalAction getSaveAction()
+ {
+
+ return _SaveAction;
+ }
+
+ public History getSchemaUriHistory()
+ {
+
+ return _SchemaUriHistory;
+ }
+
+ public WerminalAction getShowListMenuAction()
+ {
+
+ return _ShowListMenuAction;
+ }
+
+ public WerminalAction getShowModelMenuAction()
+ {
+
+ return _ShowModelMenuAction;
+ }
+
+ public SortedSet getSlotValueHistory(final URI schemaUri, final String slotName)
+ {
+
+ if (schemaUri == null || slotName == null)
+ {
+ return null;
+ }
+
+ if (!_SlotValueHistories.containsKey(schemaUri))
+ {
+ _SlotValueHistories.put(schemaUri, new TreeMap>());
+ }
+
+ final Map> schemaHistory = _SlotValueHistories.get(schemaUri);
+
+ if (!schemaHistory.containsKey(slotName))
+ {
+ schemaHistory.put(slotName, new TreeSet());
+ }
+
+ return schemaHistory.get(slotName);
+ }
+
+ public SplashWindow getSplashWindow()
+ {
+
+ return _SplashWindow;
+ }
+
+ public String getTypeTitle(final Type type)
+ {
+
+ final Context context = getContext();
+ final ValueType valueType = context.getSchemaLoader().getValueType(type);
+ final String typeTitle;
+ if (valueType == ValueType.Text && !String.class.equals(type))
+ {
+ typeTitle = valueType.name() + "/" + ((Class>) type).getSimpleName();
+ }
+ else
+ {
+ typeTitle = valueType.name();
+ }
+
+ return typeTitle;
+ }
+
+ public WerminalAction getUnimplementedAction(final String title)
+ {
+
+ if (!_UnimplementedActions.containsKey(title))
+ {
+ final UnimplementedAction action = new UnimplementedAction(this, title);
+ _UnimplementedActions.put(title, action);
+ }
+
+ return _UnimplementedActions.get(title);
+ }
+
+ public Map getUnimplementedActions()
+ {
+
+ return _UnimplementedActions;
+ }
+
+ public WerminalAction getWrmlOrgAction()
+ {
+
+ return _WrmlOrgAction;
+ }
+
+ public String listToString(final List> listValue, final Type listType)
+ {
+
+ final int itemCount = listValue.size();
+ final String itemString = (itemCount == 1) ? "1 element" : itemCount + " elements";
+ return listTypeToString(listType) + " " + "[ " + itemString + " ]";
+
+ }
+
+ public String listTypeToString(final Type listType)
+ {
+
+ final Type listElementType = ValueType.getListElementType(listType);
+ final Class> listElementClass = (Class>) listElementType;
+ final String stringValue = "List<" + listElementClass.getCanonicalName() + ">";
+ return stringValue;
+ }
+
+ public void newModelWindow(final URI schemaUri)
+ {
+
+ LOG.debug("NewModelWindow created with schemaUri [{}]", schemaUri);
+
+ // Get the engine's default context and schema loader
+ final Context context = getContext();
+
+ final Dimensions dimensions = new DimensionsBuilder(schemaUri).toDimensions();
+
+ final Model model = context.newModel(dimensions);
+
+ openModelWindow(model);
+ }
+
+ public void openListDialog(final FormField listFormField)
+ {
+
+ final WerminalTextBox listFormFieldTextBox = listFormField.getFieldValueTextBox();
+ final Type listType = listFormFieldTextBox.getHeapValueType();
+ final List> listValue = (List>) listFormFieldTextBox.getValue();
+ final String listValueString = listTypeToString(listType);
+
+ final ListValueDialogConfirmationAction listValueDialogConfirmationAction = new ListValueDialogConfirmationAction(
+ this, listFormFieldTextBox);
+
+ final AddAction addAction = new AddAction(this);
+
+ final ListValueDialog listValueDialog = new ListValueDialog(this, listFormField.getFieldName() + " - "
+ + listValueString, new Component[]{new TerminalAppButtonPanel(addAction),
+ new TerminalAppButtonPanel(_ShowListMenuAction)}, listValueDialogConfirmationAction, _CancelAction);
+
+ listValueDialogConfirmationAction.setListValueDialog(listValueDialog);
+ addAction.setListValueDialog(listValueDialog);
+
+ listValueDialog.setList(listValue, ValueType.getListElementType(listType));
+
+ showWindow(listValueDialog, Position.FULL_SCREEN);
+ }
+
+ @SuppressWarnings("unchecked")
+ public M openModel(final URI schemaUri, final Keys keys, final UUID heapId)
+ {
+
+ if (schemaUri == null || (keys == null && heapId == null))
+ {
+ return null;
+ }
+
+ // Get the engine's default context and schema loader
+ final Context context = getContext();
+
+ final Dimensions dimensions;
+ final URI uri = context.getKeyValue(keys, Document.class);
+ if (uri != null)
+ {
+ final ApiLoader apiLoader = context.getApiLoader();
+ dimensions = apiLoader.buildDocumentDimensions(Method.Get, uri, new DimensionsBuilder(schemaUri));
+ }
+ else
+ {
+ dimensions = new DimensionsBuilder(schemaUri).toDimensions();
+ }
+
+ Model model = null;
+ String errorMessage = null;
+ try
+ {
+ if (heapId != null)
+ {
+ // model = context.newModel(dimensions);
+ // TODO: support this
+ showError("Opening by heapId is temporarily disabled.");
+ model = null;
+ }
+ else
+ {
+ model = context.getModel(keys, dimensions);
+ }
+ }
+ catch (final Exception e)
+ {
+ errorMessage = "An error occured while trying to open the model using schemaUri: " + schemaUri + ", Keys: "
+ + keys + "\nError: " + e.toString() + " - message: " + e.getMessage() + " - stack trace:\n"
+ + ExceptionUtils.getStackTrace(e);
+ }
+
+ if (model == null)
+ {
+ if (errorMessage == null)
+ {
+ errorMessage = "Model could not be opened: (schemaUri: " + schemaUri + ", id: " + keys + ", heapId: "
+ + heapId + ")";
+ }
+
+ showError(errorMessage);
+ return null;
+ }
+
+ return (M) model;
+ }
+
+ public Window openModelWindow(final Model model)
+ {
+
+ final URI schemaUri = model.getSchemaUri();
+ addKeySlotValuesToHistory(schemaUri, model.getKeys());
+
+ final String title = ModelWindow.getModelWindowTitle(model);
+
+ final ModelWindow modelWindow = new ModelWindow(this, title, new Component[]{
+ new TerminalAppButtonPanel(_CloseAction),
+ new TerminalAppButtonPanel(_PrintPreviewAction),
+ new TerminalAppButtonPanel(_SetOriginAction),
+ new TerminalAppButtonPanel(_SaveAction)
+ });
+
+ modelWindow.setModel(model);
+
+ // showWindow(modelWindow, Position.OVERLAPPING);
+ showWindow(modelWindow, Position.FULL_SCREEN);
+
+ return modelWindow;
+ }
+
+ public Window openModelWindow(final URI schemaUri, final Keys keys, final UUID heapId)
+ {
+
+ if (keys == null || keys.getCount() == 0)
+ {
+ showError("\nPlease enter one (or more) key value(s).");
+ return null;
+ }
+
+ final Model model = openModel(schemaUri, keys, heapId);
+ if (model != null)
+ {
+
+ return openModelWindow(model);
+ }
+
+ return null;
+ }
+
+ public void showMainMenuBarWindow()
+ {
+ // TODO: Make themes pluggable in a different way
+ final GUIScreen guiScreen = getGuiScreen();
+ guiScreen.setTheme(getDefaultMenuTheme());
+
+ showWindow(getMainMenuBarWindow());
+ }
+
+ public void showSplashWindow()
+ {
+
+ final Random easterEggDice = new Random();
+ final int diceRoll = easterEggDice.nextInt(100) + 1;
+ final Theme theme;
+ switch (diceRoll)
+ {
+ case 77:
+ {
+ // Rolled double 7s on 2 d10!
+ theme = getLightTheme();
+ break;
+ }
+
+ default:
+ {
+ theme = getDefaultSplashTheme();
+ break;
+ }
+ }
+
+ final GUIScreen guiScreen = getGuiScreen();
+ guiScreen.setTheme(theme);
+
+ showWindow(getSplashWindow());
+ }
+
+ private void addKeySlotValuesToHistory(final URI historyListSchemaUri, final Keys keys)
+ {
+
+ final Context context = getContext();
+ final SchemaLoader schemaLoader = context.getSchemaLoader();
+ if (keys == null || keys.getCount() == 0)
+ {
+ return;
+ }
+
+ for (final URI keyedSchemaUri : keys.getKeyedSchemaUris())
+ {
+ final Object keyValue = keys.getValue(keyedSchemaUri);
+
+ final Prototype keyDeclaredPrototype = schemaLoader.getPrototype(keyedSchemaUri);
+ if (keyDeclaredPrototype == null)
+ {
+ continue;
+ }
+ final SortedSet keySlotNames = keyDeclaredPrototype.getDeclaredKeySlotNames();
+
+ if (keySlotNames == null || keySlotNames.isEmpty())
+ {
+ continue;
+ }
+
+ if (keySlotNames.size() == 1)
+ {
+ final String keySlotName = keySlotNames.first();
+
+ addSlotValueToHistory(historyListSchemaUri, keySlotName, keyValue);
+ }
+ else
+ {
+ final CompositeKey compositeKey = (CompositeKey) keyValue;
+ if (compositeKey == null)
+ {
+ continue;
+ }
+
+ final Map compositeKeySlots = compositeKey.getKeySlots();
+ for (final String compositeKeySlotName : compositeKeySlots.keySet())
+ {
+ final Object compositeKeySlotValue = compositeKeySlots.get(compositeKeySlotName);
+ if (compositeKeySlotValue != null)
+ {
+ addSlotValueToHistory(historyListSchemaUri, compositeKeySlotName, compositeKeySlotValue);
+ }
+ }
+ }
+ }
+ }
+
+ private void compileSlotValueHistoryLists(final List slotValueHistoryLists)
+ {
+
+ final Context context = getContext();
+ final SchemaLoader schemaLoader = context.getSchemaLoader();
+ final SyntaxLoader syntaxLoader = context.getSyntaxLoader();
+
+ for (final SlotValueHistoryListModel slotValueHistoryList : slotValueHistoryLists)
+ {
+ final URI historyListSchemaUri = slotValueHistoryList.getHistoryListSchemaUri();
+
+ _SlotValueHistoryModels.put(historyListSchemaUri, slotValueHistoryList);
+
+ final Prototype prototype;
+ try
+ {
+ prototype = schemaLoader.getPrototype(historyListSchemaUri);
+ }
+ catch (PrototypeException e)
+ {
+ LOG.debug("Failed to load prototype for: " + historyListSchemaUri, e);
+ continue;
+ }
+
+ if (prototype == null)
+ {
+ LOG.debug("Failed to load prototype for: " + historyListSchemaUri);
+ continue;
+ }
+
+ final List slotValueEntries = slotValueHistoryList.getSlotValueEntries();
+
+ for (final EntryModel entry : slotValueEntries)
+ {
+ final String slotName = entry.getName();
+ final String slotValueString = entry.getValue();
+
+ final ProtoSlot protoSlot = prototype.getProtoSlot(slotName);
+ final Object slotValue = syntaxLoader.parseSyntacticText(slotValueString, protoSlot.getHeapValueType());
+
+ final SortedSet slotValueHistory = getSlotValueHistory(historyListSchemaUri, slotName);
+ slotValueHistory.add(slotValue);
+ }
+ }
+
+ }
+
+ public LoadApiDialog getLoadApiDialog()
+ {
+
+ return _LoadApiDialog;
+ }
+
+ public PrintDialog getPrintDialog()
+ {
+
+ return _PrintDialog;
+ }
+
+}
+
+
+
diff --git a/cli/src/main/java/org/wrml/werminal/WerminalException.java b/cli/src/main/java/org/wrml/werminal/WerminalException.java
new file mode 100644
index 0000000..95a9e12
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/WerminalException.java
@@ -0,0 +1,44 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal;
+
+import org.wrml.werminal.terminal.TerminalAppException;
+
+/**
+ * The {@link Werminal}'s associated error type.
+ */
+public class WerminalException extends TerminalAppException
+{
+
+ private static final long serialVersionUID = 1L;
+
+ WerminalException(final String message, final Throwable cause, final Werminal werminal)
+ {
+
+ super(message, cause, werminal);
+
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/AddAction.java b/cli/src/main/java/org/wrml/werminal/action/AddAction.java
new file mode 100644
index 0000000..1fbf2ed
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/AddAction.java
@@ -0,0 +1,79 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.dialog.ListValueDialog;
+
+import java.lang.reflect.Type;
+import java.net.URI;
+
+public class AddAction extends WerminalAction
+{
+
+ private ListValueDialog _ListValueDialog;
+
+ public AddAction(final Werminal werminal)
+ {
+
+ super(werminal, "Add...");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+
+ final ListValueDialog listValueDialog = getListValueDialog();
+ Object initialValue = null;
+
+ final Type listElementType = listValueDialog.getListElementType();
+ if (String.class.equals(listElementType))
+ {
+
+ }
+ else if (URI.class.equals(listElementType))
+ {
+ // TODO: Only do this for base schema uris slot
+ initialValue = werminal.createSchemaUri("MyBaseModel");
+ }
+
+ listValueDialog.addFormField(initialValue);
+
+ }
+
+ public ListValueDialog getListValueDialog()
+ {
+
+ return _ListValueDialog;
+ }
+
+ public void setListValueDialog(final ListValueDialog listValueDialog)
+ {
+
+ _ListValueDialog = listValueDialog;
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/CancelAction.java b/cli/src/main/java/org/wrml/werminal/action/CancelAction.java
new file mode 100644
index 0000000..96eeb96
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/CancelAction.java
@@ -0,0 +1,38 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+public class CancelAction extends CloseBeforeAction
+{
+
+ public CancelAction(final Werminal werminal)
+ {
+
+ super(werminal, "Cancel");
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/CloseAfterAction.java b/cli/src/main/java/org/wrml/werminal/action/CloseAfterAction.java
new file mode 100644
index 0000000..4159332
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/CloseAfterAction.java
@@ -0,0 +1,63 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+public class CloseAfterAction extends DelegatingPhasedWerminalAction
+{
+
+ public CloseAfterAction(final Werminal werminal)
+ {
+
+ super(werminal, "Close");
+ }
+
+ public CloseAfterAction(final Werminal werminal, final String title)
+ {
+
+ super(werminal, title);
+ }
+
+ public CloseAfterAction(final Werminal werminal, final String title, final WerminalAction delegate)
+ {
+
+ super(werminal, title, delegate);
+ }
+
+ public CloseAfterAction(final Werminal werminal, final WerminalAction delegate)
+ {
+
+ super(werminal, delegate);
+ }
+
+ @Override
+ protected void postDoIt()
+ {
+
+ getWerminal().closeTopWindow();
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/CloseBeforeAction.java b/cli/src/main/java/org/wrml/werminal/action/CloseBeforeAction.java
new file mode 100644
index 0000000..de6e038
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/CloseBeforeAction.java
@@ -0,0 +1,64 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+public class CloseBeforeAction extends DelegatingPhasedWerminalAction
+{
+
+ public CloseBeforeAction(final Werminal werminal)
+ {
+
+ super(werminal, "Close");
+ }
+
+ public CloseBeforeAction(final Werminal werminal, final String title)
+ {
+
+ super(werminal, title);
+ }
+
+ public CloseBeforeAction(final Werminal werminal, final String title, final WerminalAction delegate)
+ {
+
+ super(werminal, title, delegate);
+ }
+
+ public CloseBeforeAction(final Werminal werminal, final WerminalAction delegate)
+ {
+
+ super(werminal, delegate);
+ }
+
+ @Override
+ protected boolean preDoIt()
+ {
+
+ getWerminal().closeTopWindow();
+ return true;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/DelegatingPhasedWerminalAction.java b/cli/src/main/java/org/wrml/werminal/action/DelegatingPhasedWerminalAction.java
new file mode 100644
index 0000000..7121032
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/DelegatingPhasedWerminalAction.java
@@ -0,0 +1,85 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+public class DelegatingPhasedWerminalAction extends PhasedWerminalAction
+{
+
+ private final WerminalAction _Delegate;
+
+ public DelegatingPhasedWerminalAction(final Werminal werminal, final String title)
+ {
+
+ this(werminal, title, null);
+ }
+
+ public DelegatingPhasedWerminalAction(final Werminal werminal, final String title, final WerminalAction delegate)
+ {
+
+ super(werminal, (title != null) ? title : delegate.getTitle());
+ _Delegate = delegate;
+ }
+
+ public DelegatingPhasedWerminalAction(final Werminal werminal, final WerminalAction delegate)
+ {
+
+ this(werminal, null, delegate);
+ }
+
+
+ public final WerminalAction getDelegate()
+ {
+
+ return _Delegate;
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final WerminalAction delegate = getDelegate();
+ if (delegate != null)
+ {
+ delegate.doAction();
+ }
+ return true;
+ }
+
+ @Override
+ protected void postDoIt()
+ {
+
+ }
+
+ @Override
+ protected boolean preDoIt()
+ {
+
+ return true;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/DeleteAction.java b/cli/src/main/java/org/wrml/werminal/action/DeleteAction.java
new file mode 100644
index 0000000..bafbfd9
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/DeleteAction.java
@@ -0,0 +1,61 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.model.Model;
+import org.wrml.runtime.Context;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.window.ModelWindow;
+
+public class DeleteAction extends WerminalAction
+{
+
+ public DeleteAction(final Werminal werminal)
+ {
+
+ super(werminal, "Delete");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+ final ModelWindow modelWindow = (ModelWindow) werminal.getTopWindow();
+ final Model model = modelWindow.syncModel();
+ try
+ {
+
+ final Context context = getContext();
+ context.deleteModel(model.getKeys(), model.getDimensions());
+
+ }
+ catch (final Exception t)
+ {
+ werminal.showError("An unexpected error occurred while deleting the model.", t);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/cli/src/main/java/org/wrml/werminal/action/EnumValueSelectionConfirmationAction.java b/cli/src/main/java/org/wrml/werminal/action/EnumValueSelectionConfirmationAction.java
new file mode 100644
index 0000000..609641f
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/EnumValueSelectionConfirmationAction.java
@@ -0,0 +1,78 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.dialog.EnumValueDialog;
+
+public class EnumValueSelectionConfirmationAction extends CloseBeforeAction
+{
+
+ private final WerminalTextBox _ValueTextBox;
+
+ private EnumValueDialog _EnumValueDialog;
+
+ public EnumValueSelectionConfirmationAction(final Werminal werminal, final WerminalTextBox valueTextBox)
+ {
+
+ super(werminal, "OK");
+ _ValueTextBox = valueTextBox;
+ }
+
+ public EnumValueDialog getEnumValueDialog()
+ {
+
+ return _EnumValueDialog;
+ }
+
+ public WerminalTextBox getValueTextBox()
+ {
+
+ return _ValueTextBox;
+ }
+
+ public void setEnumValueDialog(final EnumValueDialog enumValueDialog)
+ {
+
+ _EnumValueDialog = enumValueDialog;
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final Enum> selectedValue = _EnumValueDialog.getSelectedValue();
+ final Enum> currentValue = _ValueTextBox.getValue();
+
+ if (selectedValue != currentValue)
+ {
+ _ValueTextBox.setValue(selectedValue, false);
+ }
+
+ return true;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/ExitAction.java b/cli/src/main/java/org/wrml/werminal/action/ExitAction.java
new file mode 100644
index 0000000..c148cf2
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/ExitAction.java
@@ -0,0 +1,38 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+public class ExitAction extends CloseBeforeAction
+{
+
+ public ExitAction(final Werminal werminal)
+ {
+
+ super(werminal, "Exit");
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/FormFieldOpenAction.java b/cli/src/main/java/org/wrml/werminal/action/FormFieldOpenAction.java
new file mode 100644
index 0000000..2df5ae6
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/FormFieldOpenAction.java
@@ -0,0 +1,333 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import com.googlecode.lanterna.gui.GUIScreen.Position;
+import com.googlecode.lanterna.gui.Window;
+import org.wrml.model.Model;
+import org.wrml.model.rest.Link;
+import org.wrml.model.rest.LinkRelation;
+import org.wrml.model.rest.LinkTemplate;
+import org.wrml.model.rest.Method;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.Dimensions;
+import org.wrml.runtime.DimensionsBuilder;
+import org.wrml.runtime.Keys;
+import org.wrml.runtime.rest.ApiLoader;
+import org.wrml.runtime.rest.ApiNavigator;
+import org.wrml.runtime.rest.Resource;
+import org.wrml.runtime.schema.SchemaLoader;
+import org.wrml.runtime.schema.ValueType;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.component.FormField;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.dialog.EnumValueDialog;
+import org.wrml.werminal.dialog.InvocationDialog;
+import org.wrml.werminal.dialog.ListValueDialog;
+import org.wrml.werminal.dialog.NewOrOpenModelDialog;
+import org.wrml.werminal.window.ModelWindow;
+
+import java.net.URI;
+import java.util.UUID;
+
+public class FormFieldOpenAction extends WerminalAction
+{
+
+ private FormField _FormField;
+
+ public FormFieldOpenAction(final Werminal werminal)
+ {
+
+ super(werminal, "...");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+ final Context context = werminal.getContext();
+ final SchemaLoader schemaLoader = context.getSchemaLoader();
+ final ApiLoader apiLoader = context.getApiLoader();
+ final Window topWindow = werminal.getTopWindow();
+
+ final FormField formField = getFormField();
+ final String formFieldName = formField.getFieldName();
+ final WerminalTextBox valueTextBox = formField.getFieldValueTextBox();
+ final ValueType valueType = valueTextBox.getValueType();
+ final Object currentValue = valueTextBox.getValue();
+
+ switch (valueType)
+ {
+ case Boolean:
+ {
+ Boolean currentBooleanValue = (Boolean) currentValue;
+ if (currentBooleanValue == null)
+ {
+ currentBooleanValue = Boolean.FALSE;
+ }
+ valueTextBox.setValue(!(currentBooleanValue), false);
+
+ break;
+ }
+ case Link:
+ {
+ final Link link = (Link) currentValue;
+ if (link == null)
+ {
+ if (!(topWindow instanceof ModelWindow))
+ {
+
+ final String dialogTitle = "How would you like to initialize \"" + formFieldName + "\"?";
+
+ final NewOrOpenModelDialog newOrOpenModelDialog =
+ new NewOrOpenModelDialog(werminal, dialogTitle, new CancelAction(werminal), formField);
+
+ werminal.showWindow(newOrOpenModelDialog, Position.CENTER);
+ }
+ else
+ {
+
+ werminal.showMessageBox("Empty Link Slot",
+ "This Link slot value is empty; it is not \"clickable\".");
+ }
+
+ break;
+ }
+
+ final URI linkRelationUri = link.getRel();
+ final LinkRelation linkRelation = apiLoader.loadLinkRelation(linkRelationUri);
+ final Method method = linkRelation.getMethod();
+
+ if (topWindow instanceof ListValueDialog)
+ {
+ if (method != Method.Get)
+ {
+ werminal.showMessageBox("Not Implemented", "Support for referencing links with the method: "
+ + method + " (HTTP " + method.getProtocolGivenName() + ") has not been implemented for Links within a List.");
+
+ break;
+ }
+
+ final URI documentSchemaUri = schemaLoader.getDocumentSchemaUri();
+ final URI href = link.getHref();
+ if (href != null)
+ {
+ final ApiNavigator apiNavigator = apiLoader.getParentApiNavigator(href);
+ final Resource endpoint = apiNavigator.getResource(href);
+ final LinkTemplate referenceTemplate = endpoint.getReferenceTemplates().get(linkRelationUri);
+ final URI responseSchemaUri = referenceTemplate.getResponseSchemaUri();
+
+ final URI schemaUri;
+ if (responseSchemaUri != null)
+ {
+ schemaUri = responseSchemaUri;
+ }
+ else
+ {
+ schemaUri = documentSchemaUri;
+ }
+
+ final Keys keys = apiLoader.buildDocumentKeys(href, schemaUri);
+ final Dimensions dimensions = new DimensionsBuilder(schemaUri).toDimensions();
+ final Model referencedModel = context.getModel(keys, dimensions);
+ if (referencedModel == null)
+ {
+ werminal.showMessageBox("404", "Failed to open linked document.");
+ break;
+ }
+
+ werminal.openModelWindow(referencedModel);
+ }
+ break;
+ }
+ else if (topWindow instanceof ModelWindow)
+ {
+ final ModelWindow modelWindow = (ModelWindow) werminal.getTopWindow();
+ final Model model = modelWindow.syncModel();
+
+
+ switch (method)
+ {
+ case Delete:
+ {
+ // TODO: Prompt to delete
+ werminal.showMessageBox("Not Implemented", "Support for referencing links with the method: "
+ + method + " (HTTP " + method.getProtocolGivenName()
+ + ") has not been implemented in Werminal (yet).");
+ break;
+
+ }
+ case Get:
+ {
+ final Model referencedModel = model.reference(formFieldName);
+ werminal.openModelWindow(referencedModel);
+ break;
+ }
+ case Invoke:
+ {
+
+ final String dialogTitle = Method.Invoke.name() + " (" + Method.Invoke.getProtocolGivenName() + ") ";
+
+
+ try
+ {
+ final InvocationDialog invocationDialog = new InvocationDialog(werminal, dialogTitle, model, formField);
+ werminal.showWindow(invocationDialog, Position.CENTER);
+ }
+ catch (ClassNotFoundException e)
+ {
+ werminal.showError("Could not load Schema Java interface.", e);
+ return;
+ }
+
+
+ break;
+ }
+ case Metadata:
+ {
+ werminal.showMessageBox("Not Implemented", "Support for referencing links with the method: "
+ + method + " (HTTP " + method.getProtocolGivenName()
+ + ") has not been implemented in Werminal (yet).");
+ break;
+
+ }
+ case Options:
+ {
+ werminal.showMessageBox("Not Implemented", "Support for referencing links with the method: "
+ + method + " (HTTP " + method.getProtocolGivenName()
+ + ") has not been implemented in Werminal (yet).");
+ break;
+
+ }
+ case Save:
+ {
+ // TODO: Prompt to save
+ werminal.showMessageBox("Not Implemented", "Support for referencing links with the method: "
+ + method + " (HTTP " + method.getProtocolGivenName()
+ + ") has not been implemented in Werminal (yet).");
+ break;
+
+ }
+ default:
+ {
+ werminal.showMessageBox("Not Implemented", "Support for referencing links with the method: "
+ + method + " (HTTP " + method.getProtocolGivenName()
+ + ") has not been implemented in Werminal (yet).");
+ break;
+ }
+
+ }
+
+ break;
+
+ }
+ else
+ {
+ werminal.showMessageBox("Not Implemented", "Support for referencing Link slots has not been implemented (yet).");
+ }
+
+ break;
+ }
+
+ case List:
+ {
+ // werminal.showMessageBox("Not Implemented",
+ // "Support for opening List slots has not been implemented (yet).");
+ werminal.openListDialog(formField);
+ break;
+ }
+ case Model:
+ {
+
+ if (currentValue == null)
+ {
+
+ final String dialogTitle = "How would you like to initialize \"" + formFieldName + "\"?";
+
+ final NewOrOpenModelDialog newOrOpenModelDialog =
+ new NewOrOpenModelDialog(werminal, dialogTitle, new CancelAction(werminal), formField);
+
+ werminal.showWindow(newOrOpenModelDialog, Position.CENTER);
+
+ }
+ else if (currentValue instanceof Model)
+ {
+ final Model nestedModel = (Model) currentValue;
+ werminal.openModelWindow(nestedModel);
+ }
+ break;
+ }
+ case SingleSelect:
+ {
+ final Enum> selectedValue = (Enum>) currentValue;
+
+ final EnumValueSelectionConfirmationAction enumValueSelectionConfirmationAction = new EnumValueSelectionConfirmationAction(
+ werminal, valueTextBox);
+
+ final EnumValueDialog enumValueDialog = new EnumValueDialog(werminal, "Select One Value",
+ enumValueSelectionConfirmationAction, new CancelAction(werminal));
+ enumValueSelectionConfirmationAction.setEnumValueDialog(enumValueDialog);
+
+ enumValueDialog.setSelectedValue(selectedValue);
+
+ werminal.showWindow(enumValueDialog, Position.CENTER);
+
+ break;
+ }
+ case Text:
+
+
+ if (currentValue == null && valueTextBox.getHeapValueType().equals(UUID.class))
+ {
+ valueTextBox.setValue(UUID.randomUUID(), false);
+ }
+ else
+ {
+ werminal.showMessageBox("Text (Not Implemented)",
+ "Support for opening Text slots has not been implemented (yet).");
+ }
+ break;
+
+ default:
+ werminal.showMessageBox("Not Implemented",
+ "Support for opening this slot type has not been implemented (yet).");
+ break;
+ }
+ }
+
+ public FormField getFormField()
+ {
+
+ return _FormField;
+ }
+
+ public void setFormField(final FormField formField)
+ {
+
+ _FormField = formField;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/HelpGuideAction.java b/cli/src/main/java/org/wrml/werminal/action/HelpGuideAction.java
new file mode 100644
index 0000000..dd79e09
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/HelpGuideAction.java
@@ -0,0 +1,75 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+import java.io.IOException;
+import java.net.URI;
+
+public class HelpGuideAction extends WerminalAction
+{
+
+ private final URI GUIDE_URI = URI.create("http://www.wrml.org/werminal/WerminalMastersHandbook.pdf");
+
+ public HelpGuideAction(final Werminal werminal)
+ {
+
+ super(werminal, "Help Guide");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+
+ if (!java.awt.Desktop.isDesktopSupported())
+ {
+ werminal.showSplashWindow();
+ return;
+ }
+
+ final java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
+
+ if (!desktop.isSupported(java.awt.Desktop.Action.BROWSE))
+ {
+ werminal.showSplashWindow();
+ return;
+ }
+
+ try
+ {
+ desktop.browse(GUIDE_URI);
+ }
+ catch (final IOException e)
+ {
+ System.err.println(e.getMessage());
+ werminal.showSplashWindow();
+ return;
+ }
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/ListValueDialogConfirmationAction.java b/cli/src/main/java/org/wrml/werminal/action/ListValueDialogConfirmationAction.java
new file mode 100644
index 0000000..5dfd7e3
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/ListValueDialogConfirmationAction.java
@@ -0,0 +1,81 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.apache.commons.collections.ListUtils;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.dialog.ListValueDialog;
+
+import java.util.List;
+
+public class ListValueDialogConfirmationAction extends CloseBeforeAction
+{
+
+ private final WerminalTextBox _ValueTextBox;
+
+ private ListValueDialog _ListValueDialog;
+
+ public ListValueDialogConfirmationAction(final Werminal werminal, final WerminalTextBox valueTextBox)
+ {
+
+ super(werminal, "OK");
+ _ValueTextBox = valueTextBox;
+ }
+
+ public ListValueDialog getListValueDialog()
+ {
+
+ return _ListValueDialog;
+ }
+
+ public WerminalTextBox getValueTextBox()
+ {
+
+ return _ValueTextBox;
+ }
+
+ public void setListValueDialog(final ListValueDialog listValueDialog)
+ {
+
+ _ListValueDialog = listValueDialog;
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final List> dialogValue = _ListValueDialog.getList();
+ final List> currentValue = _ValueTextBox.getValue();
+
+ if (!ListUtils.isEqualList(dialogValue, currentValue))
+ {
+ _ValueTextBox.setValue(dialogValue, false);
+ }
+
+ return true;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/LoadAction.java b/cli/src/main/java/org/wrml/werminal/action/LoadAction.java
new file mode 100644
index 0000000..10cfc6d
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/LoadAction.java
@@ -0,0 +1,164 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.model.Model;
+import org.wrml.model.rest.Api;
+import org.wrml.model.rest.Document;
+import org.wrml.model.rest.LinkRelation;
+import org.wrml.model.schema.Schema;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.rest.ApiLoader;
+import org.wrml.runtime.rest.SystemApi;
+import org.wrml.runtime.rest.SystemLinkRelation;
+import org.wrml.runtime.schema.SchemaLoader;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.window.ModelWindow;
+
+import java.net.URI;
+
+public class LoadAction extends WerminalAction
+{
+
+ /**
+ *
+ * Returns true if the specified {@link Model} is loadable by the WRML runtime. Loadability only
+ * applies to built-in, system {@link Model}s such as {@link Api}, {@link LinkRelation}s, and {@link Schema}.
+ *
+ *
+ * Loading these {@link Model}s at runtime enables a WRML runtime system to change and evolve dynamically (without
+ * restart).
+ *
+ */
+ public final static boolean appliesTo(final Model model)
+ {
+
+ if (!(model instanceof Document))
+ {
+ return false;
+ }
+
+ final URI uri = ((Document) model).getUri();
+ if (uri == null)
+ {
+ return false;
+ }
+
+ if (model instanceof Api)
+ {
+
+ for (final SystemApi systemApi : SystemApi.values())
+ {
+ if (systemApi.getUri().equals(uri))
+ {
+ return false;
+ }
+ }
+
+ return true;
+
+ }
+ else if (model instanceof LinkRelation)
+ {
+
+ for (final SystemLinkRelation systemLinkRelation : SystemLinkRelation.values())
+ {
+ if (systemLinkRelation.getUri().equals(uri))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ else if (model instanceof Schema)
+ {
+ // If it got this far, the Schema is already "loaded" but it may not be class generated, loaded, or
+ // (finally) prototyped by the runtime. Check if we already have a Prototype associated with the Schema,
+ // if so there is no more "loading" to be done with the Schema.
+ final SchemaLoader schemaLoader = model.getContext().getSchemaLoader();
+ return !schemaLoader.isPrototyped(uri);
+ }
+
+ return false;
+ }
+
+ public LoadAction(final Werminal werminal)
+ {
+
+ super(werminal, "Load");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+ final ModelWindow modelWindow = (ModelWindow) werminal.getTopWindow();
+ final Model model = modelWindow.syncModel();
+
+ if (model == null)
+ {
+ werminal.showError("The model is null.");
+ }
+
+ final Context context = werminal.getContext();
+ final ApiLoader apiLoader = context.getApiLoader();
+
+ if (!LoadAction.appliesTo(model))
+ {
+ werminal.showError("The model (schema: " + model.getSchemaUri() + ") is not loadable.");
+ }
+
+ final URI uri = ((Document) model).getUri();
+ if (uri == null)
+ {
+ return;
+ }
+
+ if (model instanceof Api)
+ {
+ final Api api = (Api) model;
+ apiLoader.loadApi(api);
+ }
+ else if (model instanceof LinkRelation)
+ {
+ final LinkRelation linkRelation = (LinkRelation) model;
+ apiLoader.loadLinkRelation(linkRelation);
+ }
+ else if (model instanceof Schema)
+ {
+ final Schema schema = (Schema) model;
+ final SchemaLoader schemaLoader = context.getSchemaLoader();
+ schemaLoader.load(schema);
+ schemaLoader.getPrototype(uri);
+ }
+
+ modelWindow.updateLoadButton();
+
+ werminal.showMessageBox(getTitle() + " Complete", "\n\nThe load operation completed successfully.\n");
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/NewAction.java b/cli/src/main/java/org/wrml/werminal/action/NewAction.java
new file mode 100644
index 0000000..37f35cb
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/NewAction.java
@@ -0,0 +1,46 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+public class NewAction extends WerminalAction
+{
+
+ public NewAction(final Werminal werminal)
+ {
+
+ super(werminal, "New...");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+ werminal.showWindow(werminal.getNewModelDialog());
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/NewConfirmationAction.java b/cli/src/main/java/org/wrml/werminal/action/NewConfirmationAction.java
new file mode 100644
index 0000000..0735ccb
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/NewConfirmationAction.java
@@ -0,0 +1,67 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.runtime.Context;
+import org.wrml.runtime.schema.Prototype;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.dialog.NewModelDialog;
+
+import java.net.URI;
+
+public class NewConfirmationAction extends CloseBeforeAction
+{
+
+ public NewConfirmationAction(final Werminal werminal)
+ {
+
+ super(werminal, "OK");
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final Werminal werminal = getWerminal();
+
+ final NewModelDialog newModelDialog = werminal.getNewModelDialog();
+ final URI schemaUri = newModelDialog.getSchemaUri();
+
+ final Context context = werminal.getContext();
+ final Prototype prototype = context.getSchemaLoader().getPrototype(schemaUri);
+ if (prototype.isAbstract())
+ {
+ werminal.showError("\""
+ + schemaUri
+ + "\" is *Abstract*, meaning that models cannot be created based on this type directly. Try a subschema?");
+ return false;
+ }
+
+ werminal.newModelWindow(schemaUri);
+
+ return true;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/NewModelAction.java b/cli/src/main/java/org/wrml/werminal/action/NewModelAction.java
new file mode 100644
index 0000000..1d03749
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/NewModelAction.java
@@ -0,0 +1,149 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import com.googlecode.lanterna.gui.GUIScreen.Position;
+import org.wrml.model.Model;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.schema.Prototype;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.component.FormField;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.dialog.NewModelDialog;
+
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.SortedSet;
+
+public class NewModelAction extends CloseBeforeAction
+{
+
+ private final FormField _FormField;
+
+ public NewModelAction(final Werminal werminal, final FormField formField)
+ {
+
+ super(werminal, "New...");
+ _FormField = formField;
+ }
+
+ public FormField getFormField()
+ {
+
+ return _FormField;
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final Werminal werminal = getWerminal();
+ final FormField formField = getFormField();
+ final Context context = werminal.getContext();
+
+ final ConfirmAction confirmAction = new ConfirmAction(werminal);
+
+ final WerminalTextBox valueTextBox = formField.getFieldValueTextBox();
+ final Type heapValueType = valueTextBox.getHeapValueType();
+ final URI schemaUri = context.getSchemaLoader().getTypeUri(heapValueType);
+ final String dialogTitle = "New \"" + schemaUri + "\"";
+ final NewModelDialog newModelDialog = new NewModelDialog(werminal, dialogTitle, confirmAction,
+ werminal.getCancelAction());
+
+ confirmAction.setNewModelDialog(newModelDialog);
+
+ final SortedSet historyItems = werminal.getNewModelDialog().getSchemaUriHistoryCheckBoxList().getItems();
+ newModelDialog.getSchemaUriHistoryCheckBoxList().addItems(historyItems);
+
+ newModelDialog.setSchemaUri(schemaUri);
+ werminal.showWindow(newModelDialog, Position.CENTER);
+
+ return true;
+ }
+
+ private class ConfirmAction extends CloseBeforeAction
+ {
+
+ private NewModelDialog _NewModelDialog;
+
+ public ConfirmAction(final Werminal werminal)
+ {
+
+ super(werminal, "OK");
+ }
+
+ public NewModelDialog getNewModelDialog()
+ {
+
+ return _NewModelDialog;
+ }
+
+ public void setNewModelDialog(final NewModelDialog newModelDialog)
+ {
+
+ _NewModelDialog = newModelDialog;
+
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final Werminal werminal = getWerminal();
+ final FormField formField = getFormField();
+
+ final NewModelDialog newModelDialog = getNewModelDialog();
+ final URI schemaUri = newModelDialog.getSchemaUri();
+
+ final Context context = werminal.getContext();
+
+ final Prototype prototype = context.getSchemaLoader().getPrototype(schemaUri);
+ if (prototype.isAbstract())
+ {
+ werminal.showError("\""
+ + schemaUri
+ + "\" is *Abstract*, meaning that models cannot be created based on this type directly. Try a subschema?");
+ return false;
+ }
+
+ try
+ {
+ final Model newModel = context.newModel(schemaUri);
+ formField.getFieldValueTextBox().setValue(newModel, false);
+ werminal.openModelWindow(newModel);
+ }
+ catch (final Exception t)
+ {
+ final String errorMessage = "An unexpected error has occurred.";
+ werminal.showError(errorMessage, t);
+ Werminal.LOG.error(errorMessage + " (" + t.getMessage() + ")", t);
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/OpenAction.java b/cli/src/main/java/org/wrml/werminal/action/OpenAction.java
new file mode 100644
index 0000000..92c705b
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/OpenAction.java
@@ -0,0 +1,45 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+public class OpenAction extends WerminalAction
+{
+
+ public OpenAction(final Werminal werminal)
+ {
+
+ super(werminal, "Open...");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+ werminal.showWindow(werminal.getOpenModelDialog());
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/OpenConfirmationAction.java b/cli/src/main/java/org/wrml/werminal/action/OpenConfirmationAction.java
new file mode 100644
index 0000000..c1e1bfc
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/OpenConfirmationAction.java
@@ -0,0 +1,135 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import com.googlecode.lanterna.gui.GUIScreen;
+import com.googlecode.lanterna.gui.Window;
+import com.googlecode.lanterna.gui.dialog.DialogButtons;
+import com.googlecode.lanterna.gui.dialog.DialogResult;
+import com.googlecode.lanterna.gui.dialog.MessageBox;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.Keys;
+import org.wrml.runtime.rest.ApiLoader;
+import org.wrml.runtime.rest.ApiNavigator;
+import org.wrml.runtime.schema.SchemaLoader;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.dialog.LoadApiDialog;
+import org.wrml.werminal.dialog.OpenModelDialog;
+
+import java.net.URI;
+
+public class OpenConfirmationAction extends CloseBeforeAction
+{
+
+ public OpenConfirmationAction(final Werminal werminal)
+ {
+
+ super(werminal, "OK");
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final Werminal werminal = getWerminal();
+ final Context context = werminal.getContext();
+ final SchemaLoader schemaLoader = context.getSchemaLoader();
+
+ final OpenModelDialog openModelDialog = werminal.getOpenModelDialog();
+ final URI schemaUri = openModelDialog.getSchemaUri();
+ final Keys keys = openModelDialog.getKeys();
+
+ URI uri = null;
+ ApiNavigator apiNavigator = null;
+
+ if (keys != null)
+ {
+ final ApiLoader apiLoader = context.getApiLoader();
+ uri = keys.getValue(schemaLoader.getDocumentSchemaUri());
+ if (uri != null)
+ {
+ apiNavigator = apiLoader.getParentApiNavigator(uri);
+ }
+ }
+
+ Window window = null;
+ boolean cancelled = false;
+
+ if (schemaUri == null)
+ {
+ werminal.showError("\nPlease indicate the type of data that you would like to open by entering a Schema URI value.\n\n ");
+ cancelled = true;
+ }
+ else if (keys == null || keys.getKeyedSchemaUris().isEmpty())
+ {
+ werminal.showError("\nPlease enter one or more key values to identify the data that you would like to open.\n\n ");
+ cancelled = true;
+ }
+ else if (uri != null && !schemaLoader.getApiSchemaUri().equals(schemaUri) && apiNavigator == null)
+ {
+
+ final GUIScreen owner = werminal.getGuiScreen();
+ final String title = "Load Parent REST API Metadata?";
+ final String message = werminal
+ .formatMessageBoxTextToWrap("\nThe URI:\n\n\t"
+ + uri
+ + "\n\nIs not parented by any loaded REST API metadata.\n\nDo you wish to load this URI's parent REST API metadata now?\n\n ");
+ final DialogButtons buttons = DialogButtons.YES_NO_CANCEL;
+ final DialogResult result = MessageBox.showMessageBox(owner, title, message, buttons);
+
+ if (result == DialogResult.YES)
+ {
+ final LoadApiDialog loadApiDialog = werminal.getLoadApiDialog();
+ loadApiDialog.setApiUri(uri);
+ werminal.showWindow(loadApiDialog);
+ if (loadApiDialog.isCancelled())
+ {
+ cancelled = true;
+ }
+
+ }
+ else if (result == DialogResult.CANCEL)
+ {
+ cancelled = true;
+ }
+
+ }
+
+ if (!cancelled)
+ {
+ window = werminal.openModelWindow(schemaUri, keys, openModelDialog.getHeapId());
+ }
+
+ if (window == null)
+ {
+ // Kind of a hack, re-open the open dialog.
+ werminal.getOpenAction().doAction();
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/OpenModelAction.java b/cli/src/main/java/org/wrml/werminal/action/OpenModelAction.java
new file mode 100644
index 0000000..e5e2a6f
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/OpenModelAction.java
@@ -0,0 +1,144 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import com.googlecode.lanterna.gui.GUIScreen.Position;
+import org.wrml.model.Model;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.Keys;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.component.FormField;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.dialog.OpenModelDialog;
+
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.SortedSet;
+import java.util.UUID;
+
+public class OpenModelAction extends CloseBeforeAction
+{
+
+ private final FormField _FormField;
+
+ public OpenModelAction(final Werminal werminal, final FormField formField)
+ {
+
+ super(werminal, "Open...");
+ _FormField = formField;
+ }
+
+ public FormField getFormField()
+ {
+
+ return _FormField;
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final Werminal werminal = getWerminal();
+ final FormField formField = getFormField();
+ final Context context = werminal.getContext();
+
+ final ConfirmAction confirmAction = new ConfirmAction(werminal);
+
+ final WerminalTextBox valueTextBox = formField.getFieldValueTextBox();
+ final Type heapValueType = valueTextBox.getHeapValueType();
+ final URI schemaUri = context.getSchemaLoader().getTypeUri(heapValueType);
+
+ final String dialogTitle = " Open \"" + schemaUri + "\" ";
+ final OpenModelDialog openModelDialog = new OpenModelDialog(werminal, dialogTitle, confirmAction,
+ werminal.getCancelAction());
+
+ confirmAction.setOpenModelDialog(openModelDialog);
+
+ final SortedSet historyItems = werminal.getOpenModelDialog().getSchemaUriHistoryCheckBoxList().getItems();
+ openModelDialog.getSchemaUriHistoryCheckBoxList().addItems(historyItems);
+
+ openModelDialog.setSchemaUri(schemaUri);
+ werminal.showWindow(openModelDialog, Position.CENTER);
+
+ return true;
+ }
+
+ private class ConfirmAction extends CloseBeforeAction
+ {
+
+ private OpenModelDialog _OpenModelDialog;
+
+ public ConfirmAction(final Werminal werminal)
+ {
+
+ super(werminal, "OK");
+ }
+
+ public OpenModelDialog getOpenModelDialog()
+ {
+
+ return _OpenModelDialog;
+ }
+
+ public void setOpenModelDialog(final OpenModelDialog openModelDialog)
+ {
+
+ _OpenModelDialog = openModelDialog;
+
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final OpenModelDialog openModelDialog = getOpenModelDialog();
+
+ final URI schemaUri = openModelDialog.getSchemaUri();
+ final Keys keys = openModelDialog.getKeys();
+ final UUID heapId = openModelDialog.getHeapId();
+
+ final Werminal werminal = getWerminal();
+
+ if (schemaUri == null)
+ {
+ werminal.showError("\nPlease indicate the type of data that you would like to open by entering a Schema URI value.\n\n ");
+ return false;
+ }
+ else if (keys == null || keys.getKeyedSchemaUris().isEmpty())
+ {
+ werminal.showError("\nPlease enter one or more key values to identify the data that you would like to open.\n\n ");
+ return false;
+ }
+
+ final Model openedModel = werminal.openModel(schemaUri, keys, heapId);
+
+ final FormField formField = getFormField();
+ formField.getFieldValueTextBox().setValue(openedModel, false);
+
+ return true;
+ }
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/PhasedWerminalAction.java b/cli/src/main/java/org/wrml/werminal/action/PhasedWerminalAction.java
new file mode 100644
index 0000000..7761481
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/PhasedWerminalAction.java
@@ -0,0 +1,57 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+public abstract class PhasedWerminalAction extends WerminalAction
+{
+
+ public PhasedWerminalAction(final Werminal werminal, final String title)
+ {
+
+ super(werminal, title);
+ }
+
+ @Override
+ public final void doAction()
+ {
+
+ if (preDoIt())
+ {
+ if (doIt())
+ {
+ postDoIt();
+ }
+ }
+ }
+
+ protected abstract boolean doIt();
+
+ protected abstract void postDoIt();
+
+ protected abstract boolean preDoIt();
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/PrintAction.java b/cli/src/main/java/org/wrml/werminal/action/PrintAction.java
new file mode 100644
index 0000000..9c11925
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/PrintAction.java
@@ -0,0 +1,146 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wrml.werminal.action;
+
+import com.googlecode.lanterna.gui.GUIScreen;
+import com.googlecode.lanterna.gui.Window;
+import org.wrml.model.Model;
+import org.wrml.model.Named;
+import org.wrml.model.Titled;
+import org.wrml.model.UniquelyNamed;
+import org.wrml.model.format.Format;
+import org.wrml.model.rest.Document;
+import org.wrml.util.UniqueName;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.dialog.PrintDialog;
+import org.wrml.werminal.dialog.PrintPreviewDialog;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+
+public class PrintAction extends CloseAfterAction
+{
+ public PrintAction(final Werminal werminal)
+ {
+
+ super(werminal, "Print...");
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final Werminal werminal = getWerminal();
+
+ final Window topWindow = werminal.getTopWindow();
+ if (!(topWindow instanceof PrintPreviewDialog))
+ {
+ werminal.showError("The " + getTitle() + " action requires a top level " + PrintPreviewDialog.class.getSimpleName());
+ return false;
+ }
+
+ final PrintPreviewDialog printPreviewDialog = (PrintPreviewDialog) topWindow;
+
+ final URI formatUri = printPreviewDialog.getFormatUri();
+ if (formatUri == null)
+ {
+ werminal.showError("The " + getTitle() + " action requires a Format URI.");
+ return false;
+ }
+
+ final PrintDialog printDialog = werminal.getPrintDialog();
+
+ File baseDir = new File(".");
+ final File previousFile = printDialog.getPrintToFile();
+ if (previousFile != null)
+ {
+ baseDir = (previousFile.isDirectory()) ? previousFile : previousFile.getParentFile();
+ }
+
+ try
+ {
+ baseDir = baseDir.getCanonicalFile();
+ }
+ catch (IOException e)
+ {
+ }
+
+ final Model modelToPrint = printPreviewDialog.getModel();
+ String fileName = null;
+
+ if (modelToPrint instanceof Titled)
+ {
+ fileName = ((Titled) modelToPrint).getTitle();
+ }
+ else if (modelToPrint instanceof Named)
+ {
+ fileName = ((Named) modelToPrint).getName();
+ }
+ else if (modelToPrint instanceof UniquelyNamed)
+ {
+ final UniqueName uniqueName = ((UniquelyNamed) modelToPrint).getUniqueName();
+ fileName = uniqueName.getLocalName();
+ }
+ else if (modelToPrint instanceof Document)
+ {
+ final URI uri = ((Document) modelToPrint).getUri();
+ final String uriPath = uri.getPath();
+ final int lastSlashIndex = uriPath.lastIndexOf('/');
+ if (lastSlashIndex < uriPath.length() - 1)
+ {
+ fileName = uriPath.substring(lastSlashIndex + 1);
+ }
+ }
+
+ if (fileName == null)
+ {
+
+ fileName = String.valueOf(modelToPrint.getHeapId());
+ }
+
+
+ String fileExtension = "txt";
+
+ final Format format = getContext().getFormatLoader().loadFormat(formatUri);
+ if (format != null)
+ {
+ final String formatFileExtension = format.getFileExtension();
+ fileExtension = formatFileExtension;
+ }
+
+ fileName = fileName + "." + fileExtension;
+
+ final File printToFile = new File(baseDir, fileName);
+ printDialog.setModel(modelToPrint);
+ printDialog.setFormatUri(formatUri);
+ printDialog.setPrintToFile(printToFile);
+
+ werminal.showWindow(printDialog, GUIScreen.Position.CENTER);
+ return true;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/PrintConfirmationAction.java b/cli/src/main/java/org/wrml/werminal/action/PrintConfirmationAction.java
new file mode 100644
index 0000000..ac03642
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/PrintConfirmationAction.java
@@ -0,0 +1,96 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wrml.werminal.action;
+
+import com.googlecode.lanterna.gui.Window;
+import org.wrml.model.Filed;
+import org.wrml.model.Model;
+import org.wrml.runtime.format.ModelWriteOptions;
+import org.wrml.runtime.schema.SchemaLoader;
+import org.wrml.runtime.service.file.FileSystemService;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.dialog.PrintDialog;
+
+import java.io.File;
+import java.net.URI;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.Set;
+
+public class PrintConfirmationAction extends CloseAfterAction
+{
+ public PrintConfirmationAction(final Werminal werminal)
+ {
+
+ super(werminal, "Print");
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final Werminal werminal = getWerminal();
+
+ final Window topWindow = werminal.getTopWindow();
+
+ if (!(topWindow instanceof PrintDialog))
+ {
+ werminal.showError("The " + getTitle() + " action requires a top level " + PrintDialog.class.getSimpleName());
+ return false;
+ }
+
+ final PrintDialog printDialog = (PrintDialog) topWindow;
+
+ final Model model = printDialog.getModel();
+ final File printToFile = printDialog.getPrintToFile();
+ final Path filePath = printToFile.toPath();
+ final URI formatUri = printDialog.getFormatUri();
+
+ final ModelWriteOptions writeOptions = new ModelWriteOptions();
+ writeOptions.setPrettyPrint(true);
+ final Set excludedSchemaUris = new HashSet<>(1);
+ final SchemaLoader schemaLoader = model.getContext().getSchemaLoader();
+
+ excludedSchemaUris.add(schemaLoader.getTypeUri(Filed.class));
+ excludedSchemaUris.add(schemaLoader.getDocumentSchemaUri());
+
+ writeOptions.setExcludedSchemaUris(excludedSchemaUris);
+
+ try
+ {
+ FileSystemService.writeModelFile(model, filePath, formatUri, writeOptions);
+ }
+ catch (final Exception e)
+ {
+ werminal.showError("Print Failed.", e);
+ return false;
+ }
+
+
+ return true;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/PrintPreviewAction.java b/cli/src/main/java/org/wrml/werminal/action/PrintPreviewAction.java
new file mode 100644
index 0000000..577d4f4
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/PrintPreviewAction.java
@@ -0,0 +1,56 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.model.Model;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.dialog.PrintPreviewDialog;
+import org.wrml.werminal.window.ModelWindow;
+
+public class PrintPreviewAction extends WerminalAction
+{
+
+ public PrintPreviewAction(final Werminal werminal)
+ {
+
+ super(werminal, "Print Preview");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+ final ModelWindow modelWindow = (ModelWindow) werminal.getTopWindow();
+ final Model model = modelWindow.syncModel();
+ final String title = ModelWindow.getModelWindowTitle(model) + " - Print Preview";
+
+ final PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog(werminal, title, werminal.getCloseAction());
+ printPreviewDialog.setModel(model);
+ werminal.showWindow(printPreviewDialog); // , Position.FULL_SCREEN);
+
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/SaveAction.java b/cli/src/main/java/org/wrml/werminal/action/SaveAction.java
new file mode 100644
index 0000000..22297bd
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/SaveAction.java
@@ -0,0 +1,101 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.model.Model;
+import org.wrml.model.rest.Embedded;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.Keys;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.window.ModelWindow;
+
+public class SaveAction extends WerminalAction
+{
+
+ public SaveAction(final Werminal werminal)
+ {
+
+ super(werminal, "Save");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+ final ModelWindow modelWindow = (ModelWindow) werminal.getTopWindow();
+ final Model model;
+
+ try
+ {
+ model = modelWindow.syncModel();
+ }
+ catch (final Exception e)
+ {
+ getWerminal().showError(e.getMessage());
+ return;
+ }
+
+ if (model instanceof Embedded || model.getPrototype().getAllKeySlotNames().isEmpty())
+ {
+ werminal.showMessageBox("Form Edits Applied", "The model's state was successfully committed (locally).");
+ return;
+ }
+
+ final Keys keys = model.getKeys();
+ if (keys == null)
+ {
+ werminal.showMessageBox("Error - Save Failed", "Cannot save model; all of the key slot values are blank.");
+ return;
+ }
+
+ final Model savedModel;
+
+ try
+ {
+
+ final Context context = getContext();
+
+ savedModel = context.saveModel(model);
+
+ if (savedModel == null)
+ {
+ werminal.showError("An unexpected error has occurred and the model could not be saved.");
+ return;
+ }
+
+ }
+ catch (final Exception t)
+ {
+ werminal.showError("An unexpected error has occurred and the model could not be saved.", t);
+ return;
+ }
+
+ modelWindow.setModel(savedModel);
+ werminal.showMessageBox("Save", "The model was successfully saved.");
+
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/SetOriginAction.java b/cli/src/main/java/org/wrml/werminal/action/SetOriginAction.java
new file mode 100644
index 0000000..3319102
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/SetOriginAction.java
@@ -0,0 +1,63 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.model.Model;
+import org.wrml.runtime.service.Service;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.dialog.SetOriginDialog;
+import org.wrml.werminal.window.ModelWindow;
+
+public class SetOriginAction extends WerminalAction
+{
+
+ public SetOriginAction(final Werminal werminal)
+ {
+
+ super(werminal, "Set Origin");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+ final ModelWindow modelWindow = (ModelWindow) werminal.getTopWindow();
+ final Model model = modelWindow.syncModel();
+ final String title = ModelWindow.getModelWindowTitle(model) + " - Set Origin";
+
+ final SetOriginConfirmationAction setOriginConfirmationAction = new SetOriginConfirmationAction(werminal);
+
+ final SetOriginDialog setOriginDialog = new SetOriginDialog(werminal, title, setOriginConfirmationAction, werminal.getCloseAction());
+ setOriginConfirmationAction.setSetOriginDialog(setOriginDialog);
+
+ final String originServiceName = model.getOriginServiceName();
+ setOriginDialog.setSelectedValue(originServiceName);
+
+ werminal.showWindow(setOriginDialog);
+
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/SetOriginConfirmationAction.java b/cli/src/main/java/org/wrml/werminal/action/SetOriginConfirmationAction.java
new file mode 100644
index 0000000..a2d4297
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/SetOriginConfirmationAction.java
@@ -0,0 +1,79 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.model.Model;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.service.Service;
+import org.wrml.runtime.service.ServiceLoader;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.dialog.SetOriginDialog;
+import org.wrml.werminal.window.ModelWindow;
+
+public class SetOriginConfirmationAction extends CloseBeforeAction
+{
+
+ private SetOriginDialog _SetOriginDialog;
+
+ public SetOriginConfirmationAction(final Werminal werminal)
+ {
+
+ super(werminal, "OK");
+ }
+
+ public SetOriginDialog getSetOriginDialog()
+ {
+
+ return _SetOriginDialog;
+ }
+
+ public void setSetOriginDialog(final SetOriginDialog setOriginDialog)
+ {
+
+ _SetOriginDialog = setOriginDialog;
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final Werminal werminal = getWerminal();
+ final ModelWindow modelWindow = (ModelWindow) werminal.getTopWindow();
+ final Model model = modelWindow.syncModel();
+
+ if (model == null)
+ {
+ werminal.showError("The model is null.");
+ }
+
+ final String originServiceName = _SetOriginDialog.getSelectedValue();
+ model.setOriginServiceName(originServiceName);
+
+ modelWindow.render();
+
+ return true;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/ShowListMenuAction.java b/cli/src/main/java/org/wrml/werminal/action/ShowListMenuAction.java
new file mode 100644
index 0000000..3d1fe92
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/ShowListMenuAction.java
@@ -0,0 +1,45 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+public class ShowListMenuAction extends WerminalAction
+{
+
+ public ShowListMenuAction(final Werminal werminal)
+ {
+
+ super(werminal, "Menu...");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+ werminal.showWindow(werminal.getListMenuBarWindow());
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/ShowModelMenuAction.java b/cli/src/main/java/org/wrml/werminal/action/ShowModelMenuAction.java
new file mode 100644
index 0000000..6eeda7f
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/ShowModelMenuAction.java
@@ -0,0 +1,45 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+public class ShowModelMenuAction extends WerminalAction
+{
+
+ public ShowModelMenuAction(final Werminal werminal)
+ {
+
+ super(werminal, "Menu...");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+ werminal.showWindow(werminal.getModelMenuBarWindow());
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/SortAction.java b/cli/src/main/java/org/wrml/werminal/action/SortAction.java
new file mode 100644
index 0000000..6734725
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/SortAction.java
@@ -0,0 +1,30 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+public class SortAction
+{
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/SubmitAction.java b/cli/src/main/java/org/wrml/werminal/action/SubmitAction.java
new file mode 100644
index 0000000..acd8944
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/SubmitAction.java
@@ -0,0 +1,87 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wrml.werminal.action;
+
+import com.googlecode.lanterna.gui.Window;
+import org.wrml.model.Model;
+import org.wrml.runtime.DimensionsBuilder;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.component.FormField;
+import org.wrml.werminal.dialog.InvocationDialog;
+
+public class SubmitAction extends CloseAfterAction
+{
+
+ private final Model _Function;
+
+ private final FormField _FormField;
+
+ public SubmitAction(final Werminal werminal, final Model function, final FormField formField)
+ {
+
+ super(werminal, "Submit");
+ _Function = function;
+ _FormField = formField;
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ final Werminal werminal = getWerminal();
+ final Window topWindow = werminal.getTopWindow();
+
+ if (!(topWindow instanceof InvocationDialog))
+ {
+ werminal.showError("The " + getTitle() + " action requires a top level "
+ + InvocationDialog.class.getSimpleName());
+ return false;
+ }
+
+ final InvocationDialog invocationDialog = (InvocationDialog) topWindow;
+
+ final String formFieldName = _FormField.getFieldName();
+ final Model parameter = invocationDialog.getParameter();
+
+ final Model returnValue;
+ try
+ {
+ returnValue = _Function.reference(formFieldName, new DimensionsBuilder(), parameter);
+ }
+ catch (Exception t)
+ {
+ werminal.showError("Invocation Failed.", t);
+ return false;
+ }
+
+ if (returnValue != null)
+ {
+ werminal.openModelWindow(returnValue);
+ }
+
+ return true;
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/UnimplementedAction.java b/cli/src/main/java/org/wrml/werminal/action/UnimplementedAction.java
new file mode 100644
index 0000000..4577402
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/UnimplementedAction.java
@@ -0,0 +1,44 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+public class UnimplementedAction extends WerminalAction
+{
+
+ public UnimplementedAction(final Werminal werminal, final String title)
+ {
+
+ super(werminal, title);
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ getApp().showMessageBox("Not Implemented", "The action \"" + getTitle() + "\" has not been implmented.");
+ }
+}
\ No newline at end of file
diff --git a/cli/src/main/java/org/wrml/werminal/action/WerminalAction.java b/cli/src/main/java/org/wrml/werminal/action/WerminalAction.java
new file mode 100644
index 0000000..c31779e
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/WerminalAction.java
@@ -0,0 +1,45 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.terminal.TerminalAppAction;
+
+public abstract class WerminalAction extends TerminalAppAction
+{
+
+ public WerminalAction(final Werminal werminal, final String title)
+ {
+
+ super(werminal, title);
+ }
+
+ public Werminal getWerminal()
+ {
+
+ return getApp();
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/action/WrmlOrgAction.java b/cli/src/main/java/org/wrml/werminal/action/WrmlOrgAction.java
new file mode 100644
index 0000000..c828095
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/action/WrmlOrgAction.java
@@ -0,0 +1,75 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.action;
+
+import org.wrml.werminal.Werminal;
+
+import java.io.IOException;
+import java.net.URI;
+
+public class WrmlOrgAction extends WerminalAction
+{
+
+ private final URI WRML_ORG = URI.create("http://www.wrml.org");
+
+ public WrmlOrgAction(final Werminal werminal)
+ {
+
+ super(werminal, "WRML.org");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ final Werminal werminal = getWerminal();
+
+ if (!java.awt.Desktop.isDesktopSupported())
+ {
+ werminal.showSplashWindow();
+ return;
+ }
+
+ final java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
+
+ if (!desktop.isSupported(java.awt.Desktop.Action.BROWSE))
+ {
+ werminal.showSplashWindow();
+ return;
+ }
+
+ try
+ {
+ desktop.browse(WRML_ORG);
+ }
+ catch (final IOException e)
+ {
+ System.err.println(e.getMessage());
+ werminal.showSplashWindow();
+ return;
+ }
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/component/FormField.java b/cli/src/main/java/org/wrml/werminal/component/FormField.java
new file mode 100644
index 0000000..fd905f1
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/component/FormField.java
@@ -0,0 +1,84 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.component;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.component.CheckBox;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.terminal.TerminalAppPanel;
+
+import java.lang.reflect.Type;
+
+public class FormField extends TerminalAppPanel
+{
+
+ private final CheckBox _FieldCheckBox;
+
+ private final WerminalTextBox _FieldValueTextBox;
+
+ private final String _FieldName;
+
+ public FormField(final String fieldName, final Type valueType, final WerminalAction enterAction)
+ {
+
+ super(enterAction.getApp(),
+ " " + fieldName + " (" + enterAction.getWerminal().getTypeTitle(valueType) + "): ",
+ new Border.Standard(), Orientation.HORISONTAL, false, false);
+
+ _FieldName = fieldName;
+
+ _FieldCheckBox = new CheckBox("", false);
+
+ _FieldValueTextBox = new WerminalTextBox((Werminal) enterAction.getApp(), valueType, enterAction);
+
+ render();
+ }
+
+ public CheckBox getFieldCheckBox()
+ {
+
+ return _FieldCheckBox;
+ }
+
+ public String getFieldName()
+ {
+
+ return _FieldName;
+ }
+
+ public WerminalTextBox getFieldValueTextBox()
+ {
+
+ return _FieldValueTextBox;
+ }
+
+ protected void render()
+ {
+ // addComponent(_FieldCheckBox);
+ addComponent(_FieldValueTextBox);
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/component/FormPanel.java b/cli/src/main/java/org/wrml/werminal/component/FormPanel.java
new file mode 100644
index 0000000..2679a74
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/component/FormPanel.java
@@ -0,0 +1,134 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.component;
+
+import com.googlecode.lanterna.gui.component.EmptySpace;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.window.FormPanelWindow;
+
+import java.util.Map;
+import java.util.Set;
+
+public class FormPanel extends WerminalPanel
+{
+
+
+ private final int _FieldsPerPanel;
+
+ private final Map _FormFields;
+
+
+ public FormPanel(final Werminal werminal, final String title, final Map formFields)
+ {
+
+ this(werminal, title, formFields, null, null, formFields.size());
+ }
+
+ public FormPanel(final Werminal werminal, final String title, final Map formFields, final int fieldsPerPanel)
+ {
+
+ this(werminal, title, formFields, null, null, fieldsPerPanel);
+ }
+
+ public FormPanel(final Werminal werminal, final String title, final Map formFields, final WerminalAction nextAction, final WerminalAction previousAction)
+ {
+
+ this(werminal, title, formFields, nextAction, previousAction, FormPanelWindow.FIELDS_PER_PANEL);
+ }
+
+ public FormPanel(final Werminal werminal, final String title, final Map formFields, final WerminalAction nextAction, final WerminalAction previousAction, final int fieldsPerPanel)
+ {
+
+ super(werminal, title, nextAction, previousAction);
+
+ _FormFields = formFields;
+ _FieldsPerPanel = fieldsPerPanel;
+ render();
+ }
+
+ public void addFormField(final FormField formField)
+ {
+
+ _FormFields.put(formField.getFieldName(), formField);
+ render();
+ }
+
+ public final int getFieldCount()
+ {
+
+ return _FormFields.size();
+ }
+
+ public int getFieldsPerPanel()
+ {
+
+ return _FieldsPerPanel;
+ }
+
+ public final Set getFieldNames()
+ {
+
+ return _FormFields.keySet();
+ }
+
+ public final FormField getFormField(final String fieldName)
+ {
+
+ return _FormFields.get(fieldName);
+ }
+
+ @Override
+ protected void render()
+ {
+
+ super.render();
+ renderForm();
+ addComponent(new EmptySpace(0, 1));
+ }
+
+ protected final void renderForm()
+ {
+
+ if (_FormFields != null && !_FormFields.isEmpty())
+ {
+
+ for (final String fieldName : _FormFields.keySet())
+ {
+ final FormField formField = _FormFields.get(fieldName);
+ addComponent(formField);
+ }
+
+ final int invisibleFieldCount = getFieldsPerPanel() - _FormFields.size();
+ for (int i = 0; i < invisibleFieldCount; i++)
+ {
+ addComponent(new EmptySpace(0, 3));
+ }
+
+ }
+
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/component/HistoryCheckListBox.java b/cli/src/main/java/org/wrml/werminal/component/HistoryCheckListBox.java
new file mode 100644
index 0000000..393338a
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/component/HistoryCheckListBox.java
@@ -0,0 +1,221 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright 2012 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.component;
+
+import com.googlecode.lanterna.input.Key;
+import org.apache.commons.lang3.StringUtils;
+import org.wrml.runtime.rest.RestUtils;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+public class HistoryCheckListBox extends WerminalCheckListBox
+{
+
+ private final WerminalTextBox _TextBox;
+
+ private final SortedSet _HistorySet;
+
+ public HistoryCheckListBox(final WerminalTextBox forTextBox)
+ {
+
+ this(forTextBox, null, null);
+ }
+
+ public HistoryCheckListBox(final WerminalTextBox forTextBox, final WerminalAction enterAction,
+ final WerminalAction enterOnSelectionAction)
+ {
+
+ super((Werminal) forTextBox.getApp(), enterAction, enterOnSelectionAction);
+ _TextBox = forTextBox;
+
+ _HistorySet = new TreeSet<>();
+ }
+
+ @Override
+ public void addItem(final Object item)
+ {
+
+ if (!addItemInternal(item))
+ {
+ return;
+ }
+
+ syncView();
+ }
+
+ public void addItems(final Collection> items)
+ {
+
+ for (final Object item : items)
+ {
+ addItemInternal(item);
+ }
+
+ syncView();
+ }
+
+ @Override
+ public void clearItems()
+ {
+
+ super.clearItems();
+ _HistorySet.clear();
+ }
+
+ public WerminalTextBox getTextBox()
+ {
+
+ return _TextBox;
+ }
+
+ public SortedSet getItems()
+ {
+
+ return _HistorySet;
+ }
+
+ @Override
+ public void setCheckedItem(final Object newCheckedItem)
+ {
+
+ super.setCheckedItem(newCheckedItem);
+ _TextBox.setValue(newCheckedItem);
+
+ }
+
+ @Override
+ public Result keyboardInteraction(final Key key)
+ {
+
+ if (!isVisible())
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ final Key.Kind kind = key.getKind();
+ switch (kind)
+ {
+ case NormalKey:
+
+ final char character = key.getCharacter();
+ if (setSelectedItemFromCharacter(character))
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ break;
+ }
+
+ return super.keyboardInteraction(key);
+ }
+
+ private boolean setSelectedItemFromCharacter(final char character)
+ {
+ // Support jumping to entry based on last path element in URI
+ int indexOfBestMatch = -1;
+ final int selectedIndex = getSelectedIndex();
+
+ final String characterAsString = String.valueOf(character);
+
+ if (_HistorySet.isEmpty() || !(_HistorySet.first() instanceof URI))
+ {
+ return false;
+ }
+
+ final int size = _HistorySet.size();
+
+ for (int i = selectedIndex + 1; i < size; i++)
+ {
+ if (itemLastSegementStartsWith(i, characterAsString))
+ {
+ indexOfBestMatch = i;
+ break;
+ }
+ }
+
+ if (indexOfBestMatch < 0)
+ {
+ for (int i = 0; i < selectedIndex; i++)
+ {
+ if (itemLastSegementStartsWith(i, characterAsString))
+ {
+ indexOfBestMatch = i;
+ break;
+ }
+ }
+ }
+
+ if (indexOfBestMatch >= 0)
+ {
+ setSelectedItem(indexOfBestMatch);
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean itemLastSegementStartsWith(int itemIndex, CharSequence charSequence)
+ {
+
+ final Object historyItem = getItemAt(itemIndex);
+
+ if (!(historyItem instanceof URI))
+ {
+ return false;
+ }
+
+ final URI uri = (URI) historyItem;
+ final String lastPathElement = RestUtils.getLastPathElement(uri);
+ return StringUtils.startsWithIgnoreCase(lastPathElement, charSequence);
+ }
+
+ private boolean addItemInternal(final Object item)
+ {
+
+ if (!(item instanceof Comparable) || _HistorySet.contains(item))
+ {
+ return false;
+ }
+
+ return _HistorySet.add(item);
+ }
+
+ private void syncView()
+ {
+
+ super.clearItems();
+
+ for (final Object historyItem : _HistorySet)
+ {
+ super.addItem(historyItem);
+ }
+
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/component/ListMenu.java b/cli/src/main/java/org/wrml/werminal/component/ListMenu.java
new file mode 100644
index 0000000..4b3f231
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/component/ListMenu.java
@@ -0,0 +1,65 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wrml.werminal.component;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.component.EmptySpace;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppMenu;
+import org.wrml.werminal.terminal.TerminalAppPanel;
+
+/**
+ * Moved from inner class of {@link org.wrml.werminal.Werminal}.
+ *
+ * @author JJ Zabkar
+ */
+public class ListMenu extends TerminalAppPanel
+{
+
+ public ListMenu(final Werminal werminal)
+ {
+
+ super(werminal, "", new Border.Invisible(), Orientation.HORISONTAL, true, false);
+
+ final TerminalAppMenu editMenu = new TerminalAppMenu(werminal, " Edit Selected Elements ");
+ addComponent(editMenu);
+
+ final String[] editMenuItems = {"Copy", "Cut", "Paste", "Delete"};
+ for (String editMenuItem : editMenuItems)
+ {
+ editMenu.addComponent(new TerminalAppButtonPanel(werminal.getUnimplementedAction(editMenuItem)));
+ }
+
+ final TerminalAppMenu helpMenu = new TerminalAppMenu(werminal, " Help ");
+ addComponent(helpMenu);
+
+ final TerminalAppButtonPanel wrmlOrgMenuItem = new TerminalAppButtonPanel(werminal.getClosingWrmlOrgAction());
+ helpMenu.addComponent(wrmlOrgMenuItem);
+
+ addComponent(new EmptySpace(0, 4));
+ }
+}
\ No newline at end of file
diff --git a/cli/src/main/java/org/wrml/werminal/component/MainMenu.java b/cli/src/main/java/org/wrml/werminal/component/MainMenu.java
new file mode 100644
index 0000000..3495d09
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/component/MainMenu.java
@@ -0,0 +1,68 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wrml.werminal.component;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.terminal.TerminalSize;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppMenu;
+import org.wrml.werminal.terminal.TerminalAppPanel;
+
+/**
+ * Moved from inner class of {@link org.wrml.werminal.Werminal}.
+ *
+ * @author JJ Zabkar
+ */
+public class MainMenu extends TerminalAppPanel
+{
+
+ public MainMenu(final Werminal werminal)
+ {
+
+ super(werminal, "", new Border.Invisible(), Orientation.HORISONTAL, true, false);
+
+ final TerminalAppMenu modelMenu = new TerminalAppMenu(getApp(), " Model ");
+ modelMenu.setPreferredSize(new TerminalSize(30, 8));
+ addComponent(modelMenu);
+
+ final TerminalAppButtonPanel modelNewMenuItem = new TerminalAppButtonPanel(werminal.getNewAction());
+ modelMenu.addComponent(modelNewMenuItem);
+ final TerminalAppButtonPanel modelOpenMenuItem = new TerminalAppButtonPanel(werminal.getOpenAction());
+ modelMenu.addComponent(modelOpenMenuItem);
+
+ final TerminalAppMenu helpMenu = new TerminalAppMenu(getApp(), " Help ");
+ helpMenu.setPreferredSize(new TerminalSize(30, 8));
+ addComponent(helpMenu);
+
+ final TerminalAppButtonPanel helpGuideMenuItem = new TerminalAppButtonPanel(werminal.getHelpGuideAction());
+ helpMenu.addComponent(helpGuideMenuItem);
+
+ final TerminalAppButtonPanel wrmlOrgMenuItem = new TerminalAppButtonPanel(werminal.getWrmlOrgAction());
+ helpMenu.addComponent(wrmlOrgMenuItem);
+
+ }
+}
\ No newline at end of file
diff --git a/cli/src/main/java/org/wrml/werminal/component/ModelMenu.java b/cli/src/main/java/org/wrml/werminal/component/ModelMenu.java
new file mode 100644
index 0000000..0228191
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/component/ModelMenu.java
@@ -0,0 +1,79 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wrml.werminal.component;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.component.EmptySpace;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppMenu;
+import org.wrml.werminal.terminal.TerminalAppPanel;
+
+/**
+ * Moved from inner class of {@link org.wrml.werminal.Werminal}.
+ *
+ * @author JJ Zabkar
+ */
+public class ModelMenu extends TerminalAppPanel
+{
+
+ public ModelMenu(final Werminal werminal)
+ {
+
+ super(werminal, "", new Border.Invisible(), Orientation.HORISONTAL, true, false);
+
+ final TerminalAppMenu modelMenu = new TerminalAppMenu(werminal, " Model ");
+
+ addComponent(modelMenu);
+
+ final TerminalAppButtonPanel modelSaveMenuItem = new TerminalAppButtonPanel(
+ werminal.getUnimplementedAction("Save"));
+ modelMenu.addComponent(modelSaveMenuItem);
+ final TerminalAppButtonPanel modelSaveAsMenuItem = new TerminalAppButtonPanel(
+ werminal.getUnimplementedAction("Save As..."));
+ modelMenu.addComponent(modelSaveAsMenuItem);
+ final TerminalAppButtonPanel modelDeleteMenuItem = new TerminalAppButtonPanel(
+ werminal.getUnimplementedAction("Delete"));
+ modelMenu.addComponent(modelDeleteMenuItem);
+
+ final TerminalAppMenu editMenu = new TerminalAppMenu(werminal, " Selection ");
+ addComponent(editMenu);
+
+ final String[] editMenuActions = {"Cut", "Copy", "Paste", "Delete"};
+ for (String editMenuAction : editMenuActions)
+ {
+ editMenu.addComponent(new TerminalAppButtonPanel(werminal.getUnimplementedAction(editMenuAction)));
+ }
+
+ final TerminalAppMenu helpMenu = new TerminalAppMenu(werminal, " Help ");
+ addComponent(helpMenu);
+
+ final TerminalAppButtonPanel wrmlOrgMenuItem = new TerminalAppButtonPanel(werminal.getClosingWrmlOrgAction());
+ helpMenu.addComponent(wrmlOrgMenuItem);
+
+ addComponent(new EmptySpace(0, 4));
+ }
+}
\ No newline at end of file
diff --git a/cli/src/main/java/org/wrml/werminal/component/WerminalActionListBox.java b/cli/src/main/java/org/wrml/werminal/component/WerminalActionListBox.java
new file mode 100644
index 0000000..452d7a3
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/component/WerminalActionListBox.java
@@ -0,0 +1,107 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright 2012 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.component;
+
+import com.googlecode.lanterna.gui.component.ActionListBox;
+import com.googlecode.lanterna.input.Key;
+import com.googlecode.lanterna.input.Key.Kind;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.terminal.TerminalAppKeyboardInteraction;
+
+public class WerminalActionListBox extends ActionListBox
+{
+
+ private final TerminalAppKeyboardInteraction _KeyboardInteraction;
+
+ private final WerminalAction _EnterOnSelectionAction;
+
+ private final Werminal _Werminal;
+
+ public WerminalActionListBox(final Werminal werminal)
+ {
+
+ this(werminal, null, null);
+ }
+
+ public WerminalActionListBox(final Werminal werminal, final WerminalAction enterAction,
+ final WerminalAction enterOnSelectionAction)
+ {
+
+ _Werminal = werminal;
+ _KeyboardInteraction = new TerminalAppKeyboardInteraction(_Werminal, enterAction, true);
+ _EnterOnSelectionAction = enterOnSelectionAction;
+ }
+
+ @Override
+ public Result keyboardInteraction(final Key key)
+ {
+
+ if (!isVisible())
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ final Kind kind = key.getKind();
+ switch (kind)
+ {
+
+ case Enter:
+ {
+
+ final Object oldSelectedItem = getSelectedItem();
+
+ Result result = super.keyboardInteraction(key);
+
+ final Object newSelectedItem = getSelectedItem();
+
+ if (_KeyboardInteraction.handleKeyboardInteraction(key))
+ {
+ result = Result.EVENT_HANDLED;
+ }
+
+ if (_EnterOnSelectionAction != null && oldSelectedItem != null && newSelectedItem == oldSelectedItem)
+ {
+ _EnterOnSelectionAction.doAction();
+ }
+
+ return result;
+ }
+
+ default:
+ {
+
+ if (_KeyboardInteraction.handleKeyboardInteraction(key))
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ return super.keyboardInteraction(key);
+ }
+ }
+
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/component/WerminalCheckListBox.java b/cli/src/main/java/org/wrml/werminal/component/WerminalCheckListBox.java
new file mode 100644
index 0000000..4e1b598
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/component/WerminalCheckListBox.java
@@ -0,0 +1,139 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright 2012 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.component;
+
+import com.googlecode.lanterna.gui.component.CheckBoxList;
+import com.googlecode.lanterna.input.Key;
+import com.googlecode.lanterna.input.Key.Kind;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.terminal.TerminalAppKeyboardInteraction;
+
+public class WerminalCheckListBox extends CheckBoxList
+{
+
+ private final Werminal _Werminal;
+
+ private final TerminalAppKeyboardInteraction _KeyboardInteraction;
+
+ private final WerminalAction _EnterOnSelectionAction;
+
+ private Object _CheckedItem;
+
+ public WerminalCheckListBox(final Werminal werminal)
+ {
+
+ this(werminal, null, null);
+ }
+
+ public WerminalCheckListBox(final Werminal werminal, final WerminalAction enterAction,
+ final WerminalAction enterOnSelectionAction)
+ {
+
+ _Werminal = werminal;
+ _KeyboardInteraction = new TerminalAppKeyboardInteraction(_Werminal, enterAction, true);
+ _EnterOnSelectionAction = enterOnSelectionAction;
+ }
+
+ public Object getCheckedItem()
+ {
+
+ return _CheckedItem;
+ }
+
+ @Override
+ public Result keyboardInteraction(final Key key)
+ {
+
+ if (!isVisible())
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ final Kind kind = key.getKind();
+ switch (kind)
+ {
+
+ case Enter:
+ {
+
+ final Object oldSelectedItem = getSelectedItem();
+ final Object oldCheckedItem = getCheckedItem();
+
+ // Intentional fall through here...
+ if (_CheckedItem != null)
+ {
+ setChecked(_CheckedItem, false);
+ _CheckedItem = null;
+ }
+
+ Result result = super.keyboardInteraction(key);
+
+ final Object newSelectedItem = getSelectedItem();
+ if ((newSelectedItem != null) && isChecked(newSelectedItem))
+ {
+
+ setCheckedItem(newSelectedItem);
+
+ }
+
+ if (_KeyboardInteraction.handleKeyboardInteraction(key))
+ {
+ result = Result.EVENT_HANDLED;
+ }
+
+ if (_EnterOnSelectionAction != null && oldCheckedItem != null && oldSelectedItem == oldCheckedItem)
+ {
+ _EnterOnSelectionAction.doAction();
+ }
+
+ return result;
+ }
+
+ default:
+ {
+
+ if (_KeyboardInteraction.handleKeyboardInteraction(key))
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ return super.keyboardInteraction(key);
+ }
+ }
+
+ }
+
+ protected void setCheckedItem(final Object newCheckedItem)
+ {
+
+ _CheckedItem = newCheckedItem;
+ if (_CheckedItem != null)
+ {
+ setChecked(_CheckedItem, true);
+ }
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/component/WerminalPanel.java b/cli/src/main/java/org/wrml/werminal/component/WerminalPanel.java
new file mode 100644
index 0000000..d5ab4d0
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/component/WerminalPanel.java
@@ -0,0 +1,260 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.component;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.Component;
+import com.googlecode.lanterna.gui.component.EmptySpace;
+import com.googlecode.lanterna.gui.component.Label;
+import com.googlecode.lanterna.gui.component.Panel;
+import com.googlecode.lanterna.gui.component.Separator;
+import com.googlecode.lanterna.terminal.Terminal;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppPanel;
+import org.wrml.werminal.terminal.TerminalAppToolBar;
+
+public class WerminalPanel extends TerminalAppPanel
+{
+
+ private final WerminalAction _NextAction;
+
+ private final WerminalAction _PreviousAction;
+
+ private TerminalAppToolBar _ToolBar;
+
+ private int _PanelIndex;
+
+ private int _PanelCount;
+
+ public WerminalPanel(final Werminal werminal, final String title)
+ {
+
+ this(werminal, title, true, true);
+ }
+
+ public WerminalPanel(final Werminal werminal, final String title, final boolean horizontallyMaximized, final boolean verticallyMaximized)
+ {
+
+ this(werminal, title, horizontallyMaximized, verticallyMaximized, null, null);
+ }
+
+ public WerminalPanel(final Werminal werminal, final String title, final WerminalAction nextAction, final WerminalAction previousAction)
+ {
+
+ this(werminal, title, new Border.Standard(), Orientation.VERTICAL, nextAction, previousAction);
+ }
+
+ public WerminalPanel(final Werminal werminal, final String title, final boolean horizontallyMaximized,
+ final boolean verticallyMaximized, final WerminalAction nextAction, final WerminalAction previousAction)
+ {
+
+ this(werminal, title, new Border.Standard(), Orientation.VERTICAL, horizontallyMaximized, verticallyMaximized, nextAction, previousAction);
+ }
+
+
+ public WerminalPanel(final Werminal werminal, final String title, final Border border,
+ final Orientation orientation, final WerminalAction nextAction, final WerminalAction previousAction)
+ {
+
+ this(werminal, title, border, orientation, true, true, nextAction, previousAction);
+ }
+
+ public WerminalPanel(final Werminal werminal, final String title, final Border border,
+ final Orientation orientation, final boolean horizontallyMaximized, final boolean verticallyMaximized,
+ final WerminalAction nextAction, final WerminalAction previousAction)
+ {
+
+ super(werminal, title, border, orientation, horizontallyMaximized, verticallyMaximized);
+
+ _NextAction = nextAction;
+ _PreviousAction = previousAction;
+
+ render();
+ }
+
+
+ public WerminalAction getNextAction()
+ {
+
+ return _NextAction;
+ }
+
+ public final int getPanelCount()
+ {
+
+ return _PanelCount;
+ }
+
+ public final int getPanelIndex()
+ {
+
+ return _PanelIndex;
+ }
+
+ public WerminalAction getPreviousAction()
+ {
+
+ return _PreviousAction;
+ }
+
+ public final TerminalAppToolBar getToolBar()
+ {
+
+ return _ToolBar;
+ }
+
+ public final Werminal getWerminal()
+ {
+
+ return getApp();
+ }
+
+ public final void setPanelCount(final int panelCount)
+ {
+
+ _PanelCount = panelCount;
+ render();
+ }
+
+ public final void setPanelIndex(final int panelIndex)
+ {
+
+ _PanelIndex = panelIndex;
+ render();
+ }
+
+ protected final Component[] getNavigationToolBarComponents()
+ {
+
+ final String panelNumberSpacePaddingPrefix;
+
+ final int panelIndex = getPanelIndex();
+ final int panelCount = getPanelCount();
+
+ final boolean isFirstPanel = (panelIndex == 0);
+ final boolean isLastPanel = (panelIndex == (panelCount - 1));
+
+ if (isFirstPanel && isLastPanel)
+ {
+ return null;
+ }
+
+ if ((panelIndex < 10) & (panelCount < 10))
+ {
+ panelNumberSpacePaddingPrefix = "";
+ }
+ else if ((panelIndex < 10) && (panelCount < 100))
+ {
+ panelNumberSpacePaddingPrefix = " ";
+ }
+ else if ((panelIndex < 100) && (panelCount < 1000))
+ {
+ if (panelIndex < 10)
+ {
+ panelNumberSpacePaddingPrefix = " ";
+ }
+ else
+ {
+ panelNumberSpacePaddingPrefix = " ";
+ }
+ }
+ else
+ {
+ panelNumberSpacePaddingPrefix = "";
+ }
+
+ final int panelDisplayNumber = panelIndex + 1;
+
+ final TerminalAppPanel panelNumberPanel = new TerminalAppPanel(getWerminal(), new Border.Invisible(),
+ Panel.Orientation.VERTICAL);
+ panelNumberPanel.addComponent(new EmptySpace(0, 1));
+ final Label pageLabel = new Label(panelNumberSpacePaddingPrefix + panelDisplayNumber + " of " + panelCount, 8,
+ Terminal.Color.BLACK, false);
+ pageLabel.setAlignment(Alignment.CENTER);
+ panelNumberPanel.addComponent(pageLabel);
+
+ panelNumberPanel.addComponent(new EmptySpace(0, 1));
+
+ final WerminalAction nextAction = getNextAction();
+ final WerminalAction previousAction = getPreviousAction();
+ final Component[] toolBarComponents;
+
+ if (nextAction != null && isFirstPanel)
+ {
+ toolBarComponents = new Component[]{new TerminalAppButtonPanel(nextAction), panelNumberPanel};
+ }
+ else if (previousAction != null && isLastPanel)
+ {
+ toolBarComponents = new Component[]{new TerminalAppButtonPanel(previousAction), panelNumberPanel};
+ }
+ else if (nextAction != null && previousAction != null)
+ {
+ toolBarComponents = new Component[]{new TerminalAppButtonPanel(getPreviousAction()), panelNumberPanel,
+ new TerminalAppButtonPanel(getNextAction())};
+ }
+ else
+ {
+ toolBarComponents = null;
+ }
+
+ return toolBarComponents;
+
+ }
+
+ protected void render()
+ {
+
+ removeAllComponents();
+ renderToolBar();
+ }
+
+ protected final void renderToolBar()
+ {
+
+ final Component[] toolBarComponents = getNavigationToolBarComponents();
+ if (toolBarComponents != null)
+ {
+ _ToolBar = new TerminalAppToolBar(getWerminal(), toolBarComponents);
+ }
+ else
+ {
+ _ToolBar = null;
+ }
+
+ if (_ToolBar != null)
+ {
+ addComponent(_ToolBar);
+ addComponent(new Separator());
+ }
+ else
+ {
+ addComponent(new EmptySpace(0, 1));
+ }
+
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/component/WerminalTextBox.java b/cli/src/main/java/org/wrml/werminal/component/WerminalTextBox.java
new file mode 100644
index 0000000..d18075e
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/component/WerminalTextBox.java
@@ -0,0 +1,406 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.component;
+
+import com.googlecode.lanterna.input.Key;
+import com.googlecode.lanterna.input.Key.Kind;
+import org.apache.commons.lang3.reflect.TypeUtils;
+import org.wrml.model.Model;
+import org.wrml.model.rest.Link;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.Keys;
+import org.wrml.runtime.schema.ValueType;
+import org.wrml.runtime.syntax.SyntaxLoader;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.terminal.TerminalAppTextBox;
+
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+
+@SuppressWarnings({"unchecked"})
+public class WerminalTextBox extends TerminalAppTextBox
+{
+
+ private static final String OPEN_BUTTON_STRING = "< Open... >";
+
+ private static final String CLICK_BUTTON_STRING = "< Click... >";
+
+ private final WerminalAction _EnterAction;
+
+ private final Type _ValueType;
+
+ private Object _Value;
+
+ private String _TextValue;
+
+ private boolean _ListValueChanged;
+
+ private boolean _ModelValueChanged;
+
+ public WerminalTextBox(final Werminal werminal, final int width, final Type valueType,
+ final WerminalAction enterAction)
+ {
+
+ super(werminal, width);
+ _ValueType = valueType;
+ _EnterAction = enterAction;
+
+ }
+
+ public WerminalTextBox(final Werminal werminal, final Type valueType, final WerminalAction enterAction)
+ {
+
+ this(werminal, 255, valueType, enterAction);
+ }
+
+ public WerminalAction getEnterAction()
+ {
+
+ return _EnterAction;
+ }
+
+ public Type getHeapValueType()
+ {
+
+ return _ValueType;
+ }
+
+ public V getValue()
+ {
+
+ final Context context = getWerminal().getContext();
+ final SyntaxLoader syntaxLoader = context.getSyntaxLoader();
+ final Type heapValueType = getHeapValueType();
+ final ValueType valueType = getValueType();
+
+ if (_Value == null && valueType != ValueType.Model && valueType != ValueType.List
+ && valueType != ValueType.Link)
+ {
+ final String stringValue = getText();
+ _Value = syntaxLoader.parseSyntacticText(stringValue, heapValueType);
+ }
+
+ return (V) _Value;
+ }
+
+ public ValueType getValueType()
+ {
+
+ final Context context = getWerminal().getContext();
+ return context.getSchemaLoader().getValueType(getHeapValueType());
+ }
+
+ public Werminal getWerminal()
+ {
+
+ return getApp();
+ }
+
+ public boolean isValueChanged()
+ {
+
+ final ValueType valueType = getValueType();
+ switch (valueType)
+ {
+ case Link:
+ case Model:
+ return isModelValueChanged();
+
+ case List:
+ return isListValueChanged();
+
+ case Boolean:
+ case Date:
+ case Double:
+ case Integer:
+ case Long:
+ case Native:
+ case SingleSelect:
+ case Text:
+ default:
+
+ final String currentText = getText();
+ if (_TextValue != null)
+ {
+ return !(_TextValue.equals(currentText));
+ }
+ else
+ {
+ return currentText != null && !currentText.isEmpty();
+ }
+
+ }
+
+ }
+
+ @Override
+ public Result keyboardInteraction(final Key key)
+ {
+
+ if (!isVisible())
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ final Result result;
+ final Kind kind = key.getKind();
+ final Type valueType = getHeapValueType();
+
+ switch (kind)
+ {
+ case Enter:
+ {
+
+ if (_EnterAction != null)
+ {
+ try
+ {
+ _EnterAction.doAction();
+ }
+ catch (Exception t)
+ {
+ getWerminal().showError("Error - An unhandled exception has arisen.", t);
+
+ }
+ }
+
+ result = Result.EVENT_HANDLED;
+ break;
+ }
+ case NormalKey:
+ {
+ if (ValueType.isModelType(valueType) || TypeUtils.isAssignable(valueType, List.class))
+ {
+ result = Result.EVENT_HANDLED;
+ }
+ else
+ {
+ _Value = null;
+
+ result = super.keyboardInteraction(key);
+ }
+ break;
+ }
+ case Backspace:
+ case Delete:
+ {
+
+ // TODO: Check the value type and determine if editable
+
+ if (ValueType.isModelType(valueType))
+ {
+ setValue(null, false);
+ result = Result.EVENT_HANDLED;
+ }
+ else if (TypeUtils.isAssignable(valueType, List.class))
+ {
+ result = Result.EVENT_HANDLED;
+ }
+ else
+ {
+ _Value = null;
+ result = super.keyboardInteraction(key);
+ }
+ break;
+ }
+
+ default:
+ {
+ result = super.keyboardInteraction(key);
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public void setText(final String text)
+ {
+
+ setText(text, true);
+
+ }
+
+ public Object setValue(final Object value)
+ {
+
+ return setValue(value, true);
+ }
+
+ public Object setValue(final Object value, final boolean silentChange)
+ {
+
+ final Object oldValue = _Value;
+
+ final Werminal werminal = getWerminal();
+ final ValueType valueType = getValueType();
+ _Value = value;
+
+ final Context context = getWerminal().getContext();
+ final SyntaxLoader syntaxLoader = context.getSyntaxLoader();
+ String stringValue = "";
+ switch (valueType)
+ {
+
+ case Link:
+ {
+
+ final String disabledLinkString = "href=\"\"";
+ if (value instanceof Link)
+ {
+ final Link linkValue = (Link) value;
+ final URI href = linkValue.getHref();
+ if (href != null)
+ {
+ // TODO: Display the HTTP method and the relation URI too
+
+ stringValue = "href=\"" + href.toString() + "\" " + CLICK_BUTTON_STRING;
+ }
+ else
+ {
+ stringValue = disabledLinkString;
+ }
+
+ _ModelValueChanged = !silentChange;
+
+ // TODO: Track Model changes
+ }
+ else
+ {
+ stringValue = disabledLinkString;
+ }
+
+ break;
+ }
+ case Model:
+ {
+
+ if (value instanceof Model)
+ {
+ final Model modelValue = (Model) value;
+ final Keys keys = modelValue.getKeys();
+ if (keys != null)
+ {
+ final Set keyedSchemaUris = keys.getKeyedSchemaUris();
+ for (final URI keyedSchemaUri : keyedSchemaUris)
+ {
+ final Object initialKeyValue = keys.getValue(keyedSchemaUri);
+ stringValue = String.valueOf(initialKeyValue);
+ break;
+ }
+ }
+ else
+ {
+ stringValue = modelValue.getHeapId().toString();
+ }
+
+ _ModelValueChanged = !silentChange;
+
+ // TODO: Track Model changes
+ }
+
+ if (stringValue == null || stringValue.isEmpty())
+ {
+ stringValue = OPEN_BUTTON_STRING;
+ }
+ else
+ {
+ stringValue = stringValue + " " + OPEN_BUTTON_STRING;
+ }
+ break;
+ }
+ case List:
+ {
+
+ if (value instanceof List)
+ {
+ final List> listValue = (List>) value;
+
+ stringValue = werminal.listToString(listValue, getHeapValueType());
+
+ _ListValueChanged = !silentChange;
+ // TODO: Track List changes
+ }
+
+ stringValue = stringValue + " " + OPEN_BUTTON_STRING;
+ break;
+ }
+ case Boolean:
+ case Date:
+ case Double:
+ case Integer:
+ case Long:
+ case Native:
+ case SingleSelect:
+ case Text:
+ default:
+ stringValue = syntaxLoader.formatSyntaxValue(value);
+ break;
+
+ }
+
+ if (stringValue == null)
+ {
+ stringValue = "";
+ }
+
+ setText(stringValue, false);
+ if (silentChange)
+ {
+ _TextValue = stringValue;
+ }
+
+ return oldValue;
+ }
+
+ protected void setText(final String stringValue, final boolean clearValue)
+ {
+
+ if (clearValue)
+ {
+ _Value = null;
+ }
+
+ super.setText(stringValue);
+
+ }
+
+ private boolean isListValueChanged()
+ {
+
+ return _ListValueChanged;
+ }
+
+ private boolean isModelValueChanged()
+ {
+
+ return _ModelValueChanged;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/EnumValueDialog.java b/cli/src/main/java/org/wrml/werminal/dialog/EnumValueDialog.java
new file mode 100644
index 0000000..423501d
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/EnumValueDialog.java
@@ -0,0 +1,130 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.dialog;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.Component;
+import com.googlecode.lanterna.gui.component.RadioCheckBoxList;
+import com.googlecode.lanterna.input.Key;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppKeyboardInteraction;
+import org.wrml.werminal.terminal.TerminalAppToolBar;
+import org.wrml.werminal.window.WerminalWindow;
+
+public class EnumValueDialog extends WerminalWindow
+{
+
+ private final EnumValuesCheckBoxList _EnumValuesCheckBoxList;
+
+ public EnumValueDialog(final Werminal werminal, final String title, final WerminalAction confirmAction,
+ final WerminalAction dismissAction)
+ {
+
+ super(werminal, title);
+
+ setBorder(new Border.Standard());
+
+ _EnumValuesCheckBoxList = new EnumValuesCheckBoxList(werminal, confirmAction);
+
+ addEmptySpace();
+
+ addComponent(_EnumValuesCheckBoxList);
+
+ final TerminalAppToolBar footerToolBar = new TerminalAppToolBar(werminal, new Component[]{
+ new TerminalAppButtonPanel(confirmAction), new TerminalAppButtonPanel(dismissAction)});
+ addComponent(footerToolBar);
+ }
+
+ @SuppressWarnings("unchecked")
+ public final > E getSelectedValue()
+ {
+
+ return (E) _EnumValuesCheckBoxList.getItemAt(_EnumValuesCheckBoxList.getCheckedItemIndex());
+ }
+
+ @SuppressWarnings("unchecked")
+ public final void setSelectedValue(final Enum> selectedValue)
+ {
+
+ _EnumValuesCheckBoxList.clearItems();
+
+ if (selectedValue == null)
+ {
+ return;
+ }
+
+ final Class> enumType = (Class>) selectedValue.getDeclaringClass();
+ final Enum>[] allEnumValues = enumType.getEnumConstants();
+
+ for (int i = 0; i < allEnumValues.length; i++)
+ {
+ final Enum> enumValue = allEnumValues[i];
+ _EnumValuesCheckBoxList.addItem(enumValue);
+ if (enumValue == selectedValue)
+ {
+ _EnumValuesCheckBoxList.setCheckedItemIndex(i);
+ }
+ }
+
+ }
+
+ public static class EnumValuesCheckBoxList extends RadioCheckBoxList
+ {
+
+ private final TerminalAppKeyboardInteraction _KeyboardInteraction;
+
+ public EnumValuesCheckBoxList(final Werminal werminal, final WerminalAction confirmAction)
+ {
+
+ _KeyboardInteraction = new TerminalAppKeyboardInteraction(werminal, confirmAction, true);
+ }
+
+ @Override
+ public Result keyboardInteraction(final Key key)
+ {
+
+ if (!isVisible())
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ if (key.getKind() == Key.Kind.Enter)
+ {
+ super.keyboardInteraction(key);
+ }
+
+
+ if (_KeyboardInteraction.handleKeyboardInteraction(key))
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ return super.keyboardInteraction(key);
+ }
+
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/HistoryPopup.java b/cli/src/main/java/org/wrml/werminal/dialog/HistoryPopup.java
new file mode 100644
index 0000000..bafcbd5
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/HistoryPopup.java
@@ -0,0 +1,59 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.dialog;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.terminal.TerminalSize;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.component.HistoryCheckListBox;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.window.WerminalWindow;
+
+public class HistoryPopup extends WerminalWindow
+{
+
+ private final HistoryCheckListBox _HistoryCheckListBox;
+
+ public HistoryPopup(final Werminal werminal, final String title, final WerminalTextBox keyTextBox)
+ {
+
+ super(werminal, title);
+ setBorder(new Border.Standard());
+
+ addEmptySpace();
+
+ _HistoryCheckListBox = new HistoryCheckListBox(keyTextBox, werminal.getCloseAction(), null);
+ _HistoryCheckListBox.setPreferredSize(new TerminalSize(70, 10));
+ addComponent(_HistoryCheckListBox);
+
+ }
+
+ public HistoryCheckListBox getHistoryCheckListBox()
+ {
+
+ return _HistoryCheckListBox;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/InvocationDialog.java b/cli/src/main/java/org/wrml/werminal/dialog/InvocationDialog.java
new file mode 100644
index 0000000..349991e
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/InvocationDialog.java
@@ -0,0 +1,141 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wrml.werminal.dialog;
+
+import org.wrml.model.Model;
+import org.wrml.model.rest.Link;
+import org.wrml.runtime.schema.LinkProtoSlot;
+import org.wrml.runtime.schema.Prototype;
+import org.wrml.runtime.schema.SchemaLoader;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.CancelAction;
+import org.wrml.werminal.action.FormFieldOpenAction;
+import org.wrml.werminal.action.SubmitAction;
+import org.wrml.werminal.component.FormField;
+import org.wrml.werminal.component.FormPanel;
+
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class
+ InvocationDialog extends WerminalDialog
+{
+
+ private final FormField _FunctionLinkFormField;
+
+ private final FormField _ParameterFormField;
+
+ public InvocationDialog(final Werminal werminal, final String title, final Model function, final FormField functionLinkFormField) throws ClassNotFoundException
+ {
+
+ super(werminal, title, new SubmitAction(werminal, function, functionLinkFormField), new CancelAction(werminal));
+
+ _FunctionLinkFormField = functionLinkFormField;
+
+ final Prototype prototype = function.getPrototype();
+ final String linkSlotName = functionLinkFormField.getFieldName();
+ final LinkProtoSlot linkProtoSlot = prototype.getProtoSlot(linkSlotName);
+
+ final URI requestSchemaUri = linkProtoSlot.getRequestSchemaUri();
+ if (requestSchemaUri != null)
+ {
+
+
+ final SchemaLoader schemaLoader = werminal.getContext().getSchemaLoader();
+ final Type parameterType = schemaLoader.getSchemaInterface(requestSchemaUri);
+
+ final FormFieldOpenAction parameterFormFieldOpenAction = new FormFieldOpenAction(werminal);
+ _ParameterFormField = new FormField("Parameter", parameterType, parameterFormFieldOpenAction);
+ parameterFormFieldOpenAction.setFormField(_ParameterFormField);
+ }
+ else
+ {
+ _ParameterFormField = null;
+ }
+
+ render();
+ }
+
+ public Model getParameter()
+ {
+
+ if (_ParameterFormField != null)
+ {
+ return _ParameterFormField.getFieldValueTextBox().getValue();
+ }
+
+ return null;
+ }
+
+ @Override
+ public void render()
+ {
+
+ removeAllComponents();
+
+ if (_FunctionLinkFormField == null)
+ {
+ return;
+ }
+
+ addEmptySpace();
+
+ final Werminal werminal = getWerminal();
+
+ final int fieldCount = (_ParameterFormField != null) ? 2 : 1;
+ final Map formFieldMap = new LinkedHashMap<>(fieldCount);
+
+ final FormFieldOpenAction functionFormFieldOpenAction = new FormFieldOpenAction(werminal);
+ final FormField functionUriFormField = new FormField("Function", URI.class, functionFormFieldOpenAction);
+ functionFormFieldOpenAction.setFormField(functionUriFormField);
+
+ final Link functionLink = _FunctionLinkFormField.getFieldValueTextBox().getValue();
+ final URI functionHref = functionLink.getHref();
+ functionUriFormField.getFieldValueTextBox().setValue(functionHref);
+
+ formFieldMap.put(functionUriFormField.getFieldName(), functionUriFormField);
+
+ if (_ParameterFormField != null)
+ {
+ formFieldMap.put(_ParameterFormField.getFieldName(), _ParameterFormField);
+ }
+
+ final String linkSlotName = _FunctionLinkFormField.getFieldName();
+ final String panelTitle = " " + linkSlotName + " ";
+ final FormPanel formPanel = new FormPanel(werminal, panelTitle, formFieldMap);
+
+ addComponent(formPanel);
+
+ addEmptySpace();
+
+ super.renderFooterToolBar();
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/ListValueDialog.java b/cli/src/main/java/org/wrml/werminal/dialog/ListValueDialog.java
new file mode 100644
index 0000000..d14a0f2
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/ListValueDialog.java
@@ -0,0 +1,147 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.dialog;
+
+import com.googlecode.lanterna.gui.Component;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.component.FormField;
+import org.wrml.werminal.component.FormPanel;
+import org.wrml.werminal.component.WerminalPanel;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppToolBar;
+import org.wrml.werminal.window.FormPanelWindow;
+
+import java.lang.reflect.Type;
+import java.util.*;
+
+public class ListValueDialog extends FormPanelWindow
+{
+
+ private Type _ListElementType;
+
+ private final TerminalAppToolBar _FooterToolBar;
+
+ public ListValueDialog(final Werminal werminal, final String title, final Component[] toolBarComponents,
+ final WerminalAction confirmAction, final WerminalAction dismissAction)
+ {
+
+ super(werminal, title, toolBarComponents);
+
+ _FooterToolBar = new TerminalAppToolBar(werminal, new Component[]{new TerminalAppButtonPanel(confirmAction),
+ new TerminalAppButtonPanel(dismissAction)});
+
+ render();
+ }
+
+ public void addFormField(final Object value)
+ {
+
+ addFormField("Elements", getListElementType(), value);
+ }
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public List> getList()
+ {
+
+ final List list = new ArrayList<>();
+
+ final List panels = getPanels();
+ for (final WerminalPanel panel : panels)
+ {
+
+ if (panel instanceof FormPanel)
+ {
+
+ final FormPanel formPanel = (FormPanel) panel;
+
+ final Set fieldNames = formPanel.getFieldNames();
+
+ for (final String fieldName : fieldNames)
+ {
+ final FormField field = formPanel.getFormField(fieldName);
+ list.add(field.getFieldValueTextBox().getValue());
+ }
+ }
+ }
+
+ return (List>) list;
+ }
+
+ public Type getListElementType()
+ {
+
+ return _ListElementType;
+ }
+
+ public void setList(final List> list, final Type elementType)
+ {
+
+ _ListElementType = elementType;
+
+ final List panels = getPanels();
+ panels.clear();
+
+ // _ElementLabel.getValueLabel().setText("List Element Type: " + _ElementType);
+
+ final Map fieldMap = new LinkedHashMap<>();
+
+ for (int i = 0; i < list.size(); i++)
+ {
+ final String fieldName = String.valueOf(i);
+ fieldMap.put(fieldName, _ListElementType);
+ }
+
+ initPanels("Elements", fieldMap);
+
+ for (int i = 0; i < list.size(); i++)
+ {
+ final String fieldName = String.valueOf(i);
+ final Object value = list.get(i);
+ final FormField formField = getFormField(fieldName);
+ formField.getFieldValueTextBox().setValue(value);
+ }
+
+ }
+
+ @Override
+ public void render()
+ {
+
+ super.render();
+ renderFooterToolBar();
+ }
+
+ protected void renderFooterToolBar()
+ {
+
+ addEmptySpace();
+ if (_FooterToolBar != null)
+ {
+ addComponent(_FooterToolBar);
+ }
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/LoadApiDialog.java b/cli/src/main/java/org/wrml/werminal/dialog/LoadApiDialog.java
new file mode 100644
index 0000000..c1eb93f
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/LoadApiDialog.java
@@ -0,0 +1,163 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.dialog;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.Component;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.rest.ApiLoader;
+import org.wrml.runtime.rest.ApiLoaderException;
+import org.wrml.runtime.rest.ApiNavigator;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.CancelAction;
+import org.wrml.werminal.action.CloseAfterAction;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppTextBoxPanel;
+import org.wrml.werminal.terminal.TerminalAppToolBar;
+import org.wrml.werminal.window.WerminalWindow;
+
+import java.net.URI;
+
+public class LoadApiDialog extends WerminalWindow
+{
+
+ final LoadApiDialogConfirmationAction _ConfirmAction;
+
+ final LoadApiDialogCancelAction _CancelAction;
+
+ private final WerminalTextBox _ApiUriTextBox;
+
+ private boolean _Cancelled;
+
+ public LoadApiDialog(final Werminal werminal, final String title)
+ {
+
+ super(werminal, title);
+
+ _ConfirmAction = new LoadApiDialogConfirmationAction(werminal);
+ _CancelAction = new LoadApiDialogCancelAction(werminal);
+
+ setBorder(new Border.Standard());
+
+ addEmptySpace();
+
+ _ApiUriTextBox = new WerminalTextBox(werminal, 70, URI.class, _ConfirmAction);
+ final TerminalAppTextBoxPanel schemaUriTextBoxPanel = new TerminalAppTextBoxPanel(werminal, " REST API (URI): ", _ApiUriTextBox);
+ addComponent(schemaUriTextBoxPanel);
+
+ addEmptySpace();
+
+ final TerminalAppToolBar footerToolBar = new TerminalAppToolBar(werminal, new Component[]{
+ new TerminalAppButtonPanel(_ConfirmAction), new TerminalAppButtonPanel(_CancelAction)});
+
+ addComponent(footerToolBar);
+
+ }
+
+ public URI getApiUri()
+ {
+
+ return _ApiUriTextBox.getValue();
+ }
+
+ public void setApiUri(final URI apiUri)
+ {
+
+ _ApiUriTextBox.setValue(apiUri);
+ }
+
+ public boolean isCancelled()
+ {
+
+ return _Cancelled;
+ }
+
+ class LoadApiDialogCancelAction extends CancelAction
+ {
+
+ public LoadApiDialogCancelAction(final Werminal werminal)
+ {
+
+ super(werminal);
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ _Cancelled = true;
+ return super.doIt();
+ }
+
+ }
+
+ class LoadApiDialogConfirmationAction extends CloseAfterAction
+ {
+
+
+ public LoadApiDialogConfirmationAction(final Werminal werminal)
+ {
+
+ super(werminal, "OK");
+ }
+
+ @Override
+ protected boolean doIt()
+ {
+
+ _Cancelled = false;
+
+ final Werminal werminal = getWerminal();
+ final Context context = werminal.getContext();
+ final ApiLoader apiLoader = context.getApiLoader();
+
+ final LoadApiDialog loadApiDialog = werminal.getLoadApiDialog();
+
+ final URI apiUri = loadApiDialog.getApiUri();
+ if (apiUri == null)
+ {
+ werminal.showError("\nPlease enter the (root) URI value to identify the REST API.\n\n ");
+ return false;
+ }
+
+ try
+ {
+ final ApiNavigator apiNavigator = apiLoader.loadApi(apiUri);
+ return (apiNavigator != null);
+ }
+ catch (ApiLoaderException e)
+ {
+ werminal.showError("\nFailed to load REST API metadata from URI:\n\n\t" + apiUri + "\n\nFailure detail message:\n\n" + e.getMessage() + "\n\nPlease enter the (root) URI value to identify the REST API.\n\n ");
+ return false;
+ }
+
+
+ }
+
+ }
+
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/NewModelDialog.java b/cli/src/main/java/org/wrml/werminal/dialog/NewModelDialog.java
new file mode 100644
index 0000000..8048d11
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/NewModelDialog.java
@@ -0,0 +1,99 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.dialog;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.Component;
+import com.googlecode.lanterna.gui.component.Panel.Orientation;
+import com.googlecode.lanterna.terminal.TerminalSize;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.component.HistoryCheckListBox;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppPanel;
+import org.wrml.werminal.terminal.TerminalAppTextBoxPanel;
+import org.wrml.werminal.terminal.TerminalAppToolBar;
+import org.wrml.werminal.window.WerminalWindow;
+
+import java.net.URI;
+
+public class NewModelDialog extends WerminalWindow
+{
+
+ private final WerminalTextBox _SchemaUriTextBox;
+
+ private final HistoryCheckListBox _SchemaUriHistoryCheckBoxList;
+
+ public NewModelDialog(final Werminal werminal, final String title, final WerminalAction confirmAction,
+ final WerminalAction dismissAction)
+ {
+
+ super(werminal, title);
+
+ setBorder(new Border.Standard());
+
+ addEmptySpace();
+
+ _SchemaUriTextBox = new WerminalTextBox(werminal, 70, URI.class, confirmAction);
+
+ final TerminalAppTextBoxPanel schemaUriTextBoxPanel = new TerminalAppTextBoxPanel(werminal, " Schema (URI): ",
+ _SchemaUriTextBox);
+ addComponent(schemaUriTextBoxPanel);
+
+ final TerminalAppPanel historyPanel = new TerminalAppPanel(werminal, " History: ", new Border.Standard(),
+ Orientation.VERTICAL);
+ _SchemaUriHistoryCheckBoxList = new HistoryCheckListBox(_SchemaUriTextBox, null, confirmAction);
+ _SchemaUriHistoryCheckBoxList.setPreferredSize(new TerminalSize(70, 10));
+ historyPanel.addComponent(_SchemaUriHistoryCheckBoxList);
+ addComponent(historyPanel);
+
+ final TerminalAppToolBar footerToolBar = new TerminalAppToolBar(werminal, new Component[]{
+ new TerminalAppButtonPanel(confirmAction), new TerminalAppButtonPanel(dismissAction)});
+ addComponent(footerToolBar);
+
+ }
+
+ public URI getSchemaUri()
+ {
+
+ return (URI) _SchemaUriTextBox.getValue();
+ }
+
+ public HistoryCheckListBox getSchemaUriHistoryCheckBoxList()
+ {
+
+ return _SchemaUriHistoryCheckBoxList;
+ }
+
+ public URI setSchemaUri(final URI schemaUri)
+ {
+
+ final URI oldSchemaUri = (URI) _SchemaUriTextBox.getValue();
+ _SchemaUriTextBox.setValue(schemaUri);
+ return oldSchemaUri;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/NewOrOpenModelDialog.java b/cli/src/main/java/org/wrml/werminal/dialog/NewOrOpenModelDialog.java
new file mode 100644
index 0000000..2d59431
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/NewOrOpenModelDialog.java
@@ -0,0 +1,130 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.dialog;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.component.EmptySpace;
+import com.googlecode.lanterna.gui.component.Label;
+import com.googlecode.lanterna.terminal.Terminal.Color;
+import org.wrml.runtime.Context;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.NewModelAction;
+import org.wrml.werminal.action.OpenModelAction;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.component.FormField;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppMenu;
+import org.wrml.werminal.terminal.TerminalAppPanel;
+
+import java.lang.reflect.Type;
+import java.net.URI;
+
+public class NewOrOpenModelDialog extends WerminalDialog
+{
+
+ private final FormField _FormField;
+
+ private final OptionsMenu _OptionsMenu;
+
+ public NewOrOpenModelDialog(final Werminal werminal, final String title, final WerminalAction dismissAction, final FormField formField)
+ {
+
+ super(werminal, title, null, dismissAction);
+ _FormField = formField;
+ _OptionsMenu = new OptionsMenu(werminal, title);
+ render();
+ }
+
+ public final FormField getFormField()
+ {
+
+ return _FormField;
+ }
+
+ @Override
+ public void render()
+ {
+
+ removeAllComponents();
+ super.renderHeaderToolBar();
+
+ addEmptySpace();
+
+ addComponent(_OptionsMenu);
+
+ addEmptySpace();
+
+ super.renderFooterToolBar();
+
+ }
+
+ private class OptionsMenu extends TerminalAppPanel
+ {
+
+ public OptionsMenu(final Werminal werminal, final String title)
+ {
+
+ super(werminal, title, new Border.Invisible(), Orientation.VERTICAL, false, false);
+
+ final Context context = werminal.getContext();
+ final FormField formField = getFormField();
+ final WerminalTextBox valueTextBox = formField.getFieldValueTextBox();
+ final Type heapValueType = valueTextBox.getHeapValueType();
+ final URI schemaUri = context.getSchemaLoader().getTypeUri(heapValueType);
+ final String schemaUriString = String.valueOf(schemaUri);
+
+ final TerminalAppMenu newMenu = new TerminalAppMenu(werminal, " New ");
+ addComponent(newMenu);
+
+ newMenu.addComponent(new EmptySpace(0, 2));
+ newMenu.addComponent(new Label("With a new: "));
+ final Label newSchemaLabel = new Label(schemaUriString);
+ newSchemaLabel.setTextColor(Color.RED);
+ newMenu.addComponent(newSchemaLabel);
+
+ newMenu.addComponent(new EmptySpace(0, 2));
+
+ final TerminalAppButtonPanel newMenuItem = new TerminalAppButtonPanel(new NewModelAction(werminal, formField));
+ newMenu.addComponent(newMenuItem);
+
+ addComponent(new EmptySpace(2, 0));
+
+ final TerminalAppMenu openMenu = new TerminalAppMenu(werminal, " Open ");
+ addComponent(openMenu);
+ openMenu.addComponent(new EmptySpace(0, 2));
+ openMenu.addComponent(new Label("With an existing: "));
+ final Label openSchemaLabel = new Label(schemaUriString);
+ openSchemaLabel.setTextColor(Color.RED);
+ openMenu.addComponent(openSchemaLabel);
+
+ openMenu.addComponent(new EmptySpace(0, 2));
+
+ final TerminalAppButtonPanel openMenuItem = new TerminalAppButtonPanel(new OpenModelAction(werminal, formField));
+ openMenu.addComponent(openMenuItem);
+ }
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/OpenModelDialog.java b/cli/src/main/java/org/wrml/werminal/dialog/OpenModelDialog.java
new file mode 100644
index 0000000..309acbe
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/OpenModelDialog.java
@@ -0,0 +1,670 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.dialog;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.Component;
+import com.googlecode.lanterna.gui.Component.Alignment;
+import com.googlecode.lanterna.gui.component.Label;
+import com.googlecode.lanterna.gui.component.Panel.Orientation;
+import com.googlecode.lanterna.gui.layout.LinearLayout;
+import com.googlecode.lanterna.gui.listener.ComponentAdapter;
+import com.googlecode.lanterna.terminal.TerminalSize;
+import org.wrml.model.rest.Document;
+import org.wrml.model.schema.Schema;
+import org.wrml.runtime.CompositeKey;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.Keys;
+import org.wrml.runtime.KeysBuilder;
+import org.wrml.runtime.rest.ApiLoader;
+import org.wrml.runtime.rest.SystemApi;
+import org.wrml.runtime.schema.ProtoSlot;
+import org.wrml.runtime.schema.Prototype;
+import org.wrml.runtime.schema.SchemaLoader;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.component.HistoryCheckListBox;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.terminal.*;
+import org.wrml.werminal.window.WerminalWindow;
+
+import java.net.URI;
+import java.util.*;
+
+public class OpenModelDialog extends WerminalWindow
+{
+
+ private static final String DEFAULT_KEYS_PANEL_LABEL = " Keys: ";
+
+ private static final String ENTER_KEYS_BUTTON_LABEL = "Enter Keys...";
+
+ private static final String SHOW_HISTORY_BUTTON_LABEL = "History...";
+
+ WerminalTextBox _HeapIdTextBox;
+
+ WerminalTextBox _SchemaUriTextBox;
+
+ TerminalAppPanel _KeysPanel;
+
+ WerminalAction _ConfirmAction;
+
+ Set _KeySlotNames;
+
+ Map _KeyInputs;
+
+ HistoryCheckListBox _SchemaUriHistoryCheckBoxList;
+
+ Map> _CompositeKeyInputs;
+
+ URI _SchemaUri;
+
+
+ /**
+ * for testing -- no need to mock {@code werminal.context}
+ */
+ OpenModelDialog()
+ {
+
+ super(null, null);
+ }
+
+ public OpenModelDialog(final Werminal werminal, final String title, final WerminalAction confirmAction,
+ final WerminalAction dismissAction)
+ {
+
+ super(werminal, title);
+ final URI schemaUri = werminal.getContext().getSchemaLoader().getApiSchemaUri();
+ init(werminal, confirmAction, dismissAction, schemaUri);
+ }
+
+ /**
+ * @param werminal
+ * @param confirmAction
+ * @param dismissAction
+ */
+ private void init(final Werminal werminal, final WerminalAction confirmAction, final WerminalAction dismissAction,
+ final URI schemaUri)
+ {
+
+ _ConfirmAction = confirmAction;
+
+ _KeyInputs = new LinkedHashMap<>();
+ _CompositeKeyInputs = new LinkedHashMap<>();
+ _KeySlotNames = new LinkedHashSet<>();
+
+ setBorder(new Border.Standard());
+
+ // setBetweenComponentsPadding(0);
+
+ addEmptySpace();
+
+ //
+ // Schema ID
+ //
+
+ final WerminalAction enterKeysAction = new WerminalAction(getWerminal(), ENTER_KEYS_BUTTON_LABEL)
+ {
+
+ @Override
+ public void doAction()
+ {
+
+ _SchemaUri = getSchemaUri();
+ updateKeysPanel(_SchemaUri, null);
+ }
+ };
+
+ final TerminalAppButton enterKeysButton = new TerminalAppButton(enterKeysAction);
+
+ _SchemaUriTextBox = new WerminalTextBox(werminal, 60, URI.class, enterKeysAction)
+ {
+
+ @Override
+ protected void setText(final String stringValue, final boolean clearValue)
+ {
+
+ super.setText(stringValue, clearValue);
+ enterKeysAction.doAction();
+ }
+
+ };
+
+ final TerminalAppTextBoxPanel schemaUriTextBoxPanel = new TerminalAppTextBoxPanel(werminal, " Schema (URI): ",
+ _SchemaUriTextBox);
+
+ schemaUriTextBoxPanel.addComponent(enterKeysButton);
+
+ _SchemaUriTextBox.addComponentListener(new ComponentAdapter()
+ {
+
+ @Override
+ public void onComponentInvalidated(final Component component)
+ {
+
+ final boolean canEnterKeys;
+ final String schemaUriText = _SchemaUriTextBox.getText();
+ if (schemaUriText == null || schemaUriText.trim().isEmpty())
+ {
+ canEnterKeys = false;
+ }
+ else
+ {
+ final URI schemaUri = getSchemaUri();
+ canEnterKeys = schemaUri != null && schemaUri.equals(_SchemaUri);
+ }
+
+ // enterKeysButton.setVisible(canEnterKeys);
+
+ if (!canEnterKeys)
+ {
+ updateKeysPanel(null, null);
+ }
+ }
+ });
+
+ addComponent(schemaUriTextBoxPanel);
+
+ addEmptySpace();
+
+ final TerminalAppPanel historyPanel = new TerminalAppPanel(werminal, " History: ", new Border.Standard(),
+ Orientation.VERTICAL);
+ _SchemaUriHistoryCheckBoxList = new HistoryCheckListBox(_SchemaUriTextBox, null, confirmAction);
+ _SchemaUriHistoryCheckBoxList.setPreferredSize(new TerminalSize(70, 10));
+ historyPanel.addComponent(_SchemaUriHistoryCheckBoxList);
+ addComponent(historyPanel);
+
+ addEmptySpace();
+ //
+ // Keys
+ //
+ // addComponent(new Label("Keys: ", 70, Alignment.START), SizePolicy.CONSTANT);
+ _KeysPanel = new TerminalAppPanel(werminal, DEFAULT_KEYS_PANEL_LABEL, new Border.Bevel(true),
+ Orientation.VERTICAL);
+ addComponent(_KeysPanel, LinearLayout.GROWS_VERTICALLY);
+
+ // Heap ID
+
+ _HeapIdTextBox = new WerminalTextBox(werminal, 60, UUID.class, confirmAction);
+
+ addEmptySpace();
+
+ //
+ // Dialog buttons
+ //
+ final TerminalAppToolBar footerToolBar = new TerminalAppToolBar(werminal, new Component[]{
+ new TerminalAppButtonPanel(confirmAction), new TerminalAppButtonPanel(dismissAction)});
+ addComponent(footerToolBar);
+
+ setSchemaUri(schemaUri);
+
+ final Context context = werminal.getContext();
+ }
+
+ public UUID getHeapId()
+ {
+
+ return (UUID) _HeapIdTextBox.getValue();
+ }
+
+ public Keys getKeys()
+ {
+
+ final URI schemaUri = getSchemaUri();
+ if (schemaUri == null)
+ {
+ return null;
+ }
+
+ final Context context = getApp().getContext();
+ final ApiLoader apiLoader = context.getApiLoader();
+ final SchemaLoader schemaLoader = context.getSchemaLoader();
+ final URI documentSchemaUri = schemaLoader.getDocumentSchemaUri();
+
+ final KeysBuilder keysBuilder = new KeysBuilder();
+
+ final Set keySchemaUris = _KeyInputs.keySet();
+ for (final URI keySchemaUri : keySchemaUris)
+ {
+
+ final WerminalTextBox keyTextBox = _KeyInputs.get(keySchemaUri);
+
+ final Object keyValue;
+ try
+ {
+ keyValue = keyTextBox.getValue();
+ }
+ catch (final Exception e)
+ {
+ continue;
+ }
+
+ if (keyValue != null)
+ {
+ keysBuilder.addKey(keySchemaUri, keyValue);
+ }
+ }
+
+ if (_KeyInputs.containsKey(documentSchemaUri))
+ {
+ // Build and add the document keys (if uri value != null)
+ final WerminalTextBox uriTextBox = _KeyInputs.get(documentSchemaUri);
+
+ if (uriTextBox != null)
+ {
+ final URI uri = uriTextBox.getValue();
+ if (uri != null)
+ {
+ Keys surrogateKeys = apiLoader.buildDocumentKeys(uri, schemaUri);
+ keysBuilder.addAll(surrogateKeys);
+ }
+ }
+ }
+
+ if (!_CompositeKeyInputs.isEmpty())
+ {
+
+ final Set compositeKeySchemaUris = _CompositeKeyInputs.keySet();
+
+ outer:
+ for (final URI compositeKeySchemaUri : compositeKeySchemaUris)
+ {
+
+ final SortedMap compositeKeySlots = new TreeMap();
+ final Map compositeKeyTextBoxes = _CompositeKeyInputs
+ .get(compositeKeySchemaUri);
+ for (final String compositeKeySlotName : compositeKeyTextBoxes.keySet())
+ {
+
+ final WerminalTextBox compositeKeyTextBox = compositeKeyTextBoxes.get(compositeKeySlotName);
+
+ final Object keyComponentValue;
+ try
+ {
+ keyComponentValue = compositeKeyTextBox.getValue();
+ }
+ catch (final Exception e)
+ {
+ continue outer;
+ }
+
+ if (keyComponentValue == null)
+ {
+ continue outer;
+ }
+
+ compositeKeySlots.put(compositeKeySlotName, keyComponentValue);
+
+ }
+
+ if (!compositeKeySlots.isEmpty())
+ {
+ keysBuilder.addKey(compositeKeySchemaUri, new CompositeKey(compositeKeySlots));
+ }
+
+ }
+ }
+
+ return keysBuilder.toKeys();
+ }
+
+ public void setKeys(final Keys keys)
+ {
+
+ updateKeysPanel(getSchemaUri(), keys);
+ }
+
+ public URI getSchemaUri()
+ {
+
+ try
+ {
+ return (URI) _SchemaUriTextBox.getValue();
+ }
+ catch (final Exception e)
+ {
+ return null;
+ }
+ }
+
+ public HistoryCheckListBox getSchemaUriHistoryCheckBoxList()
+ {
+
+ return _SchemaUriHistoryCheckBoxList;
+ }
+
+ public URI setSchemaUri(final URI schemaUri)
+ {
+
+ _SchemaUri = schemaUri;
+ final URI oldSchemaUri = (URI) _SchemaUriTextBox.setValue(schemaUri, false);
+ updateKeysPanel(schemaUri, null);
+ return oldSchemaUri;
+ }
+
+ private boolean addKeyInput(final URI schemaUri, final Prototype keyDeclaredPrototype, final Keys keys)
+ {
+
+ final Werminal werminal = getWerminal();
+ final Context context = werminal.getContext();
+ final SchemaLoader schemaLoader = context.getSchemaLoader();
+ final URI keyDeclaredSchemaUri = keyDeclaredPrototype.getSchemaUri();
+
+ if (_KeyInputs.containsKey(keyDeclaredSchemaUri))
+ {
+ return false;
+ }
+
+ final SortedSet keySlotNames = keyDeclaredPrototype.getDeclaredKeySlotNames();
+ if (keySlotNames == null || keySlotNames.isEmpty())
+ {
+ // The schema declare's *zero* key slots
+ return false;
+ }
+
+ if (keySlotNames.size() == 1)
+ {
+ // The schema declare's *only one* key slot
+
+ final String keySlotName = keySlotNames.first();
+
+ if (_KeySlotNames.contains(keySlotName))
+ {
+ return false;
+ }
+
+ final Class> keySlotType = (Class>) keyDeclaredPrototype.getKeyType();
+ final TerminalAppTextBoxPanel keyTextBoxPanel = createKeyInput(schemaUri, keyDeclaredPrototype,
+ keySlotName, keySlotType, 60);
+ final WerminalTextBox keyTextBox = (WerminalTextBox) keyTextBoxPanel.getTextBox();
+ _KeysPanel.addComponent(keyTextBoxPanel);
+ _KeysPanel.addEmptySpace();
+
+ _KeyInputs.put(keyDeclaredSchemaUri, keyTextBox);
+ _KeySlotNames.add(keySlotName);
+
+ final URI documentSchemaUri = schemaLoader.getDocumentSchemaUri();
+ final boolean isDocumentPrototype = keyDeclaredSchemaUri.equals(documentSchemaUri);
+ if (isDocumentPrototype)
+ {
+
+ keyTextBox.addComponentListener(new ComponentAdapter()
+ {
+
+ @Override
+ public void onComponentInvalidated(final Component component)
+ {
+
+ final URI uri;
+ try
+ {
+ uri = (URI) keyTextBox.getValue();
+ updateKeysPanelDocumentSurrogateKeyInputs(uri);
+ }
+ catch (final Exception ex)
+ {
+ return;
+ }
+
+ }
+
+ });
+
+ }
+
+ return true;
+ }
+ else
+ {
+
+ // The schema declare's *more than one* key slot
+
+ final SortedMap compositeKeyTextBoxes = new TreeMap<>();
+ for (final String keySlotName : keySlotNames)
+ {
+
+ if (_KeySlotNames.contains(keySlotName))
+ {
+ continue;
+ }
+
+ final ProtoSlot protoSlot = keyDeclaredPrototype.getProtoSlot(keySlotName);
+ if (protoSlot == null)
+ {
+ continue;
+ }
+
+ final Class> keyComponentType = (Class>) protoSlot.getHeapValueType();
+ final TerminalAppTextBoxPanel keyTextBoxPanel = createKeyInput(schemaUri, keyDeclaredPrototype,
+ keySlotName, keyComponentType, 60);
+ final WerminalTextBox keyTextBox = (WerminalTextBox) keyTextBoxPanel.getTextBox();
+ compositeKeyTextBoxes.put(keySlotName, keyTextBox);
+
+ _KeysPanel.addComponent(keyTextBoxPanel);
+ _KeysPanel.addEmptySpace();
+
+ _KeySlotNames.add(keySlotName);
+ }
+
+ if (compositeKeyTextBoxes.isEmpty())
+ {
+ return false;
+ }
+
+ _CompositeKeyInputs.put(keyDeclaredSchemaUri, compositeKeyTextBoxes);
+ return true;
+ }
+
+ }
+
+ private void addKeyMessageLabel()
+ {
+
+ addMessageLabel("Enter a Schema.id and *click* the \"" + ENTER_KEYS_BUTTON_LABEL + "\" button.",
+ Alignment.LEFT_CENTER);
+
+ }
+
+ private void addMessageLabel(final String message, final Alignment alignment)
+ {
+
+ final Label label = new Label(message);
+ label.setAlignment(alignment);
+ _KeysPanel.addEmptySpace();
+ _KeysPanel.addComponent(label, LinearLayout.MAXIMIZES_HORIZONTALLY);
+ _KeysPanel.addEmptySpace();
+ }
+
+ private TerminalAppTextBoxPanel createKeyInput(final URI schemaUri, final Prototype keyDeclaredPrototype,
+ final String keyInputName, final Class> keyInputType, final int keyInputWidth)
+ {
+
+ final Werminal werminal = getWerminal();
+ final WerminalTextBox keyTextBox = new WerminalTextBox(getWerminal(), keyInputWidth, keyInputType,
+ _ConfirmAction);
+
+ final Class> schemaInterface = keyDeclaredPrototype.getSchemaBean().getIntrospectedClass();
+ final String schemaTitle = schemaInterface.getSimpleName();
+ final String keyInputTypeTitle = keyInputType.getSimpleName();
+ final String panelTitle = " " + schemaTitle + "." + keyInputName + " (" + keyInputTypeTitle + "): ";
+ final TerminalAppTextBoxPanel keyTextBoxPanel = new TerminalAppTextBoxPanel(werminal, panelTitle, keyTextBox);
+
+ final WerminalAction showHistoryAction = new WerminalAction(getWerminal(), SHOW_HISTORY_BUTTON_LABEL)
+ {
+
+ @Override
+ public void doAction()
+ {
+
+ final Prototype prototype = werminal.getContext().getSchemaLoader().getPrototype(schemaUri);
+ final SortedSet keyHistory = werminal.getSlotValueHistory(schemaUri, keyInputName);
+ if (keyHistory != null && !keyHistory.isEmpty())
+ {
+ final String popupTitle = "Key History - " + prototype.getTitle() + " - " + panelTitle;
+ final HistoryPopup historyPopup = new HistoryPopup(werminal, popupTitle, keyTextBox);
+
+ final HistoryCheckListBox keyHistoryCheckListBox = historyPopup.getHistoryCheckListBox();
+
+ keyHistoryCheckListBox.addItems(keyHistory);
+ werminal.showWindow(historyPopup);
+ }
+ else
+ {
+ werminal.showMessageBox("Empty Key History",
+ "\nUnfortunately, there are no saved history values associated with the \"" + schemaTitle
+ + "." + keyInputName + "\" key slot.");
+ }
+
+ setFocus(keyTextBox);
+ }
+
+ };
+
+ final TerminalAppButton showHistoryButton = new TerminalAppButton(showHistoryAction);
+ keyTextBoxPanel.addComponent(showHistoryButton);
+ return keyTextBoxPanel;
+ }
+
+ private void updateKeysPanel(final URI schemaUri, final Keys keys)
+ {
+
+ _KeysPanel.removeAllComponents();
+ _KeyInputs.clear();
+ _KeySlotNames.clear();
+
+ if (schemaUri == null)
+ {
+ _KeysPanel.setTitle(DEFAULT_KEYS_PANEL_LABEL);
+ addKeyMessageLabel();
+
+ return;
+ }
+
+ final Context context = getWerminal().getContext();
+ final SchemaLoader schemaLoader = context.getSchemaLoader();
+
+ final Prototype prototype;
+ final Class> schemaInterface;
+ try
+ {
+ prototype = schemaLoader.getPrototype(schemaUri);
+ schemaInterface = schemaLoader.getSchemaInterface(schemaUri);
+ }
+ catch (final Exception e)
+ {
+
+ addKeyMessageLabel();
+
+ return;
+ }
+
+ final String title = String.format(" %1s%2s", prototype.getSchemaBean().getIntrospectedClass().getSimpleName(),
+ DEFAULT_KEYS_PANEL_LABEL);
+ _KeysPanel.setTitle(title);
+ _KeysPanel.addEmptySpace();
+
+ URI uri = null;
+
+ // Put Document's key first
+ if (Document.class.isAssignableFrom(schemaInterface))
+ {
+ final URI documentSchemaUri = schemaLoader.getDocumentSchemaUri();
+ final Prototype documentPrototype = schemaLoader.getPrototype(documentSchemaUri);
+ addKeyInput(schemaUri, documentPrototype, keys);
+
+ if (Schema.class.equals(schemaInterface))
+ {
+ final WerminalTextBox textBox = _KeyInputs.get(documentSchemaUri);
+ textBox.setText(SystemApi.Schema.getUri().toString() + "/com/example");
+ uri = (URI) textBox.getValue();
+
+ }
+ }
+
+ // Add all of the other key inputs; skipping Document's since we already made it first.
+ if (!Document.class.equals(schemaInterface))
+ {
+
+ addKeyInput(schemaUri, prototype, keys);
+
+ final Set basePrototypes = prototype.getDeclaredBasePrototypes();
+ for (final Prototype basePrototype : basePrototypes)
+ {
+ addKeyInput(schemaUri, basePrototype, keys);
+ }
+
+ }
+
+ /*
+ * TODO: Need to support opening by heap id?
+ *
+ * if (!_KeyInputs.isEmpty()) { // Added some keys.
+ *
+ * // or... heap id addMessageLabel("or", Alignment.CENTER); }
+ *
+ * // Add the heap id for UUID-based look-ups (for...debugging?) final TerminalAppTextBoxPanel
+ * heapIdTextBoxPanel = new TerminalAppTextBoxPanel(werminal, " Model.heapId [UUID]: ", _HeapIdTextBox);
+ * _KeysPanel.addComponent(heapIdTextBoxPanel);
+ */
+
+ if (uri != null)
+ {
+ updateKeysPanelDocumentSurrogateKeyInputs(uri);
+ }
+ }
+
+ private void updateKeysPanelDocumentSurrogateKeyInputs(final URI uri)
+ {
+
+ if (uri == null)
+ {
+ return;
+ }
+
+ final Context context = getWerminal().getContext();
+ final SchemaLoader schemaLoader = context.getSchemaLoader();
+ final ApiLoader apiLoader = context.getApiLoader();
+
+ final URI documentSchemaUri = schemaLoader.getDocumentSchemaUri();
+ final Keys allDocumentKeys = apiLoader.buildDocumentKeys(uri, getSchemaUri());
+ if (allDocumentKeys != null && allDocumentKeys.getCount() > 1)
+ {
+ final Set keyedSchemaUris = allDocumentKeys.getKeyedSchemaUris();
+ for (final URI keyedSchemaUri : keyedSchemaUris)
+ {
+ if (!keyedSchemaUri.equals(documentSchemaUri))
+ {
+ if (_KeyInputs.containsKey(keyedSchemaUri))
+ {
+ final WerminalTextBox surrogateKeyTextBox = _KeyInputs.get(keyedSchemaUri);
+ final Object surrogateKeyValue = allDocumentKeys.getValue(keyedSchemaUri);
+ surrogateKeyTextBox.setValue(surrogateKeyValue);
+ }
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/PrintDialog.java b/cli/src/main/java/org/wrml/werminal/dialog/PrintDialog.java
new file mode 100644
index 0000000..6aa136e
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/PrintDialog.java
@@ -0,0 +1,108 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wrml.werminal.dialog;
+
+import org.wrml.model.Model;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.terminal.TerminalAppPanel;
+
+import java.io.File;
+import java.net.URI;
+
+public class PrintDialog extends WerminalDialog
+{
+
+ private final WerminalTextBox _PrintToFilePathTextBox;
+
+ private URI _FormatUri;
+
+ private Model _Model;
+
+ public PrintDialog(final Werminal werminal, final String title)
+ {
+
+ super(werminal, title, werminal.getPrintConfirmationAction(), werminal.getCancelAction());
+
+ _PrintToFilePathTextBox = new WerminalTextBox(werminal, File.class, werminal.getPrintConfirmationAction());
+ render();
+ }
+
+ public File getPrintToFile()
+ {
+
+ return _PrintToFilePathTextBox.getValue();
+ }
+
+ public void setPrintToFile(final File file)
+ {
+
+ _PrintToFilePathTextBox.setValue(file);
+ }
+
+ @Override
+ public void render()
+ {
+
+ removeAllComponents();
+
+ final Werminal werminal = getWerminal();
+
+ final TerminalAppPanel printToFilePanel = new TerminalAppPanel(werminal, " Print to File: ");
+ printToFilePanel.addComponent(_PrintToFilePathTextBox);
+
+ addEmptySpace();
+ addComponent(printToFilePanel);
+ addEmptySpace();
+
+ super.renderFooterToolBar();
+
+ }
+
+ public URI getFormatUri()
+ {
+
+ return _FormatUri;
+ }
+
+ public void setFormatUri(final URI formatUri)
+ {
+
+ _FormatUri = formatUri;
+ }
+
+ public Model getModel()
+ {
+
+ return _Model;
+ }
+
+ public void setModel(final Model model)
+ {
+
+ _Model = model;
+ }
+}
\ No newline at end of file
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/PrintPreviewDialog.java b/cli/src/main/java/org/wrml/werminal/dialog/PrintPreviewDialog.java
new file mode 100644
index 0000000..c781468
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/PrintPreviewDialog.java
@@ -0,0 +1,283 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.dialog;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.Component;
+import com.googlecode.lanterna.gui.component.Label;
+import com.googlecode.lanterna.gui.component.Panel.Orientation;
+import com.googlecode.lanterna.terminal.TerminalSize;
+import org.wrml.model.Model;
+import org.wrml.model.schema.Schema;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.format.FormatLoader;
+import org.wrml.runtime.format.Formatter;
+import org.wrml.runtime.format.ModelWritingException;
+import org.wrml.runtime.format.SystemFormat;
+import org.wrml.runtime.format.application.schema.json.JsonSchema;
+import org.wrml.runtime.schema.SchemaLoader;
+import org.wrml.util.AsciiArt;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.component.HistoryCheckListBox;
+import org.wrml.werminal.component.WerminalActionListBox;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppPanel;
+import org.wrml.werminal.terminal.TerminalAppTextBoxPanel;
+import org.wrml.werminal.terminal.TerminalAppToolBar;
+import org.wrml.werminal.window.WerminalWindow;
+
+import java.io.ByteArrayOutputStream;
+import java.net.URI;
+import java.util.SortedSet;
+
+public class PrintPreviewDialog extends WerminalWindow
+{
+
+ private static final int COMPONENT_COLUMNS = 80;
+
+ private final Label _SchemaUriLabel;
+
+ private final HistoryCheckListBox _FormatUriHistoryCheckListBox;
+
+ private final WerminalTextBox _FormatUriTextBox;
+
+ private final WerminalActionListBox _PrintedModelLineListBox;
+
+ private Model _Model;
+
+ public PrintPreviewDialog(final Werminal werminal, final String title, final WerminalAction dismissAction)
+ {
+
+ super(werminal, title);
+
+ setBorder(new Border.Standard());
+
+ addEmptySpace();
+
+ _SchemaUriLabel = new Label("", COMPONENT_COLUMNS);
+ final TerminalAppPanel schemaPanel = new TerminalAppPanel(werminal, " Schema: ");
+ schemaPanel.addComponent(_SchemaUriLabel);
+
+ addEmptySpace();
+ addComponent(schemaPanel);
+
+ final WerminalAction formatConfirmAction = new WerminalAction(werminal, "Preview Format")
+ {
+
+ @Override
+ public void doAction()
+ {
+
+ updatePreview();
+
+ }
+ };
+
+ _FormatUriTextBox = new WerminalTextBox(werminal, COMPONENT_COLUMNS, URI.class, formatConfirmAction);
+ final TerminalAppTextBoxPanel formatUriTextBoxPanel = new TerminalAppTextBoxPanel(werminal, " Format [URI]: ",
+ _FormatUriTextBox);
+ addEmptySpace();
+ addComponent(formatUriTextBoxPanel);
+
+ final TerminalAppPanel formatsPanel = new TerminalAppPanel(werminal, " Formats: ", new Border.Standard(),
+ Orientation.VERTICAL);
+ _FormatUriHistoryCheckListBox = new HistoryCheckListBox(_FormatUriTextBox, formatConfirmAction, null);
+ _FormatUriHistoryCheckListBox.setPreferredSize(new TerminalSize(70, 10));
+ formatsPanel.addEmptySpace();
+ formatsPanel.addComponent(_FormatUriHistoryCheckListBox);
+ formatsPanel.addEmptySpace();
+
+ addComponent(formatsPanel);
+
+ final TerminalAppPanel previewPanel = new TerminalAppPanel(werminal, " Preview: ", new Border.Standard(),
+ Orientation.VERTICAL);
+ _PrintedModelLineListBox = new WerminalActionListBox(werminal);
+ _PrintedModelLineListBox.setPreferredSize(new TerminalSize(COMPONENT_COLUMNS, 30));
+ previewPanel.addEmptySpace();
+ previewPanel.addComponent(_PrintedModelLineListBox);
+ previewPanel.addEmptySpace();
+
+ addEmptySpace();
+ addComponent(previewPanel);
+
+ final TerminalAppToolBar footerToolBar = new TerminalAppToolBar(werminal,
+ new Component[]{new TerminalAppButtonPanel(werminal.getPrintAction()), new TerminalAppButtonPanel(dismissAction)});
+ addEmptySpace();
+ addComponent(footerToolBar);
+
+ }
+
+ public URI getFormatUri()
+ {
+
+ return (URI) _FormatUriTextBox.getValue();
+ }
+
+ public Model getModel()
+ {
+
+ return _Model;
+ }
+
+ public void setModel(final Model model)
+ {
+
+ _Model = model;
+ final URI schemaUri = _Model.getSchemaUri();
+ _SchemaUriLabel.setText(String.valueOf(schemaUri));
+
+ _FormatUriHistoryCheckListBox.clearItems();
+
+ final Context context = model.getContext();
+ final FormatLoader formatLoader = context.getFormatLoader();
+ final SortedSet formatUris = formatLoader.getLoadedFormatUris();
+ final URI defaultFormatUri = formatLoader.getDefaultFormatUri();
+
+ for (final URI formatUri : formatUris)
+ {
+ final Formatter formatter = formatLoader.getFormatter(formatUri);
+ if (formatter.isApplicableTo(model.getSchemaUri()))
+ {
+ _FormatUriHistoryCheckListBox.addItem(formatUri);
+
+ if (formatUri.equals(defaultFormatUri))
+ {
+ _FormatUriHistoryCheckListBox.setCheckedItem(formatUri);
+ }
+
+ }
+ }
+
+ updatePreview();
+ }
+
+ private void updatePreview()
+ {
+
+ final Werminal werminal = getWerminal();
+ final Model model = getModel();
+
+ final Context context = model.getContext();
+ final FormatLoader formatLoader = context.getFormatLoader();
+
+ URI formatUri = getFormatUri();
+ if (formatUri == null)
+ {
+
+ formatUri = formatLoader.getDefaultFormatUri();
+ }
+
+ _FormatUriHistoryCheckListBox.setCheckedItem(formatUri);
+
+ final String printOut;
+ if (model instanceof Schema && formatUri.equals(SystemFormat.json_schema.getFormatUri()))
+ {
+ final Schema wrmlSchema = (Schema) model;
+ final SchemaLoader schemaLoader = context.getSchemaLoader();
+ final JsonSchema jsonSchema = schemaLoader.getJsonSchemaLoader().load(wrmlSchema);
+ printOut = AsciiArt.express(jsonSchema.getRootNode());
+ }
+ else
+ {
+
+ final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+
+ try
+ {
+ context.writeModel(byteOut, model, formatUri);
+ }
+ catch (final ModelWritingException e)
+ {
+ werminal.showError("Unable to express the model " + model.getHeapId() + ", returning null.", e);
+ return;
+ }
+
+ final byte[] modelBytes = byteOut.toByteArray();
+ printOut = new String(modelBytes);
+ }
+
+ final String[] unwrappedLines = printOut.split("\n");
+
+ _PrintedModelLineListBox.clearItems();
+
+ for (final String line : unwrappedLines)
+ {
+ _PrintedModelLineListBox.addAction(new PrintedLineAction(werminal, line));
+ }
+
+ }
+
+ private class PrintedLineAction extends WerminalAction
+ {
+
+ private final String _Line;
+
+ public PrintedLineAction(final Werminal werminal, final String line)
+ {
+
+ super(werminal, "");
+ _Line = line;
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ String line = getLine();
+ if (line == null)
+ {
+ return;
+ }
+
+ line = line.trim();
+
+ if (line.isEmpty())
+ {
+ return;
+ }
+
+ final Werminal werminal = getWerminal();
+
+ werminal.showMessageBox("Selected Line", "\n\n" + _Line.trim() + "\n\n");
+ }
+
+ public String getLine()
+ {
+
+ return _Line;
+ }
+
+ @Override
+ public String toString()
+ {
+
+ return getLine();
+ }
+
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/SetOriginDialog.java b/cli/src/main/java/org/wrml/werminal/dialog/SetOriginDialog.java
new file mode 100644
index 0000000..585585f
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/SetOriginDialog.java
@@ -0,0 +1,137 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.dialog;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.Component;
+import com.googlecode.lanterna.gui.component.RadioCheckBoxList;
+import com.googlecode.lanterna.input.Key;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.service.ServiceLoader;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppKeyboardInteraction;
+import org.wrml.werminal.terminal.TerminalAppToolBar;
+import org.wrml.werminal.window.WerminalWindow;
+
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+public class SetOriginDialog extends WerminalWindow
+{
+
+ private final OriginValuesCheckBoxList _OriginValuesCheckBoxList;
+
+ public SetOriginDialog(final Werminal werminal, final String title, final WerminalAction confirmAction, final WerminalAction dismissAction)
+ {
+
+ super(werminal, title);
+
+ setBorder(new Border.Standard());
+
+ _OriginValuesCheckBoxList = new OriginValuesCheckBoxList(werminal, confirmAction);
+
+ addEmptySpace();
+
+ addComponent(_OriginValuesCheckBoxList);
+
+ final TerminalAppToolBar footerToolBar = new TerminalAppToolBar(werminal, new Component[]{
+ new TerminalAppButtonPanel(confirmAction), new TerminalAppButtonPanel(dismissAction)});
+ addComponent(footerToolBar);
+ }
+
+ public final String getSelectedValue()
+ {
+
+ return (String) _OriginValuesCheckBoxList.getItemAt(_OriginValuesCheckBoxList.getCheckedItemIndex());
+ }
+
+ public final void setSelectedValue(final String selectedValue)
+ {
+
+ _OriginValuesCheckBoxList.clearItems();
+
+
+ final Context context = getWerminal().getContext();
+ final ServiceLoader serviceLoader = context.getServiceLoader();
+
+ final Set serviceNames = serviceLoader.getServiceNames();
+
+ final SortedSet sortedServiceNames = new TreeSet<>(serviceNames);
+
+ int index = 0;
+ for (final String serviceName : sortedServiceNames)
+ {
+
+ _OriginValuesCheckBoxList.addItem(serviceName);
+
+ if (serviceName.equals(selectedValue))
+ {
+ _OriginValuesCheckBoxList.setCheckedItemIndex(index);
+ }
+
+ index++;
+ }
+
+
+ }
+
+ public static class OriginValuesCheckBoxList extends RadioCheckBoxList
+ {
+
+ private final TerminalAppKeyboardInteraction _KeyboardInteraction;
+
+ public OriginValuesCheckBoxList(final Werminal werminal, final WerminalAction confirmAction)
+ {
+
+ _KeyboardInteraction = new TerminalAppKeyboardInteraction(werminal, confirmAction, true);
+ }
+
+ @Override
+ public Result keyboardInteraction(final Key key)
+ {
+
+ if (!isVisible())
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ if (key.getKind() == Key.Kind.Enter)
+ {
+ super.keyboardInteraction(key);
+ }
+
+ if (_KeyboardInteraction.handleKeyboardInteraction(key))
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ return super.keyboardInteraction(key);
+ }
+
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/dialog/WerminalDialog.java b/cli/src/main/java/org/wrml/werminal/dialog/WerminalDialog.java
new file mode 100644
index 0000000..ae6e8cd
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/dialog/WerminalDialog.java
@@ -0,0 +1,96 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.dialog;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.Component;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppToolBar;
+import org.wrml.werminal.window.WerminalWindow;
+
+public class WerminalDialog extends WerminalWindow
+{
+
+ private final TerminalAppToolBar _FooterToolBar;
+
+ public WerminalDialog(final Werminal werminal, final String title, final WerminalAction confirmAction,
+ final WerminalAction dismissAction)
+ {
+
+ super(werminal, title);
+
+ setBorder(new Border.Standard());
+
+ final Component[] footerToolBarComponents;
+ if (confirmAction != null && dismissAction != null)
+ {
+ footerToolBarComponents = new Component[]{new TerminalAppButtonPanel(confirmAction),
+ new TerminalAppButtonPanel(dismissAction)};
+ }
+ else if (confirmAction != null)
+ {
+ footerToolBarComponents = new Component[]{new TerminalAppButtonPanel(confirmAction)};
+ }
+
+ else if (dismissAction != null)
+ {
+ footerToolBarComponents = new Component[]{new TerminalAppButtonPanel(dismissAction)};
+ }
+ else
+ {
+ footerToolBarComponents = null;
+ }
+
+ if (footerToolBarComponents != null)
+ {
+ _FooterToolBar = new TerminalAppToolBar(werminal, footerToolBarComponents);
+ }
+ else
+ {
+ _FooterToolBar = null;
+ }
+ render();
+ }
+
+ @Override
+ public void render()
+ {
+
+ super.render();
+ renderFooterToolBar();
+ }
+
+ protected final void renderFooterToolBar()
+ {
+
+ if (_FooterToolBar != null)
+ {
+ addComponent(_FooterToolBar);
+ }
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/model/EntryModel.java b/cli/src/main/java/org/wrml/werminal/model/EntryModel.java
new file mode 100644
index 0000000..9cb7865
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/model/EntryModel.java
@@ -0,0 +1,36 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright 2012 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.model;
+
+import org.wrml.model.Model;
+import org.wrml.model.Named;
+
+public interface EntryModel extends Named, Model
+{
+
+ String getValue();
+
+ String setValue(final String stringValue);
+}
\ No newline at end of file
diff --git a/cli/src/main/java/org/wrml/werminal/model/SlotValueHistoryListModel.java b/cli/src/main/java/org/wrml/werminal/model/SlotValueHistoryListModel.java
new file mode 100644
index 0000000..6354c35
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/model/SlotValueHistoryListModel.java
@@ -0,0 +1,40 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright 2012 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.model;
+
+import org.wrml.model.Model;
+
+import java.net.URI;
+import java.util.List;
+
+public interface SlotValueHistoryListModel extends Model
+{
+
+ URI getHistoryListSchemaUri();
+
+ List getSlotValueEntries();
+
+ URI setHistoryListSchemaUri(URI schemaUri);
+}
diff --git a/cli/src/main/java/org/wrml/werminal/model/WerminalModel.java b/cli/src/main/java/org/wrml/werminal/model/WerminalModel.java
new file mode 100644
index 0000000..1d0eeab
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/model/WerminalModel.java
@@ -0,0 +1,40 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright 2012 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.model;
+
+import org.wrml.model.Filed;
+import org.wrml.model.Titled;
+import org.wrml.model.rest.Document;
+
+import java.net.URI;
+import java.util.List;
+
+public interface WerminalModel extends Titled, Filed, Document
+{
+ List getSchemaUriHistoryList();
+
+ List getSlotValueHistoryLists();
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalApp.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalApp.java
new file mode 100644
index 0000000..668cff1
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalApp.java
@@ -0,0 +1,234 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.TerminalFacade;
+import com.googlecode.lanterna.gui.GUIScreen;
+import com.googlecode.lanterna.gui.Window;
+import com.googlecode.lanterna.gui.dialog.DialogResult;
+import com.googlecode.lanterna.gui.dialog.MessageBox;
+import com.googlecode.lanterna.terminal.Terminal;
+import com.googlecode.lanterna.terminal.text.UnixTerminal;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.wrml.runtime.Context;
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.LinkedList;
+
+/**
+ *
+ * {@link TerminalApp} is a terminal (command line) application.
+ *
+ */
+public class TerminalApp
+{
+
+ private static final Logger LOG = LoggerFactory.getLogger(TerminalApp.class);
+
+ private final String _AppTitle;
+
+ private final Context _Context;
+
+ private final GUIScreen _GuiScreen;
+
+ private final LinkedList _WindowStack;
+
+ public TerminalApp(final String appTitle, final Context context) throws Exception
+ {
+
+ this(appTitle, context, TerminalType.Swing);
+ }
+
+ public TerminalApp(final String appTitle, final Context context, final TerminalType terminalType) throws Exception
+ {
+
+ _AppTitle = appTitle;
+ _Context = context;
+
+ final Terminal terminal;
+ switch (terminalType)
+ {
+
+ case Swing:
+ {
+ /*
+ * This construction of the GUIScreen leads to the less cool looking
+ * (but still pretty cool) Swing Terminal emulator.
+ */
+ // Setting to arbitrary large dimensions to scale the window up more.
+ terminal = TerminalFacade.createSwingTerminal(110, 60);
+ break;
+ }
+ case Unix:
+ {
+ /*
+ * Using the UnixTerminal forces the use of the much cooler looking
+ * Terminal shell (on Mac OS X at least).
+ */
+
+ terminal = new UnixTerminal(System.in, System.out, Charset.forName("UTF8"));
+ break;
+ }
+ default:
+ throw new TerminalAppException("Unknkown terminal type: " + terminalType, null, this);
+ }
+
+ _GuiScreen = TerminalFacade.createGUIScreen(terminal);
+
+ _WindowStack = new LinkedList<>();
+
+ if (_GuiScreen == null)
+ {
+ LOG.error("Couldn't allocate a terminal!");
+ throw new TerminalAppException("Couldn't allocate a terminal!", null, this);
+ }
+
+ }
+
+ public final Context getContext()
+ {
+
+ return _Context;
+ }
+
+ public final void closeTopWindow()
+ {
+
+ if (_WindowStack.isEmpty())
+ {
+ return;
+ }
+
+ final Window topWindowToClose = _WindowStack.peek();
+
+ // TODO: Check window edited state before closing.
+ topWindowToClose.close();
+ _WindowStack.pop();
+ _GuiScreen.getScreen().refresh();
+
+ }
+
+ /**
+ * Keeps line breaks in input string but also adds additional to wrap to fit screen.
+ */
+ public final String formatMessageBoxTextToWrap(final String input)
+ {
+
+ // TODO: Write a better algorithm for preservation of leading whitespace
+ final String funkyText = "`Z!0";
+ final String text = input.replace(" ", funkyText).replace("\t", funkyText);
+
+ final int columns = _GuiScreen.getScreen().getTerminalSize().getColumns();
+ final int maxWidth = columns - 10;
+ final StringBuilder wrapped = new StringBuilder();
+
+ final String[] lines = text.split("\n");
+
+ for (final String line : lines)
+ {
+ int lineLen = 0;
+ final String[] words = line.split("\\s+");
+
+ for (final String word : words)
+ {
+ if (lineLen + word.length() > maxWidth)
+ {
+ wrapped.append("\n");
+ lineLen = 0;
+ }
+
+ wrapped.append(word);
+ wrapped.append(" ");
+ lineLen += word.length() + 1;
+ }
+ wrapped.append("\n");
+ }
+
+ return wrapped.toString().replace(funkyText, " ");
+ }
+
+ public final GUIScreen getGuiScreen()
+ {
+
+ return _GuiScreen;
+ }
+
+ public final Window getTopWindow()
+ {
+
+ return _WindowStack.peek();
+ }
+
+ public final void showError(final String errorMessage)
+ {
+
+ showError(errorMessage, null);
+ }
+
+ public final void showError(final String errorMessage, final Throwable t)
+ {
+
+ if (t != null)
+ {
+ showMessageBox("Error", "\n" + errorMessage + "\n\nError Details:\n\n" + t + "\n\nError Stack:\n\n" + Arrays.deepToString(t.getStackTrace()));
+ }
+ else
+ {
+ showMessageBox("Error", "\n" + errorMessage);
+ }
+ }
+
+ public final DialogResult showMessageBox(final String title, final String message)
+ {
+
+ final StringBuilder titleBuilder = new StringBuilder(" ").append(getAppTitle()).append(" - ")
+ .append(title).append(" ");
+
+ return MessageBox.showMessageBox(_GuiScreen, titleBuilder.toString(), formatMessageBoxTextToWrap(message));
+ }
+
+ public final String getAppTitle()
+ {
+
+ return _AppTitle;
+ }
+
+ public final void showWindow(final Window window)
+ {
+
+ showWindow(window, GUIScreen.Position.CENTER);
+ }
+
+ public final void showWindow(final Window window, final GUIScreen.Position position)
+ {
+
+ _WindowStack.push(window);
+ _GuiScreen.showWindow(window, position);
+ }
+
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppAction.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppAction.java
new file mode 100644
index 0000000..2335c16
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppAction.java
@@ -0,0 +1,69 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.Action;
+import org.wrml.runtime.Context;
+
+public abstract class TerminalAppAction implements Action
+{
+
+ private final TerminalApp _App;
+
+ private String _Title;
+
+ public TerminalAppAction(final TerminalApp app, final String title)
+ {
+
+ _App = app;
+ _Title = title;
+ }
+
+ @SuppressWarnings("unchecked")
+ public final T getApp()
+ {
+
+ return (T) _App;
+ }
+
+ public final Context getContext()
+ {
+
+ return getApp().getContext();
+ }
+
+ public final String getTitle()
+ {
+
+ return _Title;
+ }
+
+ public final void setTitle(final String title)
+ {
+
+ _Title = title;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppButton.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppButton.java
new file mode 100644
index 0000000..f39b2ed
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppButton.java
@@ -0,0 +1,112 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.component.Button;
+import com.googlecode.lanterna.input.Key;
+import com.googlecode.lanterna.terminal.TerminalSize;
+
+public class TerminalAppButton extends Button
+{
+
+ private final TerminalAppKeyboardInteraction _KeyboardInteraction;
+
+ private TerminalAppAction _Action;
+
+ private TerminalSize _PreferredSize;
+
+ public TerminalAppButton(final TerminalAppAction action)
+ {
+
+ super(action.getTitle());
+ setAction(action);
+ _KeyboardInteraction = new TerminalAppKeyboardInteraction(action.getApp(), action, true);
+ }
+
+ public TerminalAppAction getAction()
+ {
+
+ return _Action;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T getApp()
+ {
+
+ return (T) getAction().getApp();
+ }
+
+ @Override
+ public final TerminalSize getPreferredSize()
+ {
+
+ if (_PreferredSize == null)
+ {
+ return super.getPreferredSize();
+ }
+
+ return _PreferredSize;
+ }
+
+ @Override
+ public Result keyboardInteraction(final Key key)
+ {
+
+ if (!isVisible())
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ if (_KeyboardInteraction.handleKeyboardInteraction(key))
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ return super.keyboardInteraction(key);
+
+ }
+
+ public void setAction(final TerminalAppAction action)
+ {
+
+ _Action = action;
+ setText(_Action.getTitle());
+ }
+
+ @Override
+ public final void setPreferredSize(final TerminalSize preferredSize)
+ {
+
+ _PreferredSize = preferredSize;
+ }
+
+ @Override
+ public String toString()
+ {
+
+ return "TerminalButton (" + super.toString() + ")";
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppButtonPanel.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppButtonPanel.java
new file mode 100644
index 0000000..e93b594
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppButtonPanel.java
@@ -0,0 +1,54 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.component.Panel;
+
+public class TerminalAppButtonPanel extends TerminalAppPanel
+{
+
+ private final TerminalAppButton _Button;
+
+ public TerminalAppButtonPanel(final TerminalAppAction action)
+ {
+
+ this(new TerminalAppButton(action));
+ }
+
+ public TerminalAppButtonPanel(final TerminalAppButton button)
+ {
+
+ super(button.getApp(), new Border.Standard(), Panel.Orientation.HORISONTAL);
+ _Button = button;
+ addComponent(_Button);
+ }
+
+ public TerminalAppButton getButton()
+ {
+
+ return _Button;
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppException.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppException.java
new file mode 100644
index 0000000..2af91c1
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppException.java
@@ -0,0 +1,50 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+/**
+ * The {@link TerminalApp}'s associated error type.
+ */
+public class TerminalAppException extends RuntimeException
+{
+
+ private static final long serialVersionUID = 1L;
+
+ private final TerminalApp _App;
+
+ protected TerminalAppException(final String message, final Throwable cause, final TerminalApp app)
+ {
+
+ super(message, cause);
+ _App = app;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T getApp()
+ {
+
+ return (T) _App;
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppKeyboardInteraction.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppKeyboardInteraction.java
new file mode 100644
index 0000000..153f8d7
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppKeyboardInteraction.java
@@ -0,0 +1,99 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.Action;
+import com.googlecode.lanterna.input.Key;
+import com.googlecode.lanterna.input.Key.Kind;
+
+public class TerminalAppKeyboardInteraction
+{
+
+ private final TerminalApp _App;
+
+ private final Action _EnterAction;
+
+ private final boolean _CloseOnEscape;
+
+ public TerminalAppKeyboardInteraction(final TerminalApp app, final Action enterAction, final boolean closeOnEscape)
+ {
+
+ _App = app;
+ _EnterAction = enterAction;
+ _CloseOnEscape = closeOnEscape;
+ }
+
+ public TerminalApp getApp()
+ {
+
+ return _App;
+ }
+
+ public Action getEnterAction()
+ {
+
+ return _EnterAction;
+ }
+
+ public boolean handleKeyboardInteraction(final Key key)
+ {
+
+ final Kind kind = key.getKind();
+
+ boolean handled = false;
+ switch (kind)
+ {
+
+ case Enter:
+ {
+
+ if (_EnterAction != null)
+ {
+ _EnterAction.doAction();
+ handled = true;
+ }
+
+ break;
+ }
+ case Escape:
+ {
+ if (_CloseOnEscape)
+ {
+ _App.closeTopWindow();
+ handled = true;
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return handled;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppMenu.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppMenu.java
new file mode 100644
index 0000000..6526cdc
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppMenu.java
@@ -0,0 +1,44 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.component.Panel;
+
+public class TerminalAppMenu extends TerminalAppPanel
+{
+
+ public TerminalAppMenu(final TerminalApp app)
+ {
+
+ this(app, null);
+ }
+
+ public TerminalAppMenu(final TerminalApp app, final String title)
+ {
+
+ super(app, title, new Border.Bevel(true), Panel.Orientation.VERTICAL);
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppMenuWindow.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppMenuWindow.java
new file mode 100644
index 0000000..823d52a
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppMenuWindow.java
@@ -0,0 +1,71 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.Component;
+import com.googlecode.lanterna.gui.component.EmptySpace;
+
+public class TerminalAppMenuWindow extends TerminalAppWindow
+{
+
+ private final TerminalAppPanel _MenuBar;
+
+ private final Component _FooterComponent;
+
+ public TerminalAppMenuWindow(final TerminalApp app, final String title, final TerminalAppPanel menuBar,
+ final Component footerComponent)
+ {
+
+ super(app, " " + title + " ");
+
+ _MenuBar = menuBar;
+ _FooterComponent = footerComponent;
+
+ setBorder(new Border.Bevel(false));
+
+ // setBetweenComponentsPadding(0);
+
+ addComponent(new EmptySpace(0, 1));
+
+ addComponent(_MenuBar);
+
+ // Refactoring note (may be deleted)
+ // closeButtonPanel.getButton().setPreferredSize(new TerminalSize(10,
+ // 1));
+
+ if (_FooterComponent != null)
+ {
+ addComponent(_FooterComponent);
+ }
+ }
+
+ public TerminalAppPanel getMenuBar()
+ {
+
+ return _MenuBar;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppNameValueLabel.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppNameValueLabel.java
new file mode 100644
index 0000000..cf0c31c
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppNameValueLabel.java
@@ -0,0 +1,80 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.component.Label;
+import com.googlecode.lanterna.gui.layout.LinearLayout;
+import com.googlecode.lanterna.terminal.Terminal;
+
+public class TerminalAppNameValueLabel extends TerminalAppPanel
+{
+
+ private final Label _NameLabel;
+
+ private final Label _ValueLabel;
+
+ public TerminalAppNameValueLabel(final TerminalApp app, final String name, final int nameWidth,
+ final Terminal.Color nameColor, final boolean nameBold, final Alignment nameAlignment, final String value,
+ final int valueWidth, final Terminal.Color valueColor, final boolean valueBold,
+ final Alignment valueAlignment)
+ {
+
+ super(app, "", new Border.Invisible(), Orientation.HORISONTAL, false, false);
+
+ // setBetweenComponentsPadding(0);
+
+ _NameLabel = new Label(name, nameWidth, nameColor, nameBold);
+ _NameLabel.setAlignment(nameAlignment);
+ addComponent(_NameLabel);
+
+ _ValueLabel = new Label(value, valueWidth, valueColor, valueBold);
+ _ValueLabel.setAlignment(valueAlignment);
+ addComponent(_ValueLabel, LinearLayout.GROWS_HORIZONTALLY);
+
+ }
+
+ public TerminalAppNameValueLabel(final TerminalApp app, final String name, final int nameWidth,
+ final Terminal.Color nameColor, final boolean nameBold, final String value, final int valueWidth,
+ final Terminal.Color valueColor, final boolean valueBold)
+ {
+
+ this(app, name, nameWidth, nameColor, nameBold, Alignment.RIGHT_CENTER, value, valueWidth, valueColor,
+ valueBold, Alignment.LEFT_CENTER);
+ }
+
+ public Label getNameLabel()
+ {
+
+ return _NameLabel;
+ }
+
+ public Label getValueLabel()
+ {
+
+ return _ValueLabel;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppPanel.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppPanel.java
new file mode 100644
index 0000000..4e515f1
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppPanel.java
@@ -0,0 +1,149 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.component.EmptySpace;
+import com.googlecode.lanterna.gui.component.Panel;
+import com.googlecode.lanterna.terminal.TerminalSize;
+
+public class TerminalAppPanel extends Panel
+{
+
+ private final TerminalApp _App;
+
+ private TerminalSize _PreferredSize;
+
+ private boolean _HorizontallyMaximized;
+
+ private boolean _VerticallyMaximized;
+
+ public TerminalAppPanel(final TerminalApp app)
+ {
+
+ this(app, "", new Border.Standard(), Orientation.VERTICAL, false, false);
+ }
+
+ public TerminalAppPanel(final TerminalApp app, final Border border, final Orientation orientation)
+ {
+
+ this(app, "", border, orientation, false, false);
+ }
+
+ public TerminalAppPanel(final TerminalApp app, final String title)
+ {
+
+ this(app, title, new Border.Standard(), Orientation.VERTICAL, false, false);
+ }
+
+ public TerminalAppPanel(final TerminalApp app, final String title, final Border border,
+ final Orientation orientation)
+ {
+
+ this(app, title, border, orientation, false, false);
+ }
+
+ public TerminalAppPanel(final TerminalApp app, final String title, final Border border,
+ final Orientation orientation, final boolean horizontallyMaximized, final boolean verticallyMaximized)
+ {
+
+ super(title, border, orientation);
+ _App = app;
+ // setBetweenComponentsPadding(0);
+
+ _HorizontallyMaximized = horizontallyMaximized;
+ _VerticallyMaximized = verticallyMaximized;
+ }
+
+ public void addEmptySpace()
+ {
+ // addComponent(new Label());
+ addComponent(new EmptySpace(0, 1));
+ }
+
+ @SuppressWarnings("unchecked")
+ public T getApp()
+ {
+
+ return (T) _App;
+ }
+
+ @Override
+ public final TerminalSize getPreferredSize()
+ {
+
+ if (_PreferredSize == null)
+ {
+ return super.getPreferredSize();
+ }
+
+ return _PreferredSize;
+ }
+
+ public boolean isHorizontallyMaximized()
+ {
+
+ return _HorizontallyMaximized;
+ }
+
+ public boolean isVerticallyMaximized()
+ {
+
+ return _VerticallyMaximized;
+ }
+
+ @Override
+ public final boolean maximisesHorisontally()
+ {
+
+ return _HorizontallyMaximized;
+ }
+
+ @Override
+ public final boolean maximisesVertically()
+ {
+
+ return _VerticallyMaximized;
+ }
+
+ public void setHorizontallyMaximized(final boolean horizontallyMaximized)
+ {
+
+ _HorizontallyMaximized = horizontallyMaximized;
+ }
+
+ @Override
+ public final void setPreferredSize(final TerminalSize preferredSize)
+ {
+
+ _PreferredSize = preferredSize;
+ }
+
+ public void setVerticallyMaximized(final boolean verticallyMaximized)
+ {
+
+ _VerticallyMaximized = verticallyMaximized;
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTextArea.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTextArea.java
new file mode 100644
index 0000000..9aba90b
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTextArea.java
@@ -0,0 +1,75 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.component.TextArea;
+import com.googlecode.lanterna.input.Key;
+import com.googlecode.lanterna.terminal.TerminalSize;
+
+public class TerminalAppTextArea extends TextArea
+{
+
+ private final TerminalApp _App;
+
+ private final TerminalAppKeyboardInteraction _KeyboardInteraction;
+
+ public TerminalAppTextArea(final TerminalApp app, final TerminalSize preferredSize, final String text)
+ {
+
+ super(preferredSize, text);
+ _App = app;
+ _KeyboardInteraction = createTerminalAppKeyboardInteraction();
+ }
+
+ @SuppressWarnings("unchecked")
+ public T getApp()
+ {
+
+ return (T) _App;
+ }
+
+ @Override
+ public Result keyboardInteraction(final Key key)
+ {
+
+ if (!isVisible())
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ if (_KeyboardInteraction.handleKeyboardInteraction(key))
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ return super.keyboardInteraction(key);
+ }
+
+ protected TerminalAppKeyboardInteraction createTerminalAppKeyboardInteraction()
+ {
+
+ return new TerminalAppKeyboardInteraction(getApp(), null, true);
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTextBox.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTextBox.java
new file mode 100644
index 0000000..6ec876f
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTextBox.java
@@ -0,0 +1,152 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.component.TextBox;
+import com.googlecode.lanterna.input.Key;
+import com.googlecode.lanterna.terminal.TerminalSize;
+import org.wrml.werminal.util.ClipboardUtils;
+
+public class TerminalAppTextBox extends TextBox
+{
+
+ private final TerminalApp _App;
+
+ private final TerminalAppKeyboardInteraction _KeyboardInteraction;
+
+ private TerminalSize _PreferredSize;
+
+ public TerminalAppTextBox(final TerminalApp app)
+ {
+
+ this(app, 10, null);
+ }
+
+ public TerminalAppTextBox(final TerminalApp app, final int width)
+ {
+
+ this(app, width, null);
+ }
+
+ public TerminalAppTextBox(final TerminalApp app, final int width, final String title)
+ {
+
+ super(title, width);
+ _App = app;
+ _KeyboardInteraction = createTerminalAppKeyboardInteraction();
+
+ }
+
+ public TerminalAppTextBox(final TerminalApp app, final String title)
+ {
+
+ this(app, 10, title);
+ }
+
+ @SuppressWarnings("unchecked")
+ public T getApp()
+ {
+
+ return (T) _App;
+ }
+
+ @Override
+ public final TerminalSize getPreferredSize()
+ {
+
+ if (_PreferredSize == null)
+ {
+ return super.getPreferredSize();
+ }
+
+ return _PreferredSize;
+ }
+
+ @Override
+ public final void setPreferredSize(final TerminalSize preferredSize)
+ {
+
+ _PreferredSize = preferredSize;
+ }
+
+ @Override
+ public Result keyboardInteraction(final Key key)
+ {
+
+ if (!isVisible())
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ if (_KeyboardInteraction.handleKeyboardInteraction(key))
+ {
+ return Result.EVENT_HANDLED;
+ }
+
+ if (key.getKind() == Key.Kind.NormalKey)
+ {
+ if (key.isCtrlPressed())
+ {
+
+ final char keyCharacter = key.getCharacter();
+ if (keyCharacter == 'C' || keyCharacter == 'c')
+ {
+ // COPY
+ ClipboardUtils.setClipboardText(getText());
+ return Result.EVENT_HANDLED;
+ }
+ else if (keyCharacter == 'V' || keyCharacter == 'v')
+ {
+ // PASTE
+ final String text = ClipboardUtils.getClipboardText();
+ if (text != null && !text.isEmpty())
+ {
+ setText(text);
+ return Result.EVENT_HANDLED;
+ }
+
+ }
+ else if (keyCharacter == 'X' || keyCharacter == 'x')
+ {
+ // CUT
+ ClipboardUtils.setClipboardText(getText());
+ setText("");
+ return Result.EVENT_HANDLED;
+ }
+
+ }
+ }
+
+
+ return super.keyboardInteraction(key);
+ }
+
+ protected TerminalAppKeyboardInteraction createTerminalAppKeyboardInteraction()
+ {
+
+ return new TerminalAppKeyboardInteraction(getApp(), null, true);
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTextBoxPanel.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTextBoxPanel.java
new file mode 100644
index 0000000..9b3ef4c
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTextBoxPanel.java
@@ -0,0 +1,54 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.Border;
+
+public class TerminalAppTextBoxPanel extends TerminalAppPanel
+{
+
+ private final TerminalAppTextBox _TextBox;
+
+ public TerminalAppTextBoxPanel(final TerminalApp app, final String title, final int textBoxWidth)
+ {
+
+ this(app, title, new TerminalAppTextBox(app, textBoxWidth));
+ }
+
+ public TerminalAppTextBoxPanel(final TerminalApp app, final String title, final TerminalAppTextBox terminalTextBox)
+ {
+
+ super(app, title, new Border.Standard(), Orientation.HORISONTAL, false, false);
+ _TextBox = terminalTextBox;
+ addComponent(_TextBox);
+ }
+
+ public TerminalAppTextBox getTextBox()
+ {
+
+ return _TextBox;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTheme.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTheme.java
new file mode 100644
index 0000000..cbe11af
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppTheme.java
@@ -0,0 +1,69 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.Theme;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class TerminalAppTheme> extends Theme
+{
+
+ private final Map _Definitions;
+
+ private final Map _CategorizedDefinitions;
+
+ private final Class _DefinitionEnumClass;
+
+ public TerminalAppTheme(final Class definitionEnumClass)
+ {
+
+ _DefinitionEnumClass = definitionEnumClass;
+ _Definitions = new HashMap<>();
+ _CategorizedDefinitions = new HashMap<>();
+ }
+
+ protected Map getCategorizedDefinitions()
+ {
+
+ return _CategorizedDefinitions;
+ }
+
+
+ protected Map getDefinitions()
+ {
+
+ return _Definitions;
+ }
+
+ @Override
+ public Definition getDefinition(final Category category)
+ {
+
+ return _CategorizedDefinitions.get(category);
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppToolBar.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppToolBar.java
new file mode 100644
index 0000000..f1910bb
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppToolBar.java
@@ -0,0 +1,59 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.Component;
+import com.googlecode.lanterna.gui.component.EmptySpace;
+
+public class TerminalAppToolBar extends TerminalAppPanel
+{
+
+ private final Component[] _Components;
+
+ public TerminalAppToolBar(final TerminalApp app, final Component[] components)
+ {
+
+ super(app, "", new Border.Invisible(), Orientation.HORISONTAL);
+
+ _Components = components;
+
+ // setBetweenComponentsPadding(0);
+
+ for (final Component component : components)
+ {
+ addComponent(component);
+ addComponent(new EmptySpace(2, 0));
+ }
+
+ }
+
+ public Component[] getComponents()
+ {
+
+ return _Components;
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppWindow.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppWindow.java
new file mode 100644
index 0000000..178e317
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalAppWindow.java
@@ -0,0 +1,66 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.gui.Interactable;
+import com.googlecode.lanterna.gui.Interactable.FocusChangeDirection;
+import com.googlecode.lanterna.gui.Window;
+
+public class TerminalAppWindow extends Window
+{
+
+ private final TerminalApp _App;
+
+ public TerminalAppWindow(final TerminalApp app, final String title)
+ {
+
+ super(title);
+
+ _App = app;
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public T getApp()
+ {
+
+ return (T) _App;
+ }
+
+ @Override
+ public void setFocus(final Interactable newFocus)
+ {
+
+ super.setFocus(newFocus);
+ }
+
+ @Override
+ public void setFocus(final Interactable newFocus, final FocusChangeDirection direction)
+ {
+
+ super.setFocus(newFocus, direction);
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/terminal/TerminalType.java b/cli/src/main/java/org/wrml/werminal/terminal/TerminalType.java
new file mode 100644
index 0000000..c9ba2e4
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/terminal/TerminalType.java
@@ -0,0 +1,32 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.terminal;
+
+public enum TerminalType
+{
+
+ Swing,
+ Unix;
+}
diff --git a/cli/src/main/java/org/wrml/werminal/theme/DefaultSplashTheme.java b/cli/src/main/java/org/wrml/werminal/theme/DefaultSplashTheme.java
new file mode 100644
index 0000000..2e1e155
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/theme/DefaultSplashTheme.java
@@ -0,0 +1,128 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.theme;
+
+import com.googlecode.lanterna.gui.Theme;
+import com.googlecode.lanterna.terminal.Terminal;
+import org.wrml.werminal.terminal.TerminalAppTheme;
+import org.wrml.werminal.theme.DefaultSplashTheme.DefaultSplashThemeDefinition;
+
+import java.util.Map;
+
+// TODO: Redesign this class to enable greater reuse
+public class DefaultSplashTheme extends TerminalAppTheme
+{
+
+ public DefaultSplashTheme()
+ {
+
+ super(DefaultSplashThemeDefinition.class);
+
+ final Map definitions = getDefinitions();
+ final Map categorizedDefinitions = getCategorizedDefinitions();
+
+ final DefaultSplashThemeDefinition[] wrmlThemeDefinitions = DefaultSplashThemeDefinition.values();
+
+ for (final DefaultSplashThemeDefinition wrmlThemeDefinition : wrmlThemeDefinitions)
+ {
+
+ final Definition definition = new Theme.Definition(wrmlThemeDefinition.getForegroundColor(),
+ wrmlThemeDefinition.getBackgroundColor(), wrmlThemeDefinition.isHighlighted(),
+ wrmlThemeDefinition.isUnderlined());
+
+ definitions.put(wrmlThemeDefinition, definition);
+ categorizedDefinitions.put(wrmlThemeDefinition.toCategory(), definition);
+ }
+
+ }
+
+ static enum DefaultSplashThemeDefinition
+ {
+
+ BORDER(Terminal.Color.BLACK, Terminal.Color.RED, false, false),
+ BUTTON_ACTIVE(Terminal.Color.BLACK, Terminal.Color.BLACK, false, true),
+ BUTTON_INACTIVE(Terminal.Color.BLACK, Terminal.Color.BLACK, false, true),
+ BUTTON_LABEL_ACTIVE(Terminal.Color.BLACK, Terminal.Color.RED, true, true),
+ BUTTON_LABEL_INACTIVE(Terminal.Color.BLACK, Terminal.Color.RED, false, false),
+ CHECKBOX(Terminal.Color.BLACK, Terminal.Color.RED, false, false),
+ CHECKBOX_SELECTED(Terminal.Color.BLACK, Terminal.Color.RED, true, false),
+ DIALOG_AREA(Terminal.Color.BLACK, Terminal.Color.RED, false, false),
+ LIST_ITEM(Terminal.Color.BLACK, Terminal.Color.RED, false, false),
+ LIST_ITEM_SELECTED(Terminal.Color.BLACK, Terminal.Color.RED, true, false),
+ RAISED_BORDER(Terminal.Color.BLACK, Terminal.Color.RED, false, false),
+ SCREEN_BACKGROUND(Terminal.Color.BLACK, Terminal.Color.BLACK, false, false),
+ SHADOW(Terminal.Color.BLACK, Terminal.Color.BLACK, false, false),
+ TEXTBOX(Terminal.Color.BLACK, Terminal.Color.WHITE, false, false),
+ TEXTBOX_FOCUSED(Terminal.Color.BLACK, Terminal.Color.WHITE, false, false);
+
+ private final Terminal.Color _BackgroundColor;
+
+ private final Terminal.Color _ForegroundColor;
+
+ private final boolean _Highlighted;
+
+ private final boolean _Underlined;
+
+ private DefaultSplashThemeDefinition(final Terminal.Color backgroundColor,
+ final Terminal.Color foregroundColor, final boolean highlighted, final boolean underlined)
+ {
+
+ _BackgroundColor = backgroundColor;
+ _ForegroundColor = foregroundColor;
+ _Highlighted = highlighted;
+ _Underlined = underlined;
+ }
+
+ public Terminal.Color getBackgroundColor()
+ {
+
+ return _BackgroundColor;
+ }
+
+ public Terminal.Color getForegroundColor()
+ {
+
+ return _ForegroundColor;
+ }
+
+ public boolean isHighlighted()
+ {
+
+ return _Highlighted;
+ }
+
+ public boolean isUnderlined()
+ {
+
+ return _Underlined;
+ }
+
+ public Category toCategory()
+ {
+
+ return Category.valueOf(String.valueOf(this));
+ }
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/theme/DefaultWindowTheme.java b/cli/src/main/java/org/wrml/werminal/theme/DefaultWindowTheme.java
new file mode 100644
index 0000000..e3e0e4a
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/theme/DefaultWindowTheme.java
@@ -0,0 +1,127 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.theme;
+
+import com.googlecode.lanterna.gui.Theme;
+import com.googlecode.lanterna.terminal.Terminal;
+import org.wrml.werminal.terminal.TerminalAppTheme;
+import org.wrml.werminal.theme.DefaultWindowTheme.DefaultWindowThemeDefinition;
+
+import java.util.Map;
+
+//TODO: Redesign this class to enable greater reuse
+public class DefaultWindowTheme extends TerminalAppTheme
+{
+
+ public DefaultWindowTheme()
+ {
+
+ super(DefaultWindowThemeDefinition.class);
+
+ final Map definitions = getDefinitions();
+ final Map categorizedDefinitions = getCategorizedDefinitions();
+
+ final DefaultWindowThemeDefinition[] wrmlThemeDefinitions = DefaultWindowThemeDefinition.values();
+
+ for (final DefaultWindowThemeDefinition wrmlThemeDefinition : wrmlThemeDefinitions)
+ {
+
+ final Definition definition = new Theme.Definition(wrmlThemeDefinition.getForegroundColor(),
+ wrmlThemeDefinition.getBackgroundColor(), wrmlThemeDefinition.isHighlighted(),
+ wrmlThemeDefinition.isUnderlined());
+
+ definitions.put(wrmlThemeDefinition, definition);
+ categorizedDefinitions.put(wrmlThemeDefinition.toCategory(), definition);
+ }
+ }
+
+ static enum DefaultWindowThemeDefinition
+ {
+
+ BORDER(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ BUTTON_ACTIVE(Terminal.Color.WHITE, Terminal.Color.RED, false, true),
+ BUTTON_INACTIVE(Terminal.Color.WHITE, Terminal.Color.BLACK, false, true),
+ BUTTON_LABEL_ACTIVE(Terminal.Color.WHITE, Terminal.Color.RED, true, true),
+ BUTTON_LABEL_INACTIVE(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ CHECKBOX(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ CHECKBOX_SELECTED(Terminal.Color.WHITE, Terminal.Color.RED, false, false),
+ DIALOG_AREA(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ LIST_ITEM(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ LIST_ITEM_SELECTED(Terminal.Color.WHITE, Terminal.Color.RED, false, false),
+ RAISED_BORDER(Terminal.Color.WHITE, Terminal.Color.RED, false, false),
+ SCREEN_BACKGROUND(Terminal.Color.BLACK, Terminal.Color.RED, false, false),
+ SHADOW(Terminal.Color.RED, Terminal.Color.RED, false, false),
+ TEXTBOX(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ TEXTBOX_FOCUSED(Terminal.Color.WHITE, Terminal.Color.RED, false, false);
+
+ private final Terminal.Color _BackgroundColor;
+
+ private final Terminal.Color _ForegroundColor;
+
+ private final boolean _Highlighted;
+
+ private final boolean _Underlined;
+
+ private DefaultWindowThemeDefinition(final Terminal.Color backgroundColor,
+ final Terminal.Color foregroundColor, final boolean highlighted, final boolean underlined)
+ {
+
+ _BackgroundColor = backgroundColor;
+ _ForegroundColor = foregroundColor;
+ _Highlighted = highlighted;
+ _Underlined = underlined;
+ }
+
+ public Terminal.Color getBackgroundColor()
+ {
+
+ return _BackgroundColor;
+ }
+
+ public Terminal.Color getForegroundColor()
+ {
+
+ return _ForegroundColor;
+ }
+
+ public boolean isHighlighted()
+ {
+
+ return _Highlighted;
+ }
+
+ public boolean isUnderlined()
+ {
+
+ return _Underlined;
+ }
+
+ public Category toCategory()
+ {
+
+ return Category.valueOf(String.valueOf(this));
+ }
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/theme/LightTheme.java b/cli/src/main/java/org/wrml/werminal/theme/LightTheme.java
new file mode 100644
index 0000000..c6d684a
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/theme/LightTheme.java
@@ -0,0 +1,127 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.theme;
+
+import com.googlecode.lanterna.gui.Theme;
+import com.googlecode.lanterna.terminal.Terminal;
+import org.wrml.werminal.terminal.TerminalAppTheme;
+import org.wrml.werminal.theme.LightTheme.LightThemeDefinition;
+
+import java.util.Map;
+
+//TODO: Redesign this class to enable greater reuse
+public class LightTheme extends TerminalAppTheme
+{
+
+ public LightTheme()
+ {
+
+ super(LightThemeDefinition.class);
+
+ final Map definitions = getDefinitions();
+ final Map categorizedDefinitions = getCategorizedDefinitions();
+
+ final LightThemeDefinition[] wrmlThemeDefinitions = LightThemeDefinition.values();
+
+ for (final LightThemeDefinition wrmlThemeDefinition : wrmlThemeDefinitions)
+ {
+
+ final Definition definition = new Theme.Definition(wrmlThemeDefinition.getForegroundColor(),
+ wrmlThemeDefinition.getBackgroundColor(), wrmlThemeDefinition.isHighlighted(),
+ wrmlThemeDefinition.isUnderlined());
+
+ definitions.put(wrmlThemeDefinition, definition);
+ categorizedDefinitions.put(wrmlThemeDefinition.toCategory(), definition);
+ }
+ }
+
+ static enum LightThemeDefinition
+ {
+
+ BORDER(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ BUTTON_ACTIVE(Terminal.Color.WHITE, Terminal.Color.RED, false, true),
+ BUTTON_INACTIVE(Terminal.Color.WHITE, Terminal.Color.BLACK, false, true),
+ BUTTON_LABEL_ACTIVE(Terminal.Color.WHITE, Terminal.Color.RED, true, true),
+ BUTTON_LABEL_INACTIVE(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ CHECKBOX(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ CHECKBOX_SELECTED(Terminal.Color.WHITE, Terminal.Color.RED, false, false),
+ DIALOG_AREA(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ LIST_ITEM(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ LIST_ITEM_SELECTED(Terminal.Color.WHITE, Terminal.Color.RED, false, false),
+ RAISED_BORDER(Terminal.Color.WHITE, Terminal.Color.RED, false, false),
+ SCREEN_BACKGROUND(Terminal.Color.WHITE, Terminal.Color.RED, false, false),
+ SHADOW(Terminal.Color.RED, Terminal.Color.RED, false, false),
+ TEXTBOX(Terminal.Color.WHITE, Terminal.Color.BLACK, false, false),
+ TEXTBOX_FOCUSED(Terminal.Color.WHITE, Terminal.Color.RED, false, false);
+
+ private final Terminal.Color _BackgroundColor;
+
+ private final Terminal.Color _ForegroundColor;
+
+ private final boolean _Highlighted;
+
+ private final boolean _Underlined;
+
+ private LightThemeDefinition(final Terminal.Color backgroundColor, final Terminal.Color foregroundColor,
+ final boolean highlighted, final boolean underlined)
+ {
+
+ _BackgroundColor = backgroundColor;
+ _ForegroundColor = foregroundColor;
+ _Highlighted = highlighted;
+ _Underlined = underlined;
+ }
+
+ public Terminal.Color getBackgroundColor()
+ {
+
+ return _BackgroundColor;
+ }
+
+ public Terminal.Color getForegroundColor()
+ {
+
+ return _ForegroundColor;
+ }
+
+ public boolean isHighlighted()
+ {
+
+ return _Highlighted;
+ }
+
+ public boolean isUnderlined()
+ {
+
+ return _Underlined;
+ }
+
+ public Category toCategory()
+ {
+
+ return Category.valueOf(String.valueOf(this));
+ }
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/util/ClipboardUtils.java b/cli/src/main/java/org/wrml/werminal/util/ClipboardUtils.java
new file mode 100644
index 0000000..8f3f261
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/util/ClipboardUtils.java
@@ -0,0 +1,72 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.util;
+
+import java.awt.*;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+
+public class ClipboardUtils
+{
+
+ public static String getClipboardText()
+ {
+
+ String text = null;
+ final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+
+ final Transferable contents = clipboard.getContents(null);
+ final boolean hasTransferableText = (contents != null)
+ && contents.isDataFlavorSupported(DataFlavor.stringFlavor);
+ if (hasTransferableText)
+ {
+ try
+ {
+ text = (String) contents.getTransferData(DataFlavor.stringFlavor);
+ }
+ catch (final Exception e)
+ {
+ }
+ }
+
+ return text;
+ }
+
+ public static void setClipboardText(final String text)
+ {
+
+ final StringSelection stringSelection = new StringSelection(text);
+ try
+ {
+ final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ clipboard.setContents(stringSelection, null);
+ }
+ catch (final Exception e)
+ {
+ }
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/util/History.java b/cli/src/main/java/org/wrml/werminal/util/History.java
new file mode 100644
index 0000000..c861b22
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/util/History.java
@@ -0,0 +1,146 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright 2012 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.util;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class History
+{
+
+ private final HistoryMap _Map;
+
+ public History()
+ {
+
+ _Map = new HistoryMap<>();
+ }
+
+ public History(final Collection initialState)
+ {
+
+ _Map = new HistoryMap(initialState);
+ }
+
+ public History(final int initialCapcity)
+ {
+
+ _Map = new HistoryMap(initialCapcity);
+ }
+
+ public void add(final E element)
+ {
+
+ if (_Map.containsKey(element))
+ {
+ _Map.get(element);
+ }
+ else
+ {
+ _Map.put(element, element);
+ }
+ }
+
+ public void addAll(final Collection elements)
+ {
+
+ _Map.addAll(elements);
+ }
+
+ public void clear()
+ {
+
+ _Map.clear();
+ }
+
+ public Set getElementSet()
+ {
+
+ return _Map.keySet();
+ }
+
+ public void remove(final E element)
+ {
+
+ _Map.remove(element);
+ }
+
+ private class HistoryMap extends LinkedHashMap
+ {
+
+ private static final int DEFAULT_EXTRA_INITIAL_CAPACITY = 64;
+
+ private static final float DEFAULT_LOAD_FACTOR = 0.75f;
+
+ private static final int DEFAULT_MAX_ENTRIES = 250;
+
+ private static final long serialVersionUID = 1L;
+
+ public HistoryMap()
+ {
+
+ this(DEFAULT_EXTRA_INITIAL_CAPACITY);
+ }
+
+ public HistoryMap(final Collection initialElements)
+ {
+
+ this(initialElements.size() + DEFAULT_EXTRA_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
+ addAll(initialElements);
+ }
+
+ public HistoryMap(final int initialCapacity)
+ {
+
+ this(initialCapacity, DEFAULT_LOAD_FACTOR);
+ }
+
+ public HistoryMap(final int initialCapacity, final float loadFactor)
+ {
+
+ super(initialCapacity, loadFactor, true);
+ }
+
+ public void addAll(final Collection elements)
+ {
+
+ for (final T element : elements)
+ {
+ put(element, element);
+ }
+
+ }
+
+ @Override
+ protected boolean removeEldestEntry(@SuppressWarnings("rawtypes") final Map.Entry eldest)
+ {
+
+ return size() > DEFAULT_MAX_ENTRIES;
+ }
+
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/window/FormPanelWindow.java b/cli/src/main/java/org/wrml/werminal/window/FormPanelWindow.java
new file mode 100644
index 0000000..7256e71
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/window/FormPanelWindow.java
@@ -0,0 +1,185 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.window;
+
+import com.googlecode.lanterna.gui.Component;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.FormFieldOpenAction;
+import org.wrml.werminal.component.FormField;
+import org.wrml.werminal.component.FormPanel;
+import org.wrml.werminal.component.WerminalPanel;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class FormPanelWindow extends WerminalPanelWindow
+{
+
+ public final static int FIELDS_PER_PANEL = 10;
+
+ public final static int HEADER_FIELD_NAME_LABEL_WIDTH = 12;
+
+ public final static int HEADER_FIELD_VALUE_LABEL_WIDTH = 100;
+
+ public FormPanelWindow(final Werminal werminal, final String title, final Component[] toolBarComponents)
+ {
+
+ super(werminal, title, toolBarComponents);
+ }
+
+ public void addFormField(final String panelTitle, final Type fieldType, final Object value)
+ {
+
+ goToLastPanel();
+
+ FormPanel form = (FormPanel) getCurrentPanel();
+ final FormField formField;
+ if (form == null)
+ {
+ final Map fieldMap = new LinkedHashMap<>();
+ final String fieldZeroSlotName = "0";
+ fieldMap.put(fieldZeroSlotName, fieldType);
+ initPanels(panelTitle, fieldMap);
+ formField = getFormField(fieldZeroSlotName);
+ }
+ else
+ {
+ final FormFieldOpenAction formFieldOpenAction = new FormFieldOpenAction(getWerminal());
+ formField = new FormField(String.valueOf((FormPanelWindow.FIELDS_PER_PANEL * form.getPanelIndex())
+ + form.getFieldCount()), fieldType, formFieldOpenAction);
+ formFieldOpenAction.setFormField(formField);
+
+ if (form.getFieldCount() == FormPanelWindow.FIELDS_PER_PANEL)
+ {
+ final Map formFields = new LinkedHashMap<>();
+ formFields.put(formField.getFieldName(), formField);
+ form = addFormPanel(panelTitle, formFields);
+ setCurrentPanel(form);
+ }
+
+ form.addFormField(formField);
+ }
+
+ formField.getFieldValueTextBox().setValue(value);
+ }
+
+ public FormPanel addFormPanel(final String panelTitle, final Map formFields)
+ {
+
+ final List panels = getPanels();
+ final int oldPanelCount = panels.size();
+ final int newPanelCount = panels.size() + 1;
+
+ for (final WerminalPanel panel : panels)
+ {
+ panel.setPanelCount(newPanelCount);
+ }
+
+ final FormPanel formPanel = createFormPanel(panelTitle, formFields, oldPanelCount, newPanelCount, FormPanelWindow.FIELDS_PER_PANEL);
+ panels.add(formPanel);
+ return formPanel;
+ }
+
+ public final FormField getFormField(final String fieldName)
+ {
+
+ for (final WerminalPanel panel : getPanels())
+ {
+
+ if (panel instanceof FormPanel)
+ {
+ final FormPanel formPanel = (FormPanel) panel;
+ final FormField field = formPanel.getFormField(fieldName);
+ if (field != null)
+ {
+ return field;
+ }
+ }
+
+ }
+
+ return null;
+ }
+
+ public final void initPanels(final String panelTitle, final Map fieldMap)
+ {
+
+ final List panels = getPanels();
+ panels.clear();
+
+ final List allFieldNames = new ArrayList<>(fieldMap.keySet());
+
+ final int totalFieldCount = allFieldNames.size();
+ final int fullFieldPanelCount = totalFieldCount / FormPanelWindow.FIELDS_PER_PANEL;
+ final int leftoverFieldCount = totalFieldCount % FormPanelWindow.FIELDS_PER_PANEL;
+ final boolean needOddLastPanel = (leftoverFieldCount != 0);
+ final int panelCount = (fullFieldPanelCount) + (needOddLastPanel ? 1 : 0);
+
+ final int lastPanelFieldCount = (panelCount == 1) ? totalFieldCount
+ : (leftoverFieldCount == 0) ? FormPanelWindow.FIELDS_PER_PANEL : leftoverFieldCount;
+
+ for (int panelIndex = 0; panelIndex < panelCount; panelIndex++)
+ {
+
+ final boolean isLastPanel = (panelIndex == (panelCount - 1));
+
+ final int panelFieldStartIndex = panelIndex * FormPanelWindow.FIELDS_PER_PANEL;
+ final int panelFieldCount = (isLastPanel) ? lastPanelFieldCount : FormPanelWindow.FIELDS_PER_PANEL;
+ final int panelFieldEndIndex = panelFieldStartIndex + panelFieldCount;
+ final Map formFields = new LinkedHashMap<>();
+ for (int fieldIndex = panelFieldStartIndex; fieldIndex < panelFieldEndIndex; fieldIndex++)
+ {
+ final String fieldName = allFieldNames.get(fieldIndex);
+ final Type fieldType = fieldMap.get(fieldName);
+ final FormFieldOpenAction formFieldOpenAction = new FormFieldOpenAction(getWerminal());
+ final FormField formField = new FormField(fieldName, fieldType, formFieldOpenAction);
+ formFieldOpenAction.setFormField(formField);
+ formFields.put(fieldName, formField);
+ }
+
+ final FormPanel formPanel = createFormPanel(panelTitle, formFields, panelIndex, panelCount, FormPanelWindow.FIELDS_PER_PANEL);
+ panels.add(formPanel);
+ }
+
+ if (panels.size() > 0)
+ {
+ setCurrentPanel(panels.get(0));
+ }
+ }
+
+ protected FormPanel createFormPanel(final String panelTitle, final Map formFields,
+ final int panelIndex, final int panelCount, final int fieldsPerPanel)
+ {
+
+ final FormPanel formPanel = new FormPanel(getWerminal(), panelTitle, formFields, getNextAction(), getPreviousAction(), fieldsPerPanel);
+ formPanel.setPanelIndex(panelIndex);
+ formPanel.setPanelCount(panelCount);
+ return formPanel;
+
+ }
+}
diff --git a/cli/src/main/java/org/wrml/werminal/window/ModelWindow.java b/cli/src/main/java/org/wrml/werminal/window/ModelWindow.java
new file mode 100644
index 0000000..1d6ac01
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/window/ModelWindow.java
@@ -0,0 +1,297 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.window;
+
+import com.googlecode.lanterna.gui.Component;
+import com.googlecode.lanterna.terminal.Terminal;
+import org.wrml.model.Model;
+import org.wrml.model.Titled;
+import org.wrml.model.rest.Api;
+import org.wrml.model.rest.Document;
+import org.wrml.model.schema.Schema;
+import org.wrml.runtime.rest.ApiLoader;
+import org.wrml.runtime.schema.Prototype;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.LoadAction;
+import org.wrml.werminal.component.FormField;
+import org.wrml.werminal.component.FormPanel;
+import org.wrml.werminal.component.WerminalPanel;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppNameValueLabel;
+import org.wrml.werminal.terminal.TerminalAppToolBar;
+
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.*;
+
+/**
+ *
+ * {@link org.wrml.werminal.Werminal}'s primary {@link Model} view/edit {@link WerminalWindow}.
+ *
+ */
+public class ModelWindow extends FormPanelWindow
+{
+
+ private final TerminalAppNameValueLabel _HeapIdLabel;
+
+ private final TerminalAppNameValueLabel _SchemaUriLabel;
+
+ private final TerminalAppNameValueLabel _OriginServiceLabel;
+
+ private final TerminalAppButtonPanel _LoadButton;
+
+ private Model _Model;
+
+ public ModelWindow(final Werminal werminal, final String title, final Component[] toolBarComponents)
+ {
+
+ super(werminal, title, toolBarComponents);
+
+ _SchemaUriLabel = new TerminalAppNameValueLabel(werminal, "Schema: ",
+ FormPanelWindow.HEADER_FIELD_NAME_LABEL_WIDTH, Terminal.Color.BLACK, true, "",
+ FormPanelWindow.HEADER_FIELD_VALUE_LABEL_WIDTH, Terminal.Color.BLACK, false);
+
+ _HeapIdLabel = new TerminalAppNameValueLabel(werminal, "Heap ID: ",
+ FormPanelWindow.HEADER_FIELD_NAME_LABEL_WIDTH, Terminal.Color.BLACK, true, "",
+ FormPanelWindow.HEADER_FIELD_VALUE_LABEL_WIDTH, Terminal.Color.BLACK, false);
+
+ _OriginServiceLabel = new TerminalAppNameValueLabel(werminal, "Origin: ",
+ FormPanelWindow.HEADER_FIELD_NAME_LABEL_WIDTH, Terminal.Color.BLACK, true, "",
+ FormPanelWindow.HEADER_FIELD_VALUE_LABEL_WIDTH, Terminal.Color.BLACK, false);
+
+ _LoadButton = new TerminalAppButtonPanel(werminal.getLoadAction());
+
+ render();
+ }
+
+ public final static String getModelWindowTitle(final Model model)
+ {
+
+ final StringBuilder modelWindowTitleBuilder = new StringBuilder("Model - ").append(model.getPrototype()
+ .getTitle());
+ if (model instanceof Titled)
+ {
+ final String modelTitle = ((Titled) model).getTitle();
+ if (modelTitle != null)
+ {
+ final String trimmedTitle = modelTitle.trim();
+ if (!trimmedTitle.isEmpty())
+ {
+ modelWindowTitleBuilder.append(" - ").append(trimmedTitle);
+ }
+ }
+
+ }
+
+ return modelWindowTitleBuilder.toString();
+
+ }
+
+ public final Model getModel()
+ {
+
+ return _Model;
+ }
+
+ public final void setModel(final Model model)
+ {
+
+ _Model = model;
+
+ final Werminal werminal = getWerminal();
+
+ final URI schemaUri = _Model.getSchemaUri();
+ _SchemaUriLabel.getValueLabel().setText(schemaUri.toString());
+
+ final UUID heapId = _Model.getHeapId();
+ _HeapIdLabel.getValueLabel().setText(String.valueOf(heapId));
+
+
+ final Prototype prototype = _Model.getPrototype();
+
+ werminal.addToSchemaUriHistory(schemaUri);
+
+ if (_Model instanceof Schema)
+ {
+ werminal.addToSchemaUriHistory(((Schema) _Model).getUri());
+ }
+
+ final Map fieldMap = new LinkedHashMap<>();
+
+ final Set keySlotNameSet = prototype.getAllKeySlotNames();
+ final List allKeySlotNames = new ArrayList(keySlotNameSet);
+ for (final String keySlotName : allKeySlotNames)
+ {
+ fieldMap.put(keySlotName, prototype.getProtoSlot(keySlotName).getHeapValueType());
+ }
+
+ final List allSlotNames = new ArrayList(prototype.getAllSlotNames());
+
+ for (final String slotName : allSlotNames)
+ {
+ if (!keySlotNameSet.contains(slotName))
+ {
+ fieldMap.put(slotName, prototype.getProtoSlot(slotName).getHeapValueType());
+ }
+ }
+
+ initPanels("Slots", fieldMap);
+
+ for (final String slotName : allSlotNames)
+ {
+
+ // Note: the _Model field reference is used because of the getModel side-effect (funny smell)
+ final Object value = _Model.getSlotValue(slotName);
+ final FormField formField = getFormField(slotName);
+ if (formField == null)
+ {
+ werminal.showError("The slot named \"" + slotName + "\" has no associated form field.");
+ break;
+ }
+ final WerminalTextBox valueTextBox = formField.getFieldValueTextBox();
+ valueTextBox.setValue(value);
+
+ }
+
+ if (_Model instanceof Schema)
+ {
+ final Schema schema = (Schema) _Model;
+ final URI uri = schema.getUri();
+ if (uri == null)
+ {
+
+ final URI newSchemaUri = werminal.createSchemaUri("MyNewSchema");
+
+ final FormField documentKeyFormField = getFormField(Document.SLOT_NAME_URI);
+ documentKeyFormField.getFieldValueTextBox().setText(newSchemaUri.toString());
+ }
+ }
+
+ updateLoadButton();
+
+ }
+
+ public final Model syncModel()
+ {
+
+ final Model model = getModel();
+ final List panels = getPanels();
+ for (final WerminalPanel panel : panels)
+ {
+
+ if (panel instanceof FormPanel)
+ {
+ final FormPanel formPanel = (FormPanel) panel;
+ for (final String slotName : formPanel.getFieldNames())
+ {
+
+ final FormField field = formPanel.getFormField(slotName);
+ final WerminalTextBox valueTextBox = field.getFieldValueTextBox();
+ if (valueTextBox.isValueChanged())
+ {
+
+ final Object slotValue = valueTextBox.getValue();
+ model.setSlotValue(slotName, slotValue);
+
+ }
+ }
+ }
+ }
+ return model;
+ }
+
+ @Override
+ public void render()
+ {
+
+ removeAllComponents();
+ renderHeaderToolBar();
+ renderDimensionsPanel();
+ renderCurrentPanel();
+ }
+
+ public void updateLoadButton()
+ {
+
+ final TerminalAppToolBar headerToolBar = getHeaderToolBar();
+ if (headerToolBar == null)
+ {
+ return;
+ }
+
+ final Model model = getModel();
+ final boolean isLoadButtonAlreadyVisible = headerToolBar.containsComponent(_LoadButton);
+ final boolean shouldLoadButtonBeVisible = LoadAction.appliesTo(model);
+
+ String loadButtonTitleText = "Load";
+ if (model instanceof Api)
+ {
+ if (shouldLoadButtonBeVisible)
+ {
+ final ApiLoader apiLoader = model.getContext().getApiLoader();
+ if (apiLoader.getLoadedApi(model.getKeys()) != null)
+ {
+ loadButtonTitleText = "Reload";
+ }
+ }
+ }
+
+ _LoadButton.getButton().setText(loadButtonTitleText);
+
+ if (isLoadButtonAlreadyVisible != shouldLoadButtonBeVisible)
+ {
+ if (shouldLoadButtonBeVisible)
+ {
+ headerToolBar.addComponent(_LoadButton);
+ }
+ else
+ {
+ headerToolBar.removeComponent(_LoadButton);
+ }
+ }
+ }
+
+ private void renderDimensionsPanel()
+ {
+
+
+ if (_Model != null)
+ {
+ final String originServiceName = _Model.getOriginServiceName();
+ final String labelText = (originServiceName != null) ? originServiceName : "";
+ _OriginServiceLabel.getValueLabel().setText(labelText);
+ }
+
+
+ addEmptySpace();
+ addComponent(_SchemaUriLabel);
+ addComponent(_HeapIdLabel);
+ addComponent(_OriginServiceLabel);
+ addEmptySpace();
+
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/window/SplashWindow.java b/cli/src/main/java/org/wrml/werminal/window/SplashWindow.java
new file mode 100644
index 0000000..fa187dd
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/window/SplashWindow.java
@@ -0,0 +1,160 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.window;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.component.EmptySpace;
+import com.googlecode.lanterna.gui.component.TextArea;
+import com.googlecode.lanterna.input.Key;
+import com.googlecode.lanterna.terminal.TerminalSize;
+import org.wrml.util.AsciiArt;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.terminal.TerminalAppMenu;
+import org.wrml.werminal.terminal.TerminalAppMenuWindow;
+import org.wrml.werminal.terminal.TerminalAppPanel;
+import org.wrml.werminal.terminal.TerminalAppTextArea;
+
+import java.util.Calendar;
+
+public class SplashWindow extends TerminalAppMenuWindow
+{
+
+ public final static String WERMINAL_SPLASH_SCREEN;
+
+ static
+ {
+
+ final int currentYear = Calendar.getInstance().get(Calendar.YEAR);
+ final String attribution = "Mark Masse (WRML.org)";
+
+ final StringBuilder splash = new StringBuilder();
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append(" Web Resource Modeling Language");
+ splash.append('\n');
+ splash.append(AsciiArt.LOGO);
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append(" Welcome to Werminal");
+ splash.append('\n');
+ splash.append('\n');
+ splash.append(" A keyboard-only terminal/console app");
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append(" < Please press any key to start modeling >");
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append('\n');
+ splash.append(" Copyright (C) " + currentYear + " " + attribution);
+ splash.append('\n');
+
+ WERMINAL_SPLASH_SCREEN = splash.toString();
+
+ }
+
+ private final static TerminalSize PREFERRED_MENU_SIZE = new TerminalSize(78, 40);
+
+ private final static TerminalSize PREFERRED_TEXT_SIZE = new TerminalSize(70, 38);
+
+ public SplashWindow(final Werminal werminal)
+ {
+
+ super(werminal, "", new SplashPanel(werminal), null);
+
+ setBorder(new Border.Invisible());
+ setSoloWindow(true);
+ }
+
+ public static class SplashPanel extends TerminalAppPanel
+ {
+
+ public SplashPanel(final Werminal werminal)
+ {
+
+ super(werminal, "", new Border.Invisible(), Orientation.HORISONTAL, true, false);
+
+ addComponent(new EmptySpace(2, 0));
+
+ final TerminalAppMenu textMenu = new TerminalAppMenu(werminal);
+ textMenu.setPreferredSize(SplashWindow.PREFERRED_MENU_SIZE);
+ addComponent(textMenu);
+
+ final TextArea textArea = new AsciiTextArea(werminal, SplashWindow.PREFERRED_TEXT_SIZE,
+ WERMINAL_SPLASH_SCREEN);
+ textMenu.addComponent(textArea);
+
+ addComponent(new EmptySpace(2, 0));
+ }
+
+ @Override
+ public boolean isScrollable()
+ {
+
+ return false;
+ }
+ }
+
+ private static class AsciiTextArea extends TerminalAppTextArea
+ {
+
+ public AsciiTextArea(final Werminal werminal, final TerminalSize preferredSize, final String text)
+ {
+
+ super(werminal, preferredSize, text);
+ }
+
+ @Override
+ public boolean isScrollable()
+ {
+
+ return false;
+ }
+
+ @Override
+ public Result keyboardInteraction(final Key key)
+ {
+
+ getApp().closeTopWindow();
+ return Result.EVENT_HANDLED;
+ }
+
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/window/WerminalPanelWindow.java b/cli/src/main/java/org/wrml/werminal/window/WerminalPanelWindow.java
new file mode 100644
index 0000000..11e602f
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/window/WerminalPanelWindow.java
@@ -0,0 +1,215 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.window;
+
+import com.googlecode.lanterna.gui.Component;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.component.WerminalPanel;
+import org.wrml.werminal.terminal.TerminalAppButtonPanel;
+import org.wrml.werminal.terminal.TerminalAppToolBar;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class WerminalPanelWindow extends WerminalWindow
+{
+
+ private final static int PREVIOUS_BUTTON_INDEX = 0;
+
+ private final static int NEXT_BUTTON_INDEX = 2;
+
+ private WerminalPanel _CurrentPanel;
+
+ private final List _Panels;
+
+ private final WerminalAction _NextAction;
+
+ private final WerminalAction _PreviousAction;
+
+ public WerminalPanelWindow(final Werminal werminal, final String title, final Component[] toolBarComponents)
+ {
+
+ super(werminal, title, toolBarComponents);
+
+ _Panels = new ArrayList();
+
+ _NextAction = new NextAction(werminal);
+ _PreviousAction = new PreviousAction(werminal);
+ }
+
+ public final WerminalPanel getCurrentPanel()
+ {
+
+ return _CurrentPanel;
+ }
+
+ public final WerminalAction getNextAction()
+ {
+
+ return _NextAction;
+ }
+
+ public final int getPanelCount()
+ {
+
+ return _Panels.size();
+ }
+
+ @SuppressWarnings("unchecked")
+ public final List getPanels()
+ {
+
+ return (List) _Panels;
+ }
+
+ public final WerminalAction getPreviousAction()
+ {
+
+ return _PreviousAction;
+ }
+
+ public final void goToFirstPanel()
+ {
+
+ if (_Panels.isEmpty())
+ {
+ return;
+ }
+ setCurrentPanel(_Panels.get(0));
+ }
+
+ public final void goToLastPanel()
+ {
+
+ if (_Panels.isEmpty())
+ {
+ return;
+ }
+ setCurrentPanel(_Panels.get(_Panels.size() - 1));
+ }
+
+ public final void goToNextPanel()
+ {
+
+ if (_Panels.isEmpty())
+ {
+ return;
+ }
+ directPanel(false);
+ }
+
+ public final void goToPreviousPanel()
+ {
+
+ if (_Panels.isEmpty())
+ {
+ return;
+ }
+ directPanel(true);
+ }
+
+ public final void setCurrentPanel(final WerminalPanel currentPanel)
+ {
+
+ _CurrentPanel = currentPanel;
+ render();
+ }
+
+ protected final void directPanel(final boolean reverse)
+ {
+
+ final int panelIndexIncrement = (reverse) ? -1 : 1;
+
+ setCurrentPanel(_Panels.get(getCurrentPanel().getPanelIndex() + panelIndexIncrement));
+
+ final TerminalAppToolBar toolBar = getCurrentPanel().getToolBar();
+ if (toolBar != null)
+ {
+ final int toolBarComponentCount = toolBar.getComponents().length;
+ int toolBarButtonIndex = (reverse) ? WerminalPanelWindow.PREVIOUS_BUTTON_INDEX
+ : WerminalPanelWindow.NEXT_BUTTON_INDEX;
+ toolBarButtonIndex = (toolBarButtonIndex < toolBarComponentCount) ? toolBarButtonIndex : 0;
+ final Component focusComponent = toolBar.getComponents()[toolBarButtonIndex];
+ if (focusComponent instanceof TerminalAppButtonPanel)
+ {
+ setFocus(((TerminalAppButtonPanel) focusComponent).getButton());
+ }
+ }
+ }
+
+ @Override
+ public void render()
+ {
+
+ super.render();
+ renderCurrentPanel();
+ }
+
+ protected void renderCurrentPanel()
+ {
+
+ if (_CurrentPanel != null)
+ {
+ addComponent(_CurrentPanel);
+ }
+ }
+
+ private class NextAction extends WerminalAction
+ {
+
+ protected NextAction(final Werminal werminal)
+ {
+
+ super(werminal, "Next");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ goToNextPanel();
+ }
+
+ }
+
+ private class PreviousAction extends WerminalAction
+ {
+
+ protected PreviousAction(final Werminal werminal)
+ {
+
+ super(werminal, "Previous");
+ }
+
+ @Override
+ public void doAction()
+ {
+
+ goToPreviousPanel();
+ }
+ }
+
+}
diff --git a/cli/src/main/java/org/wrml/werminal/window/WerminalWindow.java b/cli/src/main/java/org/wrml/werminal/window/WerminalWindow.java
new file mode 100644
index 0000000..f4b162d
--- /dev/null
+++ b/cli/src/main/java/org/wrml/werminal/window/WerminalWindow.java
@@ -0,0 +1,109 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.werminal.window;
+
+import com.googlecode.lanterna.gui.Border;
+import com.googlecode.lanterna.gui.Component;
+import com.googlecode.lanterna.gui.component.EmptySpace;
+import com.googlecode.lanterna.gui.component.Separator;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.terminal.TerminalAppToolBar;
+import org.wrml.werminal.terminal.TerminalAppWindow;
+
+public class WerminalWindow extends TerminalAppWindow
+{
+
+ private TerminalAppToolBar _HeaderToolBar;
+
+ public WerminalWindow(final Werminal werminal, final String title)
+ {
+
+ this(werminal, title, null);
+ }
+
+ public WerminalWindow(final Werminal werminal, final String title, final Component[] toolBarComponents)
+ {
+
+ super(werminal, getTitle(werminal, title));
+
+ setBorder(new Border.Standard());
+
+ if (toolBarComponents != null)
+ {
+ _HeaderToolBar = new TerminalAppToolBar(werminal, toolBarComponents);
+ }
+
+ render();
+ }
+
+ private static String getTitle(final Werminal werminal, final String title)
+ {
+
+ // NOTE: This check is needed to support mocking tests
+ if (werminal == null)
+ {
+ return title;
+ }
+
+ String werminalTitle = werminal.getAppTitle();
+ return String.format(" %s - %s ", werminalTitle, title);
+ }
+
+ public void addEmptySpace()
+ {
+
+ addComponent(new EmptySpace(0, 1));
+ }
+
+ public TerminalAppToolBar getHeaderToolBar()
+ {
+
+ return _HeaderToolBar;
+ }
+
+ public Werminal getWerminal()
+ {
+
+ return getApp();
+ }
+
+ public void render()
+ {
+
+ removeAllComponents();
+ renderHeaderToolBar();
+ }
+
+ protected void renderHeaderToolBar()
+ {
+
+ if (_HeaderToolBar != null)
+ {
+ addComponent(_HeaderToolBar);
+ addComponent(new Separator());
+ }
+ }
+
+}
diff --git a/cli/src/main/resources/headers/JavaFileHeader-latest.txt b/cli/src/main/resources/headers/JavaFileHeader-latest.txt
new file mode 100644
index 0000000..2212b4b
--- /dev/null
+++ b/cli/src/main/resources/headers/JavaFileHeader-latest.txt
@@ -0,0 +1,22 @@
+WRML - Web Resource Modeling Language
+ __ __ ______ __ __ __
+/\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+\ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+
+http://www.wrml.org
+
+Copyright (C) ${year} Mark Masse (OSS project WRML.org)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/cli/src/main/resources/headers/JavaFileHeader-version-00.txt b/cli/src/main/resources/headers/JavaFileHeader-version-00.txt
new file mode 100644
index 0000000..f792205
--- /dev/null
+++ b/cli/src/main/resources/headers/JavaFileHeader-version-00.txt
@@ -0,0 +1,22 @@
+WRML - Web Resource Modeling Language
+ __ __ ______ __ __ __
+/\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+\ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+
+http://www.wrml.org
+
+Copyright 2012 Mark Masse (OSS project WRML.org)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/cli/src/main/resources/headers/JavaFileHeader-version-01.txt b/cli/src/main/resources/headers/JavaFileHeader-version-01.txt
new file mode 100644
index 0000000..2212b4b
--- /dev/null
+++ b/cli/src/main/resources/headers/JavaFileHeader-version-01.txt
@@ -0,0 +1,22 @@
+WRML - Web Resource Modeling Language
+ __ __ ______ __ __ __
+/\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+\ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+
+http://www.wrml.org
+
+Copyright (C) ${year} Mark Masse (OSS project WRML.org)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/cli/src/main/resources/headers/JavaFileHeader-version-02.txt b/cli/src/main/resources/headers/JavaFileHeader-version-02.txt
new file mode 100644
index 0000000..2552fba
--- /dev/null
+++ b/cli/src/main/resources/headers/JavaFileHeader-version-02.txt
@@ -0,0 +1,22 @@
+WRML - Web Resource Modeling Language
+ __ __ ______ __ __ __
+/\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+\ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+
+http://www.wrml.org
+
+Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/cli/src/main/resources/logback.xml b/cli/src/main/resources/logback.xml
new file mode 100644
index 0000000..bd7f767
--- /dev/null
+++ b/cli/src/main/resources/logback.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${logging.dir}/wrml.log
+
+ ${logging.dir}/wrml.%d{yyyy-MM-dd}.log
+ 7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cli/src/test/java/org/wrml/werminal/dialog/OpenModelDialogTest.java b/cli/src/test/java/org/wrml/werminal/dialog/OpenModelDialogTest.java
new file mode 100644
index 0000000..2a4f16c
--- /dev/null
+++ b/cli/src/test/java/org/wrml/werminal/dialog/OpenModelDialogTest.java
@@ -0,0 +1,189 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wrml.werminal.dialog;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.internal.util.MockUtil;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.wrml.model.schema.Schema;
+import org.wrml.runtime.rest.ApiLoader;
+import org.wrml.runtime.schema.Prototype;
+import org.wrml.runtime.schema.SchemaLoader;
+import org.wrml.util.JavaBean;
+import org.wrml.werminal.Werminal;
+import org.wrml.werminal.action.WerminalAction;
+import org.wrml.werminal.component.WerminalTextBox;
+import org.wrml.werminal.terminal.TerminalAppPanel;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Test for {@link OpenModelDialog}.
+ *
+ * Only select high-value JUnit tests were added for coverage. The highest-profiled hotspot is
+ * {@link OpenModelDialog#updateKeysPanel}.
+ *
+ * Some dependencies could not be (Power)Mocked due to java/inheritance limitations, complexities.
+ *
+ * @author JJ Zabkar
+ */
+@RunWith(MockitoJUnitRunner.class)
+// @RunWith(PowerMockRunner.class)
+// @PrepareForTest({ WerminalWindow.class }) // no worky (stackmap err)
+// @PrepareForTest({ TerminalApp.class }) // no worky (stackmap err)
+// @PrepareForTest({ JavaBean.class })
+@Ignore
+public class OpenModelDialogTest
+{
+
+ private final URI mockSchemaUri = URI.create("mockSchemaUri");
+
+ private final Object mockSchemaUriOld = URI.create("mockSchemaUriOld");
+
+ /**
+ * class under test
+ */
+ OpenModelDialog _OpenModelDialog;
+
+ @Mock
+ private WerminalAction mockConfirmAction;
+
+ @Mock
+ private TerminalAppPanel mockKeysPanel;
+
+ @Mock
+ private Set mockKeySlotNames;
+
+ @Mock
+ private Map mockKeyInputs;
+
+ @Mock
+ private WerminalTextBox mockWerminalTextBox;
+
+ @Mock
+ private SchemaLoader mockSchemaLoader;
+
+ // @Mock
+ private Prototype mockPrototype;
+
+ @Before
+ public void setUp() throws Exception
+ {
+
+ MockUtil mockUtil = new MockUtil();
+
+ _OpenModelDialog = new OpenModelDialog();
+ _OpenModelDialog._SchemaUriTextBox = mockWerminalTextBox;
+ _OpenModelDialog._KeysPanel = mockKeysPanel;
+ _OpenModelDialog._ConfirmAction = mockConfirmAction;
+ _OpenModelDialog._KeySlotNames = mockKeySlotNames;
+ _OpenModelDialog._KeyInputs = mockKeyInputs;
+ _OpenModelDialog._SchemaUri = mockSchemaUri;
+
+ //_OpenModelDialog._SchemaLoader = mock(SchemaLoader.class, Mockito.RETURNS_DEEP_STUBS);
+ //_OpenModelDialog._ApiLoader = mock(ApiLoader.class);
+ mockPrototype = mock(Prototype.class, Mockito.RETURNS_DEEP_STUBS);
+
+ assertNotNull(mockWerminalTextBox);
+ assertTrue(mockUtil.isMock(mockWerminalTextBox));
+
+ when(mockWerminalTextBox.setValue(any(Object.class))).thenReturn(mockSchemaUriOld);
+ when(mockSchemaLoader.getPrototype(any(URI.class))).thenReturn(mockPrototype);
+
+ }
+
+ /**
+ * fails on NPE due to unmockable inherited context
+ */
+ @Test(expected = NullPointerException.class)
+ public void testConstructor4ArgNull()
+ {
+
+ _OpenModelDialog = new OpenModelDialog(null, null, null, null);
+ fail("expected NPE");
+ }
+
+ @Test
+ @Ignore
+ public void testConstructor() throws Exception
+ {
+
+ Werminal mockWerminal = mock(Werminal.class, Mockito.RETURNS_DEEP_STUBS);
+ // deep stub: http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#RETURNS_DEEP_STUBS
+ when(mockWerminal.getContext().getSchemaLoader().getApiSchemaUri()).thenReturn(mockSchemaUri);
+ _OpenModelDialog = new OpenModelDialog(mockWerminal, null, null, null);
+ }
+
+ @Test
+ public void testDefaultConstructor()
+ {
+
+ assertNotNull(_OpenModelDialog);
+ }
+
+ @Test
+ public void testSetKeys()
+ {
+
+ _OpenModelDialog.setKeys(null);
+ }
+
+ @Test
+ public void testSetSchemaUriNull()
+ {
+
+ _OpenModelDialog.setSchemaUri(null);
+ }
+
+ /**
+ * Fails on NPE related to {@link JavaBean}. Worth troubleshooting deep mocking?
+ */
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ @Test
+ @Ignore
+ public void testSetSchemaUri() throws ClassNotFoundException
+ {
+
+ JavaBean mockJavaBean = mock(JavaBean.class);
+ Class mockSchemaInterface = Schema.class;
+ when(mockSchemaLoader.getSchemaInterface(mockSchemaUri)).thenReturn(mockSchemaInterface);
+ when(mockPrototype.getSchemaBean()).thenReturn(mockJavaBean);
+
+ _OpenModelDialog.setSchemaUri(mockSchemaUri);
+ }
+}
diff --git a/cli/src/test/java/org/wrml/werminal/terminal/TerminalAppTest.java b/cli/src/test/java/org/wrml/werminal/terminal/TerminalAppTest.java
new file mode 100644
index 0000000..253badd
--- /dev/null
+++ b/cli/src/test/java/org/wrml/werminal/terminal/TerminalAppTest.java
@@ -0,0 +1,160 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.wrml.werminal.terminal;
+
+import com.googlecode.lanterna.TerminalFacade;
+import com.googlecode.lanterna.gui.GUIScreen;
+import com.googlecode.lanterna.gui.GUIScreen.Position;
+import com.googlecode.lanterna.gui.Window;
+import com.googlecode.lanterna.gui.dialog.DialogResult;
+import com.googlecode.lanterna.gui.dialog.MessageBox;
+import com.googlecode.lanterna.screen.Screen;
+import com.googlecode.lanterna.terminal.Terminal;
+import com.googlecode.lanterna.terminal.TerminalSize;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.wrml.runtime.Context;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.when;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+
+/**
+ * Test for {@link TerminalApp}.
+ *
+ * Initial goal is to hit most-used methods based on profiling results.
+ *
+ * @author JJ Zabkar
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({MessageBox.class, TerminalFacade.class, DialogResult.class, Position.class})
+public class TerminalAppTest
+{
+
+ /**
+ * class under test
+ */
+ private TerminalApp _TerminalApp;
+
+ @Mock
+ private Context mockContext;
+
+ @Mock
+ private String mockErrorMessage;
+
+ @Mock
+ private String mockTitle;
+
+ @Mock
+ private String mockMessage;
+
+ @Mock
+ private DialogResult mockDialogResult;
+
+ @Mock
+ private Throwable mockThrowable;
+
+ @Mock
+ private Window mockWindow;
+
+ @Mock
+ private Position mockPosition;
+
+ @Mock
+ private GUIScreen mockGUIScreen;
+
+ @Mock
+ private Screen mockScreen;
+
+ @Mock
+ private TerminalSize mockTerminalSize;
+
+ @Before
+ public void setUp() throws Exception
+ {
+
+ mockStatic(MessageBox.class);
+ mockStatic(TerminalFacade.class);
+
+ when(MessageBox.showMessageBox(any(GUIScreen.class), any(String.class), any(String.class))).thenReturn(
+ mockDialogResult);
+ when(TerminalFacade.createGUIScreen(any(Terminal.class))).thenReturn(mockGUIScreen);
+ when(TerminalFacade.createScreen(any(Terminal.class))).thenReturn(mockScreen);
+ when(mockGUIScreen.getScreen()).thenReturn(mockScreen);
+ when(mockScreen.getTerminalSize()).thenReturn(mockTerminalSize);
+ when(mockTerminalSize.getColumns()).thenReturn(100);
+
+ _TerminalApp = new TerminalApp("Test", mockContext);
+ }
+
+ @After
+ public void tearDown() throws Exception
+ {
+
+ _TerminalApp = null;
+ }
+
+ @Test
+ public void testShowErrorString()
+ {
+
+ _TerminalApp.showError(mockErrorMessage);
+ }
+
+ @Test
+ public void testShowErrorStringThrowable()
+ {
+
+ _TerminalApp.showError(mockErrorMessage, mockThrowable);
+ }
+
+ @Test
+ public void testShowMessageBox()
+ {
+
+ _TerminalApp.showMessageBox(mockTitle, mockMessage);
+ }
+
+ @Test
+ public void testShowWindowWindow()
+ {
+
+ _TerminalApp.showWindow(mockWindow);
+ }
+
+ @Test
+ public void testShowWindowWindowPosition()
+ {
+
+ _TerminalApp.showWindow(mockWindow, mockPosition);
+ }
+
+}
diff --git a/cli/src/test/resources/fileSystemServiceRootDirectory/placeholder.txt b/cli/src/test/resources/fileSystemServiceRootDirectory/placeholder.txt
new file mode 100644
index 0000000..b367646
--- /dev/null
+++ b/cli/src/test/resources/fileSystemServiceRootDirectory/placeholder.txt
@@ -0,0 +1,4 @@
+placeholder.txt
+
+This file is a placeholder to ensure that this test resource directory is
+version controlled in case there are issues with empty directories.
\ No newline at end of file
diff --git a/cli/src/test/resources/logback-test.xml b/cli/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..4fa1903
--- /dev/null
+++ b/cli/src/test/resources/logback-test.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cli/src/test/resources/schemaClassRootDirectory/placeholder.txt b/cli/src/test/resources/schemaClassRootDirectory/placeholder.txt
new file mode 100644
index 0000000..b367646
--- /dev/null
+++ b/cli/src/test/resources/schemaClassRootDirectory/placeholder.txt
@@ -0,0 +1,4 @@
+placeholder.txt
+
+This file is a placeholder to ensure that this test resource directory is
+version controlled in case there are issues with empty directories.
\ No newline at end of file
diff --git a/cli/src/test/resources/wrml.json b/cli/src/test/resources/wrml.json
new file mode 100644
index 0000000..7e3a51a
--- /dev/null
+++ b/cli/src/test/resources/wrml.json
@@ -0,0 +1,48 @@
+{
+
+ "context" :
+ {
+ "modelCache" :
+ {
+ "name":"Cache",
+ "implementation":"org.wrml.runtime.service.cache.ShardedModelCache"
+ },
+
+ "schemaLoader" :
+ {
+
+ "factory" : "org.wrml.runtime.schema.DefaultSchemaLoaderFactory",
+ "schemaClassRootDirectory":"./src/test/resources/schemaClassRootDirectory"
+ },
+
+ "serviceLoader" :
+ {
+ "services" :
+ [
+ {
+ "name" : "File",
+ "implementation" : "org.wrml.runtime.service.file.FileSystemService",
+ "settings" :
+ {
+ "rootDirectory" : "./src/test/resources/fileSystemServiceRootDirectory"
+ }
+ },
+ {
+ "name" : "ApiDesigner",
+ "implementation" : "org.wrml.runtime.service.apiDesigner.ApiDesignerService",
+ "settings" :
+ {
+ "apiUri" : "http://design.api.wrml.org"
+ }
+ }
+
+ ],
+
+ "serviceMapping" :
+ {
+ "http://schema.api.wrml.org/org/wrml/runtime/service/apiDesigner/*" : "ApiDesigner",
+ "*" : "File"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/contrib/.gitignore b/contrib/.gitignore
new file mode 100644
index 0000000..a448b58
--- /dev/null
+++ b/contrib/.gitignore
@@ -0,0 +1,4 @@
+bin
+.project
+.classpath
+.settings
diff --git a/contrib/contrib.iml b/contrib/contrib.iml
new file mode 100644
index 0000000..b475024
--- /dev/null
+++ b/contrib/contrib.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contrib/maven/.gitignore b/contrib/maven/.gitignore
new file mode 100644
index 0000000..eb5a316
--- /dev/null
+++ b/contrib/maven/.gitignore
@@ -0,0 +1 @@
+target
diff --git a/contrib/maven/maven.iml b/contrib/maven/maven.iml
new file mode 100644
index 0000000..7d40b66
--- /dev/null
+++ b/contrib/maven/maven.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contrib/maven/pom.xml b/contrib/maven/pom.xml
new file mode 100644
index 0000000..d3c7636
--- /dev/null
+++ b/contrib/maven/pom.xml
@@ -0,0 +1,57 @@
+
+ 4.0.0
+
+ org.wrml
+ contrib
+ 1.0-SNAPSHOT
+
+
+ Mark Masse (OSS project WRML.org)
+ http://www.wrml.org
+
+ org.wrml.contrib
+ pom
+ maven
+ Contributions that may optionally be used along with the WRML core.
+
+ UTF-8
+ UTF-8
+
+
+
+
+
+
+ junit
+ junit
+ test
+
+
+ org.mockito
+ mockito-all
+ test
+
+
+
+
+
+ ./schema-builder-plugin
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
+
+ maven
+
diff --git a/contrib/maven/schema-builder-plugin/.gitignore b/contrib/maven/schema-builder-plugin/.gitignore
new file mode 100644
index 0000000..42eda58
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/.gitignore
@@ -0,0 +1,7 @@
+target
+bin
+logs
+.classpath
+.project
+.settings
+dependency-reduced-pom.xml
diff --git a/contrib/maven/schema-builder-plugin/example-models/.gitignore b/contrib/maven/schema-builder-plugin/example-models/.gitignore
new file mode 100644
index 0000000..42eda58
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/example-models/.gitignore
@@ -0,0 +1,7 @@
+target
+bin
+logs
+.classpath
+.project
+.settings
+dependency-reduced-pom.xml
diff --git a/contrib/maven/schema-builder-plugin/example-models/pom.xml b/contrib/maven/schema-builder-plugin/example-models/pom.xml
new file mode 100644
index 0000000..4d34bd9
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/example-models/pom.xml
@@ -0,0 +1,57 @@
+
+ 4.0.0
+ org.wrml.contrib.examples
+ example-models
+ 1.0-SNAPSHOT
+
+
+
+ org.wrml
+ schema-builder-plugin
+ 1.0-SNAPSHOT
+
+
+ process-resources
+
+ model
+
+
+
+
+
+
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ 1.0.0
+
+
+
+
+
+ org.wrml
+
+ schema-builder-plugin
+
+
+ [1.0-SNAPSHOT,)
+
+
+ model
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/contrib/maven/schema-builder-plugin/example-models/src/main/json-schema/org/wrml/test/Person.json b/contrib/maven/schema-builder-plugin/example-models/src/main/json-schema/org/wrml/test/Person.json
new file mode 100644
index 0000000..d7c55dc
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/example-models/src/main/json-schema/org/wrml/test/Person.json
@@ -0,0 +1,19 @@
+{
+ "title": "Person Schema",
+ "type": "object",
+ "properties": {
+ "firstName": {
+ "type": "string"
+ },
+ "lastName": {
+ "type": "string"
+ },
+ "age": {
+ "description": "Age in years",
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 150
+ }
+ },
+ "required": ["firstName", "lastName"]
+}
\ No newline at end of file
diff --git a/contrib/maven/schema-builder-plugin/example-models/src/main/wrml-model/org/wrml/test/Alphabet.mdl b/contrib/maven/schema-builder-plugin/example-models/src/main/wrml-model/org/wrml/test/Alphabet.mdl
new file mode 100644
index 0000000..b34d306
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/example-models/src/main/wrml-model/org/wrml/test/Alphabet.mdl
@@ -0,0 +1,33 @@
+{
+ "uniqueName" : "org/wrml/test/Alphabet",
+ "list" :
+ [
+ "alf",
+ "buckarooBanzai",
+ "capricaSix",
+ "darkwingDuck",
+ "et",
+ "flashGordon",
+ "gandalf",
+ "heMan",
+ "I",
+ "J",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "T",
+ "u",
+ "V",
+ "W",
+ "x",
+ "y",
+ "zippy"
+ ],
+ "version" : 1
+}
\ No newline at end of file
diff --git a/contrib/maven/schema-builder-plugin/example-models/src/main/wrml-model/org/wrml/test/WrmlLetters.mdl b/contrib/maven/schema-builder-plugin/example-models/src/main/wrml-model/org/wrml/test/WrmlLetters.mdl
new file mode 100644
index 0000000..263ca7b
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/example-models/src/main/wrml-model/org/wrml/test/WrmlLetters.mdl
@@ -0,0 +1,11 @@
+{
+ "uniqueName" : "org/wrml/test/WrmlLetters",
+ "list" :
+ [
+ "W",
+ "R",
+ "M",
+ "L"
+ ],
+ "version" : 1
+}
\ No newline at end of file
diff --git a/contrib/maven/schema-builder-plugin/pom.xml b/contrib/maven/schema-builder-plugin/pom.xml
new file mode 100644
index 0000000..bd82a8e
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/pom.xml
@@ -0,0 +1,70 @@
+
+
+ 4.0.0
+
+ org.wrml.contrib
+ maven
+ 1.0-SNAPSHOT
+
+ schema-builder-plugin
+ maven-plugin
+ schema-builder-plugin Maven Mojo
+ http://maven.apache.org
+
+ Mark Masse (OSS project WRML.org)
+ http://www.wrml.org
+
+
+
+
+
+
+ com.mycila.maven-license-plugin
+ maven-license-plugin
+
+ true
+ src/main/resources/headers/JavaFileHeader-latest.txt
+
+ src/**/*.java
+
+ UTF-8
+
+ src/main/resources/headers/JavaFileHeader-version-00.txt
+ src/main/resources/headers/JavaFileHeader-version-01.txt
+ src/main/resources/headers/JavaFileHeader-version-02.txt
+
+
+
+
+ test
+
+ check
+
+
+
+
+
+
+
+
+ commons-io
+ commons-io
+
+
+ org.apache.maven
+ maven-plugin-api
+
+
+ junit
+ junit
+ test
+
+
+ org.wrml
+ core
+
+
+
diff --git a/contrib/maven/schema-builder-plugin/schema-builder-plugin.iml b/contrib/maven/schema-builder-plugin/schema-builder-plugin.iml
new file mode 100644
index 0000000..a831b85
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/schema-builder-plugin.iml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contrib/maven/schema-builder-plugin/src/main/java/org/wrml/mojo/schema/builder/SchemaBuilderMojo.java b/contrib/maven/schema-builder-plugin/src/main/java/org/wrml/mojo/schema/builder/SchemaBuilderMojo.java
new file mode 100644
index 0000000..1134fd7
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/src/main/java/org/wrml/mojo/schema/builder/SchemaBuilderMojo.java
@@ -0,0 +1,224 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) ${year} Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.mojo.schema.builder;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.nio.file.Path;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.wrml.model.schema.Schema;
+import org.wrml.runtime.DefaultEngine;
+import org.wrml.runtime.Engine;
+import org.wrml.runtime.EngineConfiguration;
+import org.wrml.runtime.format.application.schema.json.JsonSchema;
+import org.wrml.runtime.format.application.schema.json.JsonSchemaLoader;
+import org.wrml.runtime.rest.SystemApi;
+import org.wrml.runtime.schema.SchemaLoader;
+import org.wrml.runtime.service.file.FileSystemService;
+
+/**
+ * Goal which touches a timestamp file.
+ *
+ * @goal model
+ *
+ * @phase process-resources
+ */
+public class SchemaBuilderMojo extends AbstractMojo {
+
+ public static final String MANIFEST_NAME = "manifest.txt";
+ /**
+ * Project's source directory as specified in the POM.
+ *
+ * @parameter expression="${project.build.sourceDirectory}"
+ * @readonly
+ * @required
+ */
+ private File resourcesDirectory;
+ /**
+ * Location of the file.
+ *
+ * @parameter expression="${project.build.outputDirectory}"
+ * @required
+ */
+ private File outputDirectory;
+
+ private Engine engine;
+ private URI rootJsonSchemaUri;
+ @SuppressWarnings("unused")
+ private URI rootWrmlModelUri;
+
+ private enum SourceType { JSON_SCHEMA, WRML_MODEL };
+
+ public void execute() throws MojoExecutionException {
+ /*
+ * Recursive decent into the resourcesDirectory looking for files with
+ * the extension .mdl These are JSON files that describe a model. Read
+ * each .mdl file and generate a class in the target directory that
+ * implements the model.
+ */
+ File mainDir = resourcesDirectory.getParentFile();
+ if (!mainDir.isDirectory())
+ throw new MojoExecutionException(String.format(
+ "%s is not a directory.", resourcesDirectory.getPath()));
+
+
+ File rootWrmlModelDir = new File(mainDir, "wrml-model");
+ File rootJsonSchemaDir = new File(mainDir, "json-schema");
+
+ getLog().info("Expected JsonSchema Location: " + rootJsonSchemaDir.toString());
+ getLog().info("Expected Wrml Model location: " + rootWrmlModelDir.toString());
+ Path rootWrmlModelPath = rootWrmlModelDir.toPath();
+ Path rootJsonSchemaPath = rootJsonSchemaDir.toPath();
+
+ rootWrmlModelUri = rootWrmlModelPath.toUri();
+ rootJsonSchemaUri = rootJsonSchemaPath.toUri();
+
+ try {
+ engine = createEngine();
+ } catch (IOException e) {
+ throw new MojoExecutionException("Error creating wrml engine.", e);
+ }
+
+ try {
+ if(rootJsonSchemaDir.isDirectory()) {
+ getLog().info("Processing: " + rootJsonSchemaDir.toString());
+ File manifest = new File(rootJsonSchemaDir + File.separator + MANIFEST_NAME);
+ if(manifest.exists() && manifest.isFile()) {
+ getLog().info("Using file Manifest...");
+ decendManifest(manifest);
+ } else {
+ getLog().info("No Manifest at " + manifest.getAbsolutePath() + ", decending per directories...");
+ decend(rootJsonSchemaDir, SourceType.JSON_SCHEMA);
+ }
+ }
+ if(rootWrmlModelDir.isDirectory()) {
+ getLog().info("Processing: " + rootWrmlModelDir.toString());
+ decend(rootWrmlModelDir, SourceType.WRML_MODEL);
+ }
+ } catch (Exception e) {
+ throw new MojoExecutionException("Error generating models.", e);
+ }
+ }
+
+ // Only do this for JsonSchemas....
+ private void decendManifest(File manifestFile) throws IOException, ClassNotFoundException
+ {
+ List files = IOUtils.readLines(new FileInputStream(manifestFile));
+ String relPath = manifestFile.getParentFile().getAbsolutePath();
+ for(String file : files)
+ {
+ File rawSchema = new File(relPath + File.separator + file);
+ generateJsonSchema(rawSchema);
+ }
+ }
+
+ private void decend(File parentDir, SourceType sourceType) throws IOException, ClassNotFoundException {
+ if(sourceType == SourceType.JSON_SCHEMA) {
+ File models[] = parentDir.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.toLowerCase().endsWith(".json");
+ }
+ });
+ for (File model : models) {
+ generateJsonSchema(model);
+ }
+ } else if(sourceType == SourceType.WRML_MODEL) {
+ /* TODO: Uncomment the contents of this block when the
+ * generateWrmlModel method is fixed to work correctly.
+ *
+ File models[] = parentDir.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.toLowerCase().endsWith(".mdl");
+ }
+ });
+
+ for (File model : models) {
+ generateWrmlModel(model);
+ }
+ */
+ }
+
+ File subDirectories[] = parentDir.listFiles(new FileFilter() {
+ public boolean accept(File pathname) {
+ return pathname.isDirectory();
+ }
+ });
+ for (File subDirectory : subDirectories)
+ decend(subDirectory, sourceType);
+ }
+
+ private URI createModelUri(File sourceFile, URI rootUri) {
+ URI relativeUri = rootUri.relativize(sourceFile.toPath().toUri());
+ String modelUriString = SystemApi.Schema.getUri().toString() + "/" + relativeUri.toString();
+ modelUriString = modelUriString.substring(0, modelUriString.lastIndexOf("."));
+ getLog().info("Model URI created from " + relativeUri + ", and root " + rootUri + ", is " + modelUriString);
+ return URI.create(modelUriString);
+ }
+
+ private void generateJsonSchema(File sourceFile) throws IOException, ClassNotFoundException {
+ getLog().info("Working: " + sourceFile.getAbsolutePath());
+ SchemaLoader loader = engine.getContext().getSchemaLoader();
+ InputStream in = FileUtils.openInputStream(sourceFile);
+ JsonSchemaLoader jsonSchemaLoader = loader.getJsonSchemaLoader();
+ JsonSchema jsonSchema = jsonSchemaLoader.load(in, createModelUri(sourceFile, rootJsonSchemaUri));
+ Schema schema = loader.load(jsonSchema);
+ Class> classz = loader.getSchemaInterface(schema.getUri());
+ getLog().info("Created: " + classz.getName());
+ }
+
+ /* TODO: Uncomment and fix this so that it works
+ private void generateWrmlModel(File sourceFile) throws IOException, ClassNotFoundException {
+ SchemaLoader loader = engine.getContext().getSchemaLoader();
+ Schema schema = loader.load(sourceFile.toURI());
+ Class> classz = loader.getSchemaInterface(schema.getUri());
+ getLog().info("Created: " + classz.getName());
+ }
+ */
+
+ private EngineConfiguration createEngineConfig() throws IOException {
+ EngineConfiguration config = EngineConfiguration.load(this.getClass(), "wrml.json");
+ config.getContext().getSchemaLoader().setSchemaClassRootDirectory(outputDirectory);
+ getLog().info("config.context.schemaLoader.schemaClassRootDirectory = "
+ + config.getContext().getSchemaLoader().getSchemaClassRootDirectory().toString() );
+ return config;
+ }
+
+ public final Engine createEngine() throws IOException {
+ final Engine engine = new DefaultEngine();
+ engine.init(createEngineConfig());
+ return engine;
+ }
+}
+
\ No newline at end of file
diff --git a/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-latest.txt b/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-latest.txt
new file mode 100644
index 0000000..2212b4b
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-latest.txt
@@ -0,0 +1,22 @@
+WRML - Web Resource Modeling Language
+ __ __ ______ __ __ __
+/\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+\ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+
+http://www.wrml.org
+
+Copyright (C) ${year} Mark Masse (OSS project WRML.org)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-version-00.txt b/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-version-00.txt
new file mode 100644
index 0000000..f792205
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-version-00.txt
@@ -0,0 +1,22 @@
+WRML - Web Resource Modeling Language
+ __ __ ______ __ __ __
+/\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+\ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+
+http://www.wrml.org
+
+Copyright 2012 Mark Masse (OSS project WRML.org)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-version-01.txt b/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-version-01.txt
new file mode 100644
index 0000000..2212b4b
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-version-01.txt
@@ -0,0 +1,22 @@
+WRML - Web Resource Modeling Language
+ __ __ ______ __ __ __
+/\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+\ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+
+http://www.wrml.org
+
+Copyright (C) ${year} Mark Masse (OSS project WRML.org)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-version-02.txt b/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-version-02.txt
new file mode 100644
index 0000000..2552fba
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/src/main/resources/headers/JavaFileHeader-version-02.txt
@@ -0,0 +1,22 @@
+WRML - Web Resource Modeling Language
+ __ __ ______ __ __ __
+/\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+\ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+
+http://www.wrml.org
+
+Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/contrib/maven/schema-builder-plugin/src/main/resources/org/wrml/mojo/schema/builder/wrml.json b/contrib/maven/schema-builder-plugin/src/main/resources/org/wrml/mojo/schema/builder/wrml.json
new file mode 100644
index 0000000..fc3e808
--- /dev/null
+++ b/contrib/maven/schema-builder-plugin/src/main/resources/org/wrml/mojo/schema/builder/wrml.json
@@ -0,0 +1,39 @@
+{
+
+ "context" :
+ {
+ "modelCache" :
+ {
+ "name":"Cache",
+ "implementation":"org.wrml.runtime.service.cache.ShardedModelCache"
+ },
+
+ "schemaLoader" :
+ {
+
+ "factory" : "org.wrml.runtime.schema.DefaultSchemaLoaderFactory",
+
+ "schemaClassRootDirectory":"",
+ "jsonSchemaIds":
+ [
+ "http://www.my.schemas/schemas/my-schema.json"
+ ]
+ },
+
+ "serviceLoader" :
+ {
+ "services" :
+ [
+
+ ],
+
+ "serviceChains" :
+ {
+ "*":
+ [
+
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/contrib/pom.xml b/contrib/pom.xml
new file mode 100644
index 0000000..79d5db5
--- /dev/null
+++ b/contrib/pom.xml
@@ -0,0 +1,40 @@
+
+ 4.0.0
+
+ org.wrml
+ wrml
+ 1.0-SNAPSHOT
+
+
+
+ Mark Masse (OSS project WRML.org)
+ http://www.wrml.org
+
+
+
+ contrib
+ pom
+ wrml-contrib
+ Contributions that may optionally be used along with the WRML core.
+
+
+ runtime
+ maven
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
+
+
diff --git a/contrib/runtime/pom.xml b/contrib/runtime/pom.xml
new file mode 100644
index 0000000..be1546c
--- /dev/null
+++ b/contrib/runtime/pom.xml
@@ -0,0 +1,36 @@
+
+ 4.0.0
+
+ org.wrml
+ contrib
+ 1.0-SNAPSHOT
+
+
+
+ Mark Masse (OSS project WRML.org)
+ http://www.wrml.org
+
+
+ org.wrml.contrib
+ runtime
+ pom
+ wrml-contrib-runtime
+ Contributions that may optionally be used along with the WRML core runtime.
+
+
+ service
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
diff --git a/contrib/runtime/runtime.iml b/contrib/runtime/runtime.iml
new file mode 100644
index 0000000..b475024
--- /dev/null
+++ b/contrib/runtime/runtime.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contrib/runtime/service/README.txt b/contrib/runtime/service/README.txt
new file mode 100644
index 0000000..34dc768
--- /dev/null
+++ b/contrib/runtime/service/README.txt
@@ -0,0 +1 @@
+This project is home to Service contributions.
\ No newline at end of file
diff --git a/contrib/runtime/service/groovy/.gitignore b/contrib/runtime/service/groovy/.gitignore
new file mode 100644
index 0000000..35cb9d1
--- /dev/null
+++ b/contrib/runtime/service/groovy/.gitignore
@@ -0,0 +1,3 @@
+target
+dependency-reduced-pom.xml
+
diff --git a/contrib/runtime/service/groovy/groovy.iml b/contrib/runtime/service/groovy/groovy.iml
new file mode 100644
index 0000000..8b341c5
--- /dev/null
+++ b/contrib/runtime/service/groovy/groovy.iml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contrib/runtime/service/groovy/logs/wrml.log b/contrib/runtime/service/groovy/logs/wrml.log
new file mode 100644
index 0000000..c7ceaa2
--- /dev/null
+++ b/contrib/runtime/service/groovy/logs/wrml.log
@@ -0,0 +1,189 @@
+2013-03-27 01:57:56,615 0 [main] ERROR org.wrml.contrib.runtime.service.groovy.GroovyTemplateService getGroovyClass - Unable to compile target file [/Users/mark/Documents/WRML/code/WRML/contrib/runtime/service/groovy/target/test-classes/org/wrml/contrib/runtime/service/groovy/groovyTemplates/bad/jargon.groovy]
+org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
+/Users/mark/Documents/WRML/code/WRML/contrib/runtime/service/groovy/target/test-classes/org/wrml/contrib/runtime/service/groovy/groovyTemplates/bad/jargon.groovy: 1: expecting EOF, found 'Javalang' @ line 1, column 19.
+ crappy != compile Javalang Moose
+ ^
+
+1 error
+
+ at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:309)
+ at org.codehaus.groovy.control.ErrorCollector.addFatalError(ErrorCollector.java:149)
+ at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:119)
+ at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:131)
+ at org.codehaus.groovy.control.SourceUnit.addError(SourceUnit.java:359)
+ at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:142)
+ at org.codehaus.groovy.antlr.AntlrParserPlugin.parseCST(AntlrParserPlugin.java:108)
+ at org.codehaus.groovy.control.SourceUnit.parse(SourceUnit.java:236)
+ at org.codehaus.groovy.control.CompilationUnit$1.call(CompilationUnit.java:163)
+ at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:912)
+ at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:575)
+ at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:551)
+ at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:528)
+ at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:279)
+ at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:258)
+ at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:244)
+ at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:185)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.getGroovyClass(GroovyTemplateService.java:141)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.getGroovyTemplate(GroovyTemplateService.java:161)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.loadGroovyTemplate(GroovyTemplateService.java:113)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.get(GroovyTemplateService.java:91)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateServiceTest.testLoadJargonTemplate(GroovyTemplateServiceTest.java:149)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:601)
+ at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
+ at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
+ at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
+ at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
+ at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
+ at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
+ at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
+ at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
+ at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
+ at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
+ at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
+ at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
+ at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
+ at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
+ at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
+ at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
+ at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
+ at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115)
+ at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:601)
+ at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
+ at $Proxy0.invoke(Unknown Source)
+ at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
+ at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
+ at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
+2013-03-27 01:57:56,621 6 [main] WARN org.wrml.contrib.runtime.service.groovy.GroovyTemplateService loadGroovyTemplate - Failed to load template from location /Users/mark/Documents/WRML/code/WRML/contrib/runtime/service/groovy/target/test-classes/org/wrml/contrib/runtime/service/groovy/groovyTemplates/, proceeding to next root.
+2013-03-29 17:39:21,192 0 [main] ERROR org.wrml.contrib.runtime.service.groovy.GroovyTemplateService getGroovyClass - Unable to compile target file [/Users/mark/Documents/WRML/code/WRML/contrib/runtime/service/groovy/target/test-classes/org/wrml/contrib/runtime/service/groovy/groovyTemplates/bad/jargon.groovy]
+org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
+/Users/mark/Documents/WRML/code/WRML/contrib/runtime/service/groovy/target/test-classes/org/wrml/contrib/runtime/service/groovy/groovyTemplates/bad/jargon.groovy: 1: expecting EOF, found 'Javalang' @ line 1, column 19.
+ crappy != compile Javalang Moose
+ ^
+
+1 error
+
+ at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:309)
+ at org.codehaus.groovy.control.ErrorCollector.addFatalError(ErrorCollector.java:149)
+ at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:119)
+ at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:131)
+ at org.codehaus.groovy.control.SourceUnit.addError(SourceUnit.java:359)
+ at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:142)
+ at org.codehaus.groovy.antlr.AntlrParserPlugin.parseCST(AntlrParserPlugin.java:108)
+ at org.codehaus.groovy.control.SourceUnit.parse(SourceUnit.java:236)
+ at org.codehaus.groovy.control.CompilationUnit$1.call(CompilationUnit.java:163)
+ at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:912)
+ at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:575)
+ at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:551)
+ at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:528)
+ at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:279)
+ at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:258)
+ at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:244)
+ at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:185)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.getGroovyClass(GroovyTemplateService.java:141)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.getGroovyTemplate(GroovyTemplateService.java:161)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.loadGroovyTemplate(GroovyTemplateService.java:113)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.get(GroovyTemplateService.java:91)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateServiceTest.testLoadJargonTemplate(GroovyTemplateServiceTest.java:149)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:601)
+ at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
+ at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
+ at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
+ at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
+ at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
+ at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
+ at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
+ at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
+ at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
+ at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
+ at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
+ at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
+ at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
+ at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
+ at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
+ at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
+ at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
+ at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115)
+ at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:601)
+ at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
+ at $Proxy0.invoke(Unknown Source)
+ at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
+ at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
+ at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
+2013-03-29 17:39:21,199 7 [main] WARN org.wrml.contrib.runtime.service.groovy.GroovyTemplateService loadGroovyTemplate - Failed to load template from location /Users/mark/Documents/WRML/code/WRML/contrib/runtime/service/groovy/target/test-classes/org/wrml/contrib/runtime/service/groovy/groovyTemplates/, proceeding to next root.
+2013-03-30 11:13:47,766 0 [main] ERROR org.wrml.contrib.runtime.service.groovy.GroovyTemplateService getGroovyClass - Unable to compile target file [/Users/mark/Documents/WRML/code/WRML/contrib/runtime/service/groovy/target/test-classes/org/wrml/contrib/runtime/service/groovy/groovyTemplates/bad/jargon.groovy]
+org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
+/Users/mark/Documents/WRML/code/WRML/contrib/runtime/service/groovy/target/test-classes/org/wrml/contrib/runtime/service/groovy/groovyTemplates/bad/jargon.groovy: 1: expecting EOF, found 'Javalang' @ line 1, column 19.
+ crappy != compile Javalang Moose
+ ^
+
+1 error
+
+ at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:309)
+ at org.codehaus.groovy.control.ErrorCollector.addFatalError(ErrorCollector.java:149)
+ at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:119)
+ at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:131)
+ at org.codehaus.groovy.control.SourceUnit.addError(SourceUnit.java:359)
+ at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:142)
+ at org.codehaus.groovy.antlr.AntlrParserPlugin.parseCST(AntlrParserPlugin.java:108)
+ at org.codehaus.groovy.control.SourceUnit.parse(SourceUnit.java:236)
+ at org.codehaus.groovy.control.CompilationUnit$1.call(CompilationUnit.java:163)
+ at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:912)
+ at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:575)
+ at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:551)
+ at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:528)
+ at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:279)
+ at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:258)
+ at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:244)
+ at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:185)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.getGroovyClass(GroovyTemplateService.java:141)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.getGroovyTemplate(GroovyTemplateService.java:161)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.loadGroovyTemplate(GroovyTemplateService.java:113)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateService.get(GroovyTemplateService.java:91)
+ at org.wrml.contrib.runtime.service.groovy.GroovyTemplateServiceTest.testLoadJargonTemplate(GroovyTemplateServiceTest.java:149)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:601)
+ at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
+ at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
+ at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
+ at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
+ at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:19)
+ at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
+ at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
+ at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
+ at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
+ at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
+ at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
+ at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
+ at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
+ at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
+ at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
+ at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
+ at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
+ at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115)
+ at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
+ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+ at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
+ at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+ at java.lang.reflect.Method.invoke(Method.java:601)
+ at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
+ at $Proxy0.invoke(Unknown Source)
+ at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
+ at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
+ at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
+2013-03-30 11:13:47,772 6 [main] WARN org.wrml.contrib.runtime.service.groovy.GroovyTemplateService loadGroovyTemplate - Failed to load template from location /Users/mark/Documents/WRML/code/WRML/contrib/runtime/service/groovy/target/test-classes/org/wrml/contrib/runtime/service/groovy/groovyTemplates/, proceeding to next root.
diff --git a/contrib/runtime/service/groovy/pom.xml b/contrib/runtime/service/groovy/pom.xml
new file mode 100644
index 0000000..2991547
--- /dev/null
+++ b/contrib/runtime/service/groovy/pom.xml
@@ -0,0 +1,119 @@
+
+ 4.0.0
+
+ org.wrml.contrib.runtime
+ service
+ 1.0-SNAPSHOT
+
+
+
+ Mark Masse (OSS project WRML.org)
+ http://www.wrml.org
+
+
+ org.wrml.contrib.runtime.service
+ groovy
+ wrml-contrib-runtime-service-groovy
+ The Groovy template language as a WRML service.
+
+
+
+
+ org.wrml
+ core
+
+
+ org.wrml
+ core
+ test-jar
+ test
+
+
+
+
+ org.codehaus.groovy
+ groovy-all
+
+
+
+
+ ch.qos.logback
+ logback-classic
+
+
+
+
+ junit
+ junit
+ test
+
+
+ org.mockito
+ mockito-all
+ test
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-eclipse-plugin
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ org.wrml.cli.Wrml
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+
+
+
+
+ org.wrml:core:*:*
+
+
+
+
+
+ package
+
+ shade
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/EmbeddedGroovyService.java b/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/EmbeddedGroovyService.java
new file mode 100644
index 0000000..08b25ac
--- /dev/null
+++ b/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/EmbeddedGroovyService.java
@@ -0,0 +1,127 @@
+
+package org.wrml.contrib.runtime.service.groovy;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.control.CompilationFailedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.wrml.model.Model;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.Dimensions;
+import org.wrml.runtime.Keys;
+import org.wrml.runtime.service.AbstractService;
+import org.wrml.runtime.service.ServiceConfiguration;
+import org.wrml.runtime.service.ServiceException;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Map;
+
+public class EmbeddedGroovyService extends AbstractService
+{
+ public static final String SERVICE_ABS_LOCATION_KEY = "absGroovyService";
+
+ public static final String SERVICE_RES_LOCATION_KEY = "resGroovyService";
+
+ private static final Logger LOG = LoggerFactory.getLogger(EmbeddedGroovyService.class);
+
+ private GroovyClassLoader _Loader;
+
+ private GroovyServiceInterface _GroovyService;
+
+ public GroovyServiceInterface getGroovyService()
+ {
+
+ return _GroovyService;
+ }
+
+ @Override
+ public void initFromConfiguration(final ServiceConfiguration serviceConfig)
+ {
+
+ Map config = serviceConfig.getSettings();
+ File scriptLocation = null;
+ String givenLocation;
+ if (config.containsKey(SERVICE_ABS_LOCATION_KEY))
+ {
+ givenLocation = config.get(SERVICE_ABS_LOCATION_KEY);
+ scriptLocation = new File(givenLocation);
+ }
+ else if (config.containsKey(SERVICE_RES_LOCATION_KEY))
+ {
+ givenLocation = config.get(SERVICE_RES_LOCATION_KEY);
+ URL resourceLocation = getClass().getResource(givenLocation);
+ if (resourceLocation == null)
+ {
+ throw new ServiceException("Service script specified not found. " + givenLocation, null, this);
+ }
+ scriptLocation = new File(resourceLocation.getFile());
+ }
+ else
+ {
+ throw new ServiceException("No service script specified to start EmbeddedGroovy.", null, this);
+ }
+
+ ClassLoader parent = getClass().getClassLoader();
+ _Loader = new GroovyClassLoader(parent);
+
+ Class groovyServiceClass;
+ try
+ {
+ groovyServiceClass = _Loader.parseClass(scriptLocation);
+ }
+ catch (CompilationFailedException | IOException ex)
+ {
+ String message = "Unable to parse given script into class. " + scriptLocation;
+ LOG.error(message, ex);
+ throw new ServiceException(message, ex, this);
+ }
+
+ try
+ {
+ _GroovyService = (GroovyServiceInterface) groovyServiceClass.newInstance();
+ }
+ catch (InstantiationException | IllegalAccessException ex)
+ {
+ String message = "Unable to instantiate Groovy Service class " + scriptLocation + ".";
+ LOG.error(message, ex);
+ throw new ServiceException(message, ex, this);
+ }
+
+ // TODO, comment out
+ if (_GroovyService == null)
+ {
+ throw new ServiceException("Unable to find given script name to load. " + scriptLocation, null, this);
+ }
+ }
+
+ @Override
+ public void delete(Keys keys, final Dimensions dimensions)
+ {
+
+ _GroovyService.delete(getContext(), keys);
+ }
+
+ @Override
+ public Model get(Keys keys, Dimensions dimensions)
+ {
+
+ final Context context = getContext();
+ // Create an instance of the model
+ Model model = context.newModel(dimensions);
+
+ _GroovyService.get(context, model, keys, dimensions);
+
+ return model;
+ }
+
+ @Override
+ public Model save(Model model)
+ {
+
+ model = _GroovyService.save(model);
+
+ return model;
+ }
+}
diff --git a/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/GroovyServiceInterface.java b/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/GroovyServiceInterface.java
new file mode 100644
index 0000000..2a40273
--- /dev/null
+++ b/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/GroovyServiceInterface.java
@@ -0,0 +1,18 @@
+
+package org.wrml.contrib.runtime.service.groovy;
+
+import java.util.SortedMap;
+import org.wrml.model.Model;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.Dimensions;
+import org.wrml.runtime.Keys;
+
+public interface GroovyServiceInterface
+{
+
+ public void delete(Context context, Keys keys);
+
+ public M get(Context context, M model, Keys keys, Dimensions dimensions);
+
+ public M save(M model);
+}
diff --git a/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/GroovyTemplate.java b/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/GroovyTemplate.java
new file mode 100644
index 0000000..eea458b
--- /dev/null
+++ b/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/GroovyTemplate.java
@@ -0,0 +1,12 @@
+
+package org.wrml.contrib.runtime.service.groovy;
+
+import org.wrml.model.Model;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.Dimensions;
+import org.wrml.runtime.Keys;
+
+public interface GroovyTemplate
+{
+ public M fill(Context context, M model, Keys keys, Dimensions dimensions);
+}
diff --git a/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/GroovyTemplateService.java b/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/GroovyTemplateService.java
new file mode 100644
index 0000000..99dc8fc
--- /dev/null
+++ b/contrib/runtime/service/groovy/src/main/java/org/wrml/contrib/runtime/service/groovy/GroovyTemplateService.java
@@ -0,0 +1,233 @@
+/**
+ * WRML - Web Resource Modeling Language
+ * __ __ ______ __ __ __
+ * /\ \ _ \ \ /\ == \ /\ "-./ \ /\ \
+ * \ \ \/ ".\ \\ \ __< \ \ \-./\ \\ \ \____
+ * \ \__/".~\_\\ \_\ \_\\ \_\ \ \_\\ \_____\
+ * \/_/ \/_/ \/_/ /_/ \/_/ \/_/ \/_____/
+ *
+ * http://www.wrml.org
+ *
+ * Copyright (C) 2013 Mark Masse (OSS project WRML.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.wrml.contrib.runtime.service.groovy;
+
+import groovy.lang.GroovyClassLoader;
+import java.io.File;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.wrml.model.Model;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.Dimensions;
+import org.wrml.runtime.Keys;
+import org.wrml.runtime.service.AbstractService;
+import org.wrml.runtime.service.ServiceConfiguration;
+import org.wrml.runtime.service.ServiceException;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.codehaus.groovy.control.CompilationFailedException;
+
+public class GroovyTemplateService extends AbstractService
+{
+
+ public static final String TEMPLATE_ROOT_LOCATION = "templateRoots";
+
+ public static final String ROOTS_SEP = ",";
+
+ private static final Logger LOG = LoggerFactory.getLogger(GroovyTemplateService.class);
+
+ private List _Roots;
+
+ private GroovyClassLoader _Loader;
+
+ private Map _Templates;
+
+ public Map getTemplates()
+ {
+ return _Templates;
+ }
+
+ public void clearTemplates()
+ {
+ _Templates.clear();
+ }
+
+ public List getRoots()
+ {
+ return _Roots;
+ }
+
+ @Override
+ public Model get(Keys keys, Dimensions dimensions)
+ {
+ // Create an instance of the model
+ Model model = getContext().newModel(dimensions);
+
+ // Pass arguments to the engine, cross fingers
+ GroovyTemplate template = _Templates.get(dimensions.getSchemaUri());
+ if (template == null)
+ {
+ template = loadGroovyTemplate(dimensions.getSchemaUri());
+ _Templates.put(dimensions.getSchemaUri(), template);
+ }
+
+ template.fill(getContext(), model, keys, dimensions);
+
+ // Return the model
+ return model;
+ }
+
+ private GroovyTemplate loadGroovyTemplate(URI schemaUri)
+ {
+ GroovyTemplate template = null;
+ File scriptLocation;
+ for(String rootPath : _Roots)
+ {
+ String scriptAttempt = rootPath + schemaUri;
+ scriptLocation = new File(scriptAttempt);
+ if(scriptLocation.exists() && scriptLocation.isFile())
+ {
+ try
+ {
+ template = getGroovyTemplate(scriptLocation);
+ break;
+ }
+ catch(Exception e)
+ {
+ LOG.warn("Failed to load template from location {}, proceeding to next root.", new Object[]{rootPath});
+ }
+ }
+ else
+ {
+ scriptLocation = null;
+ }
+ }
+
+ if(template == null)
+ {
+ String message = "No template found to match the requested resource, " + schemaUri;
+ throw new ServiceException(message, null, this);
+ }
+
+ return template;
+ }
+
+ private Class getGroovyClass(File location)
+ {
+ Class groovyTemplateClass;
+ try
+ {
+ groovyTemplateClass = _Loader.parseClass(location);
+ }
+ catch (CompilationFailedException cfe)
+ {
+ String message = "Unable to compile target file [" + location + "]";
+ LOG.error(message, cfe);
+ throw new ServiceException(message, cfe, this);
+ }
+ catch (IOException ioe)
+ {
+ String message = "Unable to read/locate file [" + location + "]";
+ LOG.error(message, ioe);
+ throw new ServiceException(message, ioe, this);
+ }
+
+ return groovyTemplateClass;
+ }
+
+ private GroovyTemplate getGroovyTemplate(File scriptLocation)
+ {
+ Class groovyTemplateClass = getGroovyClass(scriptLocation);
+
+ GroovyTemplate template;
+ try
+ {
+ template = (GroovyTemplate)groovyTemplateClass.newInstance();
+ }
+ catch (InstantiationException ie)
+ {
+ String message = "Unable to instantiate instance of groovy template.";
+ LOG.error(message, ie);
+ throw new ServiceException(message, ie, this);
+ }
+ catch (IllegalAccessException iae)
+ {
+ String message = "Unable to access class for instantiation.";
+ LOG.error(message, iae);
+ throw new ServiceException(message, iae, this);
+ }
+
+ return template;
+ }
+
+ @Override
+ protected void initFromConfiguration(final ServiceConfiguration config)
+ {
+
+ if (config == null)
+ {
+ final ServiceException e = new ServiceException("The config cannot be null.", null, this);
+ LOG.error(e.getMessage(), e);
+ throw e;
+ }
+
+ final Map settings = config.getSettings();
+ if (settings == null)
+ {
+ final ServiceException e = new ServiceException("The config settings cannot be null.", null, this);
+ LOG.error(e.getMessage(), e);
+ throw e;
+ }
+
+ String rootsString = settings.get(TEMPLATE_ROOT_LOCATION);
+ if (rootsString == null || rootsString.equals(""))
+ {
+ LOG.error("No root path param passed to GroovyTemplateService.");
+ throw new ServiceException("Unable to instantiate GroovyTemplateService, the template roots are null or empty.", null, this);
+ }
+
+ String[] rootStrings = rootsString.split(ROOTS_SEP);
+ List tempRoots = Arrays.asList(rootStrings);
+ _Roots = new ArrayList();
+
+ for (String rootPath : tempRoots)
+ {
+ File root = new File(rootPath);
+ if (root.exists() && root.isDirectory())
+ {
+ _Roots.add(root.getAbsolutePath() + File.separator);
+ }
+ else
+ {
+ LOG.error("Removing {} from the list of roots, unable to locate.", new Object[]{rootPath});
+ }
+ }
+
+ if (_Roots.isEmpty())
+ {
+ throw new ServiceException("No viable roots configured.", null, this);
+ }
+
+ ClassLoader parent = getClass().getClassLoader();
+ _Loader = new GroovyClassLoader(parent);
+ _Templates = new HashMap();
+ }
+}
diff --git a/contrib/runtime/service/groovy/src/test/java/org/wrml/contrib/runtime/service/groovy/EmbeddedGroovyServiceTest.java b/contrib/runtime/service/groovy/src/test/java/org/wrml/contrib/runtime/service/groovy/EmbeddedGroovyServiceTest.java
new file mode 100644
index 0000000..88d35ba
--- /dev/null
+++ b/contrib/runtime/service/groovy/src/test/java/org/wrml/contrib/runtime/service/groovy/EmbeddedGroovyServiceTest.java
@@ -0,0 +1,210 @@
+
+package org.wrml.contrib.runtime.service.groovy;
+
+import groovy.lang.GroovyObject;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import org.wrml.runtime.Context;
+import org.wrml.runtime.service.ServiceException;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import org.wrml.model.Model;
+import org.wrml.model.rest.Document;
+import org.wrml.runtime.Dimensions;
+import org.wrml.runtime.Keys;
+import org.wrml.runtime.service.DefaultServiceConfiguration;
+
+public class EmbeddedGroovyServiceTest
+{
+ private static final String GROOVY_SERVICE_RES_LOCATION = "groovyTemplates/Server.groovy";
+ private static final String GROOVY_SERVICE_REL_LOCATION = "src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/Server.groovy";
+
+ private static final String SERVER_CACHE_METHOD = "getCache";
+ private static final String SERVER_CALL_COUNT_METHOD = "getCallCount";
+
+ private static final URI DOC_SCHEMA_ID = URI.create("moose/squirrel");
+ private static final String DOC_KEY_VALUE = "Bulwinkle";
+
+ private EmbeddedGroovyService _Service;
+ private Context _Context;
+
+
+ @Before
+ public void setUp()
+ {
+ _Service = new EmbeddedGroovyService();
+
+ // Init
+ SortedMap config = new TreeMap<>();
+ config.put(EmbeddedGroovyService.SERVICE_RES_LOCATION_KEY, GROOVY_SERVICE_RES_LOCATION);
+ final DefaultServiceConfiguration defaultServiceConfiguration = new DefaultServiceConfiguration();
+ defaultServiceConfiguration.setSettings(config);
+
+ _Context = mock(Context.class);
+ _Service.init(_Context, defaultServiceConfiguration);
+ }
+
+ @After
+ public void tearDown()
+ {
+ _Service = null;
+ _Context = null;
+ }
+
+ @Test(expected=ServiceException.class)
+ public void testInitNullConfig()
+ {
+ _Service.init(null, null);
+ }
+
+ @Test(expected=ServiceException.class)
+ public void testInitBadAbsoluteLocation()
+ {
+ SortedMap config = new TreeMap<>();
+ config.put(EmbeddedGroovyService.SERVICE_ABS_LOCATION_KEY, "xkzy");
+ final DefaultServiceConfiguration defaultServiceConfiguration = new DefaultServiceConfiguration();
+ defaultServiceConfiguration.setSettings(config);
+
+ _Service.init(null, defaultServiceConfiguration);
+ }
+
+ @Test(expected=ServiceException.class)
+ public void testInitBadResourceLocation()
+ {
+ SortedMap config = new TreeMap<>();
+ config.put(EmbeddedGroovyService.SERVICE_RES_LOCATION_KEY, "xkzy");
+ final DefaultServiceConfiguration defaultServiceConfiguration = new DefaultServiceConfiguration();
+ defaultServiceConfiguration.setSettings(config);
+
+ _Service.init(null, defaultServiceConfiguration);
+ }
+
+ @Test
+ public void testInitRes()
+ {
+ SortedMap config = new TreeMap<>();
+ config.put(EmbeddedGroovyService.SERVICE_RES_LOCATION_KEY, GROOVY_SERVICE_RES_LOCATION);
+ final DefaultServiceConfiguration defaultServiceConfiguration = new DefaultServiceConfiguration();
+ defaultServiceConfiguration.setSettings(config);
+
+ _Context = mock(Context.class);
+ _Service.init(_Context, defaultServiceConfiguration);
+
+ GroovyServiceInterface serv = _Service.getGroovyService();
+ assertTrue(serv != null);
+ }
+
+ @Test
+ public void testInitRel()
+ {
+ SortedMap config = new TreeMap<>();
+ config.put(EmbeddedGroovyService.SERVICE_ABS_LOCATION_KEY, GROOVY_SERVICE_REL_LOCATION);
+ final DefaultServiceConfiguration defaultServiceConfiguration = new DefaultServiceConfiguration();
+ defaultServiceConfiguration.setSettings(config);
+
+ _Context = mock(Context.class);
+ _Service.init(_Context, defaultServiceConfiguration);
+
+ GroovyServiceInterface serv = _Service.getGroovyService();
+ assertTrue(serv != null);
+ }
+
+ @Test
+ public void testGetBasic()
+ {
+ Dimensions dims = mock(Dimensions.class);
+ Document doc = mock(Document.class);
+ when(doc.getSchemaUri()).thenReturn(DOC_SCHEMA_ID);
+ when(_Context.newModel(dims)).thenReturn(doc);
+ Keys keys = mock(Keys.class);
+ when(keys.getValue(DOC_SCHEMA_ID)).thenReturn(DOC_KEY_VALUE);
+
+ Model value = _Service.get(keys, dims);
+
+ assertTrue(value.equals(doc));
+ }
+
+ @Test
+ public void testPutGetBasic()
+ {
+ Dimensions dims = mock(Dimensions.class);
+ Document doc = mock(Document.class);
+ when(doc.getSchemaUri()).thenReturn(DOC_SCHEMA_ID);
+ when(_Context.newModel(dims)).thenReturn(doc);
+ Keys keys = mock(Keys.class);
+ when(keys.getValue(DOC_SCHEMA_ID)).thenReturn(DOC_KEY_VALUE);
+ when(doc.getKeys()).thenReturn(keys);
+
+ Model value = _Service.save(doc);
+
+ assertTrue(value != null);
+ assertTrue(doc.equals(value));
+
+ Model value2 = _Service.get(keys, dims);
+
+ assertTrue(value != null);
+ assertTrue(doc.equals(value2));
+
+ GroovyServiceInterface serv = _Service.getGroovyService();
+ GroovyObject obj = (GroovyObject)serv;
+
+ Map cache = (Map)obj.invokeMethod(SERVER_CACHE_METHOD, null);
+
+ assertTrue(cache.size() == 1);
+
+ int callCount = Integer.valueOf(obj.invokeMethod(SERVER_CALL_COUNT_METHOD, null).toString());
+
+ assertTrue(callCount == 2);
+ }
+
+ @Test
+ public void testPutDeleteGet()
+ {
+ GroovyServiceInterface serv = _Service.getGroovyService();
+ GroovyObject obj = (GroovyObject)serv;
+
+ Map cache = (Map)obj.invokeMethod(SERVER_CACHE_METHOD, null);
+
+ int callCount = Integer.valueOf(obj.invokeMethod(SERVER_CALL_COUNT_METHOD, null).toString());
+
+ assertTrue(cache.size() == 0);
+ assertTrue(callCount == 0);
+
+ Dimensions dims = mock(Dimensions.class);
+ Document doc = mock(Document.class);
+ when(doc.getSchemaUri()).thenReturn(DOC_SCHEMA_ID);
+ when(_Context.newModel(dims)).thenReturn(doc);
+ Keys keys = mock(Keys.class);
+ Set schemaUris = new HashSet<>();
+ schemaUris.add(DOC_SCHEMA_ID);
+ when(keys.getKeyedSchemaUris()).thenReturn(schemaUris);
+ when(keys.getValue(DOC_SCHEMA_ID)).thenReturn(DOC_KEY_VALUE);
+ when(doc.getKeys()).thenReturn(keys);
+
+ Model value = _Service.save(doc);
+
+ callCount = Integer.valueOf(obj.invokeMethod(SERVER_CALL_COUNT_METHOD, null).toString());
+
+ assertTrue(value != null);
+ assertTrue(doc.equals(value));
+ assertTrue(cache.size() == 1);
+ assertTrue(callCount == 1);
+
+ _Service.delete(keys, value.getDimensions());
+
+ callCount = Integer.valueOf(obj.invokeMethod(SERVER_CALL_COUNT_METHOD, null).toString());
+
+ assertTrue(callCount == 2);
+ assertTrue(cache.size() == 0);
+ }
+}
diff --git a/contrib/runtime/service/groovy/src/test/java/org/wrml/contrib/runtime/service/groovy/GroovyTemplateServiceTest.java b/contrib/runtime/service/groovy/src/test/java/org/wrml/contrib/runtime/service/groovy/GroovyTemplateServiceTest.java
new file mode 100644
index 0000000..7c19091
--- /dev/null
+++ b/contrib/runtime/service/groovy/src/test/java/org/wrml/contrib/runtime/service/groovy/GroovyTemplateServiceTest.java
@@ -0,0 +1,299 @@
+
+package org.wrml.contrib.runtime.service.groovy;
+
+import java.net.URI;
+import java.util.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.wrml.model.Model;
+import org.wrml.runtime.Dimensions;
+import org.wrml.runtime.Keys;
+import org.wrml.runtime.service.DefaultServiceConfiguration;
+import org.wrml.runtime.service.ServiceConfiguration;
+import org.wrml.runtime.service.ServiceException;
+
+// TODO: This import isn't working out-of-the box with our current maven setup
+//import org.wrml.service.ServiceTest;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
+import static org.junit.Assert.assertTrue;
+import org.junit.Ignore;
+
+import org.wrml.model.rest.Document;
+import org.wrml.runtime.Context;
+
+// TODO: extends ServiceTest
+public class GroovyTemplateServiceTest //extends ServiceTest
+{
+ private GroovyTemplateService _Service;
+ private Context _Context;
+
+ private static final String RESOURCES = "org/wrml/contrib/runtime/service/groovy/groovyTemplates";
+
+ private static final String BASIC_SCRIPT_NAME = "TTL.groovy";
+ private static final String NO_SCRIPT_NAME = "bulhunky.groovy";
+ private static final String JARGON_SCRIPT_NAME = "bad/jargon.groovy";
+ private static final String DEEP_SET_SCRIPT_NAME = "TTLDeep.groovy";
+ private static final String SCRIPT_INPUT_KEY = "ttl";
+ private static final Long TTL_VALUE = 8L;
+
+ @Before
+ public void setUp()
+ {
+ _Service = new GroovyTemplateService();
+
+ // initialize
+ SortedMap settings = new TreeMap<>();
+ settings.put(GroovyTemplateService.TEMPLATE_ROOT_LOCATION, getClass().getClassLoader().getResource(RESOURCES).getFile());
+
+ _Context = mock(Context.class);
+ _Service.init(_Context, createServiceConfiguration(settings));
+ }
+
+ @After
+ public void tearDown()
+ {
+ _Service = null;
+ _Context = null;
+ }
+
+ @Test(expected=ServiceException.class)
+ public void testInitNull()
+ {
+ _Service = null;
+ _Service = new GroovyTemplateService();
+ _Service.init(null, null);
+ }
+
+ @Test(expected=ServiceException.class)
+ public void testInitEmpty()
+ {
+ _Service = null;
+ _Service = new GroovyTemplateService();
+
+ _Service.init(null, createServiceConfiguration());
+ }
+
+ @Test(expected=ServiceException.class)
+ public void testInitBadName()
+ {
+ _Service = null;
+ _Service = new GroovyTemplateService();
+
+ SortedMap settings = new TreeMap<>();
+ settings.put("random", "moose");
+ _Service.init(null, createServiceConfiguration(settings));
+ }
+
+ @Test(expected=ServiceException.class)
+ public void testInitBadLocation()
+ {
+ _Service = null;
+ _Service = new GroovyTemplateService();
+
+ SortedMap settings = new TreeMap<>();
+ settings.put(GroovyTemplateService.TEMPLATE_ROOT_LOCATION, "moose");
+ _Service.init(null, createServiceConfiguration(settings));
+ }
+
+ @Test
+ public void testInitGood()
+ {
+ _Service = null;
+ _Service = new GroovyTemplateService();
+
+ SortedMap settings = new TreeMap<>();
+ settings.put(GroovyTemplateService.TEMPLATE_ROOT_LOCATION, getClass().getClassLoader().getResource(RESOURCES).getFile());
+ _Service.init(_Context, createServiceConfiguration(settings));
+
+ assertTrue(_Service.getRoots().size() == 1);
+ assertTrue(_Service.getTemplates().isEmpty());
+ }
+
+ @Test(expected=ServiceException.class)
+ public void testLoadNoTemplate()
+ {
+ Context context = mock(Context.class);
+ Keys keys = mock(Keys.class);
+ Set args = new HashSet<>();
+ args.add(URI.create(SCRIPT_INPUT_KEY));
+ when(keys.getKeyedSchemaUris()).thenReturn(args);
+ when(keys.getValue(URI.create(SCRIPT_INPUT_KEY))).thenReturn("Bulwinkle");
+ Dimensions dimensions = mock(Dimensions.class);
+ Document doc = mock(Document.class);
+ when(context.newModel(dimensions)).thenReturn(doc);
+ URI scriptSchemaName = URI.create(NO_SCRIPT_NAME);
+ when(dimensions.getSchemaUri()).thenReturn(scriptSchemaName);
+ Model model = _Service.get(keys, dimensions);
+ }
+
+ @Test(expected=ServiceException.class)
+ public void testLoadJargonTemplate()
+ {
+ Context context = mock(Context.class);
+ Keys keys = mock(Keys.class);
+ Set args = new HashSet<>();
+ args.add(URI.create(SCRIPT_INPUT_KEY));
+ when(keys.getKeyedSchemaUris()).thenReturn(args);
+ when(keys.getValue(URI.create(SCRIPT_INPUT_KEY))).thenReturn("Bulwinkle");
+ Dimensions dimensions = mock(Dimensions.class);
+ Document doc = mock(Document.class);
+ when(context.newModel(dimensions)).thenReturn(doc);
+ URI scriptSchemaName = URI.create(JARGON_SCRIPT_NAME);
+ when(dimensions.getSchemaUri()).thenReturn(scriptSchemaName);
+ Model model = _Service.get(keys, dimensions);
+ }
+
+ @Test
+ public void testGetBasic()
+ {
+ Keys keys = mock(Keys.class);
+ Set args = new HashSet<>();
+ args.add(URI.create(SCRIPT_INPUT_KEY));
+ when(keys.getKeyedSchemaUris()).thenReturn(args);
+ when(keys.getValue(URI.create(SCRIPT_INPUT_KEY))).thenReturn(TTL_VALUE);
+ Dimensions dimensions = mock(Dimensions.class);
+ Document doc = mock(Document.class);
+ when(_Context.newModel(dimensions)).thenReturn(doc);
+ URI scriptSchemaName = URI.create(BASIC_SCRIPT_NAME);
+ when(dimensions.getSchemaUri()).thenReturn(scriptSchemaName);
+ Model model = _Service.get(keys, dimensions);
+
+ // Assert the model has what we hope
+ assertTrue(model.equals(doc));
+ assertTrue(_Service.getRoots().size() == 1);
+ assertTrue(_Service.getTemplates().size() == 1);
+ }
+
+ @Test
+ public void testGetSet()
+ {
+ Keys keys = mock(Keys.class);
+ Set args = new HashSet<>();
+ args.add(URI.create(SCRIPT_INPUT_KEY));
+ when(keys.getKeyedSchemaUris()).thenReturn(args);
+ when(keys.getValue(URI.create(SCRIPT_INPUT_KEY))).thenReturn(TTL_VALUE);
+ Dimensions dimensions = mock(Dimensions.class);
+ Document doc = mock(Document.class);
+ when(_Context.newModel(dimensions)).thenReturn(doc);
+ URI scriptSchemaName = URI.create(BASIC_SCRIPT_NAME);
+ when(dimensions.getSchemaUri()).thenReturn(scriptSchemaName);
+ Model model = _Service.get(keys, dimensions);
+
+ // Assert the model has what we hope
+ assertTrue(model.equals(doc));
+ assertTrue(_Service.getRoots().size() == 1);
+ assertTrue(_Service.getTemplates().size() == 1);
+ verify(doc, times(1)).setSecondsToLive(TTL_VALUE);
+ }
+
+ @Test
+ public void testMultipleGets()
+ {
+ Keys keys = mock(Keys.class);
+ Set args = new HashSet<>();
+ args.add(URI.create(SCRIPT_INPUT_KEY));
+ when(keys.getKeyedSchemaUris()).thenReturn(args);
+ when(keys.getValue(URI.create(SCRIPT_INPUT_KEY))).thenReturn(TTL_VALUE);
+ Dimensions dimensions = mock(Dimensions.class);
+ Document doc = mock(Document.class);
+ when(_Context.newModel(dimensions)).thenReturn(doc);
+ URI scriptSchemaName = URI.create(BASIC_SCRIPT_NAME);
+ when(dimensions.getSchemaUri()).thenReturn(scriptSchemaName);
+ Model model = _Service.get(keys, dimensions);
+
+ // Assert the model has what we hope
+ assertTrue(model.equals(doc));
+ assertTrue(_Service.getRoots().size() == 1);
+ assertTrue(_Service.getTemplates().size() == 1);
+ verify(doc, times(1)).setSecondsToLive(TTL_VALUE);
+
+ model = _Service.get(keys, dimensions);
+ model = _Service.get(keys, dimensions);
+ model = _Service.get(keys, dimensions);
+ verify(doc, times(4)).setSecondsToLive(TTL_VALUE);
+ assertTrue(_Service.getRoots().size() == 1);
+ assertTrue(_Service.getTemplates().size() == 1);
+
+ }
+
+ @Test
+ public void testDeepTemplates()
+ {
+ Keys keys = mock(Keys.class);
+ Set args = new HashSet<>();
+ args.add(URI.create(SCRIPT_INPUT_KEY));
+ when(keys.getKeyedSchemaUris()).thenReturn(args);
+ when(keys.getValue(URI.create(SCRIPT_INPUT_KEY))).thenReturn("Bulwinkle");
+ Dimensions dimensions = mock(Dimensions.class);
+ Document doc = mock(Document.class);
+ when(_Context.newModel(dimensions)).thenReturn(doc);
+ URI scriptSchemaName = URI.create(DEEP_SET_SCRIPT_NAME);
+ when(dimensions.getSchemaUri()).thenReturn(scriptSchemaName);
+ Model model = _Service.get(keys, dimensions);
+
+ // Assert the model has what we hope
+ assertTrue(model.equals(doc));
+ verify(doc, times(1)).setSecondsToLive(0L);
+ model = _Service.get(keys, dimensions);
+
+ // Assert the model has what we hope
+ assertTrue(model.equals(doc));
+ verify(doc, times(1)).setSecondsToLive(1L);
+ model = _Service.get(keys, dimensions);
+
+ // Assert the model has what we hope
+ assertTrue(model.equals(doc));
+ verify(doc, times(1)).setSecondsToLive(2L);
+ model = _Service.get(keys, dimensions);
+
+ // Assert the model has what we hope
+ assertTrue(model.equals(doc));
+ verify(doc, times(1)).setSecondsToLive(3L);
+ }
+
+ @Test
+ public void testClearTemplates()
+ {
+ Map templates = _Service.getTemplates();
+ assertTrue(templates.isEmpty());
+
+ testGetSet();
+
+ assertTrue(templates.size() == 1);
+
+ _Service.clearTemplates();
+
+ assertTrue(templates.size() == 0);
+ }
+
+
+ // TODO: Reuse this from ServletTest base class
+ protected ServiceConfiguration createServiceConfiguration()
+ {
+
+ return createServiceConfiguration(null);
+ }
+
+ // TODO: Reuse this from ServletTest base class
+ protected ServiceConfiguration createServiceConfiguration(final Map props)
+ {
+
+ final DefaultServiceConfiguration defaultServiceConfiguration = new DefaultServiceConfiguration();
+ final SortedMap settings = new TreeMap<>();
+
+ if (props != null)
+ {
+ settings.putAll(props);
+ }
+
+ defaultServiceConfiguration.setSettings(settings);
+ return defaultServiceConfiguration;
+ }
+
+}
diff --git a/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/Deeper.groovy b/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/Deeper.groovy
new file mode 100644
index 0000000..7d9fea0
--- /dev/null
+++ b/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/Deeper.groovy
@@ -0,0 +1,11 @@
+package org.wrml.contrib.runtime.service.groovy.groovyTemplates
+
+class Deeper
+{
+ long count = 0L
+
+ long getAndIncCount()
+ {
+ return count++
+ }
+}
\ No newline at end of file
diff --git a/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/ExampleConfig.groovy b/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/ExampleConfig.groovy
new file mode 100644
index 0000000..d4f4163
--- /dev/null
+++ b/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/ExampleConfig.groovy
@@ -0,0 +1,4 @@
+def static getAddress()
+{
+ 8L
+}
diff --git a/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/Server.groovy b/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/Server.groovy
new file mode 100644
index 0000000..47cab43
--- /dev/null
+++ b/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/Server.groovy
@@ -0,0 +1,57 @@
+class Server implements org.wrml.contrib.runtime.service.groovy.GroovyServiceInterface
+{
+ def callCount = 0;
+ def cache = new java.util.HashMap()
+
+ // Introspection Methods
+ def getCallCount()
+ {
+ return callCount
+ }
+
+ def getCache()
+ {
+ return cache
+ }
+
+ // Service methods
+ def void delete(org.wrml.runtime.Context context, org.wrml.runtime.Keys keys)
+ {
+ callCount++
+ def keyURIs = keys.getKeyedSchemaUris()
+
+ for (uri in keyURIs)
+ {
+ def key = keys.getValue(uri)
+ cache.remove(key)
+ }
+ }
+
+ //def get(model, keys, dimensions)
+ def org.wrml.model.Model get(org.wrml.runtime.Context context, org.wrml.model.Model model, org.wrml.runtime.Keys keys, org.wrml.runtime.Dimensions dimensions)
+ {
+ callCount++
+ def key = keys.getValue(model.getSchemaUri())
+
+ if ( cache.containsKey(key) )
+ {
+ return cache[key]
+ }
+
+ return model
+ }
+
+ def void init(java.util.SortedMap map)
+ {
+ println "Doing something awesome..."
+ }
+
+ def save(model)
+ {
+ callCount++
+ def keys = model.getKeys()
+ def key = keys.getValue(model.getSchemaUri())
+ cache[key] = model
+ return model
+ }
+}
diff --git a/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/TTL.groovy b/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/TTL.groovy
new file mode 100644
index 0000000..dbad5d6
--- /dev/null
+++ b/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/TTL.groovy
@@ -0,0 +1,14 @@
+import org.wrml.model.Model
+import org.wrml.runtime.Context
+import org.wrml.runtime.Dimensions
+import org.wrml.runtime.Keys
+import org.wrml.contrib.runtime.service.groovy.GroovyTemplate
+
+class Hello implements GroovyTemplate
+{
+ def Model fill(Context context, Model model, Keys keys, Dimensions dimensions)
+ {
+ model.setSecondsToLive(8L)
+ return model
+ }
+}
diff --git a/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/TTLDeep.groovy b/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/TTLDeep.groovy
new file mode 100644
index 0000000..da4a3f5
--- /dev/null
+++ b/contrib/runtime/service/groovy/src/test/resources/org/wrml/contrib/runtime/service/groovy/groovyTemplates/TTLDeep.groovy
@@ -0,0 +1,22 @@
+import org.wrml.model.Model
+import org.wrml.runtime.Context
+import org.wrml.runtime.Dimensions
+import org.wrml.runtime.Keys
+import org.wrml.contrib.runtime.service.groovy.GroovyTemplate
+import org.wrml.contrib.runtime.service.groovy.groovyTemplates.Deeper
+
+class TTLDeeper implements GroovyTemplate
+{
+ def deeper
+
+ TTLDeeper()
+ {
+ deeper = new Deeper()
+ }
+
+ def Model fill(Context context, Model model, Keys keys, Dimensions dimensions)
+ {
+ model.setSecondsToLive(deeper.getAndIncCount())
+ return model
+ }
+}
\ No newline at end of file
diff --git a/contrib/runtime/service/mongo/.gitignore b/contrib/runtime/service/mongo/.gitignore
new file mode 100644
index 0000000..42eda58
--- /dev/null
+++ b/contrib/runtime/service/mongo/.gitignore
@@ -0,0 +1,7 @@
+target
+bin
+logs
+.classpath
+.project
+.settings
+dependency-reduced-pom.xml
diff --git a/contrib/runtime/service/mongo/Werminal.json b/contrib/runtime/service/mongo/Werminal.json
new file mode 100644
index 0000000..3923978
--- /dev/null
+++ b/contrib/runtime/service/mongo/Werminal.json
@@ -0,0 +1,3 @@
+{
+ "title" : "Werminal"
+}
\ No newline at end of file
diff --git a/contrib/runtime/service/mongo/mongo.iml b/contrib/runtime/service/mongo/mongo.iml
new file mode 100644
index 0000000..a2c1251
--- /dev/null
+++ b/contrib/runtime/service/mongo/mongo.iml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contrib/runtime/service/mongo/pom.xml b/contrib/runtime/service/mongo/pom.xml
new file mode 100644
index 0000000..8d88256
--- /dev/null
+++ b/contrib/runtime/service/mongo/pom.xml
@@ -0,0 +1,116 @@
+
+ 4.0.0
+
+ org.wrml.contrib.runtime
+ service
+ 1.0-SNAPSHOT
+
+
+
+ Mark Masse (OSS project WRML.org)
+ http://www.wrml.org
+
+
+ org.wrml.contrib.runtime.service
+ mongo
+ wrml-contrib-runtime-service-mongo
+ The mongoDB NoSQL mongoDatabase as a WRML service. See also: http://www.mongodb.org
+
+
+
+
+ org.wrml
+ core
+
+
+ org.wrml
+ core
+ test-jar
+ test
+
+
+
+
+ ch.qos.logback
+ logback-classic
+ provided
+
+
+
+
+ org.mongodb
+ mongo-java-driver
+
+
+
+
+ junit
+ junit
+ test
+
+
+ org.mockito
+ mockito-all
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-eclipse-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+