diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 149242e9..00000000 --- a/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -/.classpath -/.project -.settings/ -.gradle -build -target/ -/log.roo - -/bin/ -/*.log - -/.idea -/*.iml -/*.ipr -/*.iws -out -.gradletasknamecache diff --git a/.springBeans b/.springBeans deleted file mode 100644 index 7d843d92..00000000 --- a/.springBeans +++ /dev/null @@ -1,14 +0,0 @@ - - - 1 - - - - - - - src/test/resources/META-INF/spring/spring-shell-plugin.xml - - - - diff --git a/README.asciidoc b/README.asciidoc deleted file mode 100644 index 95e9eb3d..00000000 --- a/README.asciidoc +++ /dev/null @@ -1,88 +0,0 @@ -:currentReleaseVersion: 1.1.0.RELEASE -:currentSnapshotVersion: 1.2.0.BUILD-SNAPSHOT - -Spring Shell is an shell skeleton that can be easily extended with commands using a Spring based programming model. Spring Shell eases the creation of interactive console applications, featuring ANSI coloring, TAB completion, history browsing, _etc._ - -To witness possibilities of Spring Shell, have a look at the http://docs.spring.io/spring-xd/docs/current-SNAPSHOT/reference/html/#interactive-shell[Spring XD Shell]. - -The latest release version is {currentReleaseVersion}, while the development version is {currentSnapshotVersion}. - -# Useful links - -* http://static.springsource.org/spring-shell/docs/current/reference/[User documentation] -* https://jira.spring.io/browse/SHL[Issue Tracker] - -# Artifacts - -[filter=source,language=xml,subs="attributes,specialcharacters"] ----- - - - - spring-release - Spring Maven RELEASE Repository - http://repo.springframework.org/release - - - - - libs-release - Spring Maven libs-release Repository - http://repo.springframework.org/libs-release - - - - org.springframework.shell - spring-shell - {currentReleaseVersion} - - - - - - spring-snapshot - Spring Maven SNAPSHOT Repository - http://repo.springframework.org/libs-snapshot - - - - org.springframework.shell - spring-shell - {currentSnapshotVersion} - ----- - - -* Gradle: - -[subs="attributes,specialcharacters"] ----- -repositories { - maven { url "http://repo.springsource.org/lib-release" } -} - -dependencies { - compile "org.springframework.shell:spring-shell:{currentReleaseVersion}" -} ----- - -# Building -Spring Shell is built with Gradle. To build Spring Shell, run - - ./gradlew - -# Running Example - - cd samples/helloworld - ./gradlew installApp - cd build/install/helloworld/bin - helloworld - - -# Contributing - -Here are some ways for you to get involved in the community: - -* Get involved with the Spring community on Stack Overflow. Please help out on the http://stackoverflow.com/questions/tagged/spring-shell[dedicated SO tag] by responding to questions and joining the debate. -* Create https://jira.spring.io/browse/SHL[JIRA] tickets for bugs and new features and comment and vote on the ones that you are interested in. -Github is for social coding: if you want to write code, we encourage contributions through pull requests from http://help.github.com/forking/[forks of this repository]. If you want to contribute code this way, please reference a JIRA tracker ticket covering the specific issue you are addressing. Before we accept a non-trivial patch or pull request we will need you to sign the https://support.springsource.com/spring_committer_signup[contributor's agreement]. Signing the contributor's agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. Active contributors might be asked to join the core team, and given the ability to merge pull requests. diff --git a/build.gradle b/build.gradle deleted file mode 100644 index a2888a36..00000000 --- a/build.gradle +++ /dev/null @@ -1,220 +0,0 @@ -buildscript { - repositories { - maven { url 'http://repo.springsource.org/plugins-release' } - } - dependencies { - classpath 'io.spring.gradle:docbook-reference-plugin:0.3.1' - classpath 'org.springframework.build.gradle:spring-io-plugin:0.0.3.RELEASE' - } -} - -description = 'Spring Shell' -group = 'org.springframework.shell' - -repositories { - mavenCentral() - maven { url "http://repo.springsource.org/libs-snapshot" } - maven { url "http://repo.springsource.org/plugins-release" } -} - -apply plugin: "java" -apply plugin: 'eclipse' -apply plugin: 'idea' -apply from: "$rootDir/maven.gradle" -apply plugin: 'docbook-reference' -apply plugin: 'application' - -if (project.hasProperty('platformVersion')) { - apply plugin: 'spring-io' - - repositories { - maven { url "https://repo.spring.io/libs-snapshot" } - } - - dependencies { - springIoVersions "io.spring.platform:platform-versions:${platformVersion}@properties" - } -} - -[compileJava, compileTestJava]*.options*.compilerArgs = ["-Xlint:-serial", "-Xlint:unchecked", "-Xlint:rawtypes"] - -[compileJava, compileTestJava]*.options*.encoding = "UTF-8" - -dependencies { - compile "org.springframework:spring-core:$springVersion" - compile "org.springframework:spring-context-support:$springVersion" - compile "commons-io:commons-io:$commonsioVersion" - compile "jline:jline:$jlineVersion" - - - // Testing - testCompile "junit:junit:$junitVersion" - testCompile "org.mockito:mockito-core:$mockitoVersion" - testCompile "org.hamcrest:hamcrest-library:$hamcrestVersion" -} - -sourceCompatibility = 1.6 -targetCompatibility = 1.6 - -javadoc { - ext.srcDir = file("${projectDir}/docs/src/api") - destinationDir = file("${buildDir}/api") - ext.tmpDir = file("${buildDir}/api-work") - - configure(options) { - encoding = "UTF-8" - stylesheetFile = file("${srcDir}/spring-javadoc.css") - overview = "${srcDir}/overview.html" - docFilesSubDirs = true - outputLevel = org.gradle.external.javadoc.JavadocOutputLevel.QUIET - breakIterator = true - showFromProtected() - groups = [ - 'Spring Shell' : ['org.springframework.shell*'], - ] - - links = [ - "http://static.springframework.org/spring/docs/3.1.x/javadoc-api", - "http://download.oracle.com/javase/6/docs/api", - ] - - //exclude "org/springframework/data/redis/config/**" - if (JavaVersion.current().isJava8Compatible()) { - options.addStringOption('Xdoclint:none', '-quiet') - } - } - - title = "${rootProject.description} ${version} API" -} - - -jar { - manifest.attributes['Implementation-Title'] = 'spring-shell' - manifest.attributes['Implementation-Version'] = project.version - - from("$rootDir/docs/src/info") { - include "license.txt" - include "notice.txt" - into "META-INF" - expand(copyright: new Date().format('yyyy'), version: project.version) - } -} - -task sourcesJar(type: Jar, dependsOn:classes) { - classifier = 'sources' - from sourceSets.main.allJava -} - -task javadocJar(type: Jar) { - classifier = 'javadoc' - from javadoc -} - -reference { - sourceDir = file('docs/src/reference/docbook') -} - - -task docsZip(type: Zip) { - group = 'Distribution' - classifier = 'docs' - description = "Builds -${classifier} archive containing api and reference for deployment" - - from('docs/src/info') { - include 'changelog.txt' - } - - from (javadoc) { - into 'api' - } - - from (reference) { - into 'reference' - } -} - -task schemaZip(type: Zip) { - group = 'Distribution' - classifier = 'schema' - description = "Builds -${classifier} archive containing all XSDs for deployment" - - def Properties schemas = new Properties(); - - sourceSets.main.resources.find { - it.path.endsWith('META-INF' + File.separator + 'spring.schemas') - }?.withInputStream { schemas.load(it) } - - ext.paths = [] as Set - - for (def key : schemas.keySet()) { - def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1') - assert shortName != key - File xsdFile = sourceSets.main.resources.find { - it.path.replace('\\', '/').endsWith(schemas.get(key)) - } - assert xsdFile != null - def input = xsdFile.path - - if (!paths.contains(input)) { - paths.add(input) - into (shortName) { - from input - } - } - } -} - -task distroZip(type: Zip, dependsOn: [jar, docsZip, sourcesJar, javadocJar]) { - group = 'Distribution' - classifier = 'dist' - description = "Builds -${classifier} archive, containing all jars and docs, " + - "suitable for community download page." - - ext.zipRootDir = "${project.name}-${project.version}" - - into (zipRootDir) { - from('docs/src/info') { - include 'readme.txt' - include 'license.txt' - include 'notice.txt' - expand(copyright: new Date().format('yyyy'), version: project.version) - } - - from('samples/') { - into 'samples' - exclude '.gradle/' - exclude 'build/' - } - - from(zipTree(docsZip.archivePath)) { - into "docs" - } - -// from(zipTree(schemaZip.archivePath)) { -// into "schema" -// } - into ("dist") { - from rootProject.collect { project -> project.libsDir } - } - } -} - -artifacts { - archives sourcesJar - archives javadocJar - - archives docsZip -// archives schemaZip - archives distroZip -} - -task wrapper(type: Wrapper) { - description = 'Generates gradlew[.bat] scripts' - gradleVersion = '2.10' -} - - -mainClassName = "org.springframework.shell.Bootstrap" - -assemble.dependsOn = ['jar', 'sourcesJar'] -defaultTasks 'build' diff --git a/docs/src/api/doc-files/th-background.png b/docs/src/api/doc-files/th-background.png deleted file mode 100644 index 72d65e77..00000000 Binary files a/docs/src/api/doc-files/th-background.png and /dev/null differ diff --git a/docs/src/api/overview.html b/docs/src/api/overview.html deleted file mode 100644 index 6bf9f535..00000000 --- a/docs/src/api/overview.html +++ /dev/null @@ -1,24 +0,0 @@ - - -This document is the API specification for the Spring Shell project. -
- -
- -

- If you are interested in commercial training, consultancy and - support for the Spring Shell project, - SpringSource provides - such commercial support. -

-
- - \ No newline at end of file diff --git a/docs/src/api/spring-javadoc.css b/docs/src/api/spring-javadoc.css deleted file mode 100644 index 1f009c4b..00000000 --- a/docs/src/api/spring-javadoc.css +++ /dev/null @@ -1,48 +0,0 @@ -/* Spring-specific Javadoc style sheet rules */ - -#overviewBody { - -} - -.code { - border: 1px solid black; - background-color: #F4F4F4; - padding: 5px; -} - -/* Vanilla Javadoc style sheet rules */ - -body { - font-family: Helvetica, Arial, sans-serif; - background-color: white; - font-size: 10pt; -} - -td { font-size: 10pt; font-family: Helvetica, Arial, sans-serif }/* Javadoc style sheet */ - -/* Define colors, fonts and other style attributes here to override the defaults */ - -/* Page background color */ -body { background-color: #FFFFFF } - -/* Headings */ -h1 { font-size: 145% } - -/* Table colors */ -.TableHeadingColor { background: #CCCCFF } /* Dark mauve */ -.TableSubHeadingColor { background: #EEEEFF } /* Light mauve */ -.TableRowColor { background: #FFFFFF } /* White */ - -/* Font used in left-hand frame lists */ -.FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif } -.FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } -.FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif } - -/* Navigation bar fonts and colors */ -.NavBarCell1 { background-color:#EEEEFF;} /* Light mauve */ -.NavBarCell1Rev { background-color:#00008B;} /* Dark Blue */ -.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;} -.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;} - -.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;} -.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;} diff --git a/docs/src/info/changelog.txt b/docs/src/info/changelog.txt deleted file mode 100644 index a05d0bed..00000000 --- a/docs/src/info/changelog.txt +++ /dev/null @@ -1,175 +0,0 @@ -SPRING SHELL CHANGELOG -====================== -http://www.springsource.org/spring-shell - -Commit changelog: http://github.com/SpringSource/spring-shell/tree/[version] -Issues changelog: http://jira.springsource.org/secure/ReleaseNote.jspa?projectId=10361 - -Changes in version 1.1.0 RELEASE (2014-7-25) -------------------------------------- - -No changes - -Changes in version 1.1 RC4 (2014-7-8) -------------------------------------- -** Bug -* [SHL-138] - Support unquoted doublequotes inside singles, and vice versa -* [SHL-140] - Fix completions for the "help" builtin command -* [SHL-153] - Date command should assume user localization. - -** Improvement -* [SHL-136] - Shell should indicate error location with a caret when possible -* [SHL-155] - Expose number of times the TAB key has been hit in completion - -** Task -* [SHL-154] - Update DateCommand test - - -Changes in version 1.1 RC3 (2014-5-16) --------------------------------------- -** Bug -* [SHL-140] - Fix completions for the "help" builtin command - -** Improvement -* [SHL-134] - Grab the entire input line as parameter to CliCommand -* [SHL-139] - Add support for common escapes -* [SHL-143] - Upgrade to gradle 1.11 -* [SHL-149] - Upgrad to Spring Framework 4 - -Changes in version 1.1 RC2 (2014-4-15) --------------------------------------- -** Bug -* [SHL-133] - Shell command "! ls /tmp" fails -* [SHL-135] - Key-less option corner case - -Changes in version 1.1 RC1 (2014-4-2) -------------------------------------- - -** Bug -* [SHL-84] - Shell cannot deal with "-" in CliOption keys -* [SHL-85] - Argument completion broken when default value present -* [SHL-107] - Prompt not re-evaluated if the user input is just an "enter" command. -* [SHL-116] - Support quotes escaping -* [SHL-119] - Remove unused bright color constants -* [SHL-120] - Add @Inherited and @Documented to the annotations -* [SHL-122] - --key --foo thinks "--foo" is a value, even if --key has a default - -** Improvement -* [SHL-74] - Switch JLine dependency to an official JLine version -* [SHL-80] - ability to disable built-in commands -* [SHL-91] - Applications built with spring-shell are required to inherit comment commands -* [SHL-125] - Some documentation fixes - -** New Feature -* [SHL-126] - Add utility classes for rendering ascii based tables - -** Task -* [SHL-118] - Rename JLineCompletorAdapter to ParserCompleter -* [SHL-128] - Change version of spring shell in hello world application to 1.1 RC1 -* [SHL-130] - Release 1.1 RC1 - -Release Notes - Spring Shell - Version 1.1 M1 - - -Changes in version 1.1 M1 (2013-7-26) -------------------------------------- - -** Bug -* [SHL-47] - Invesitgate if SimpleFileConverter should be used or incorporated in FileConverter -* [SHL-72] - DefaultBannerProvider welcome message mentions non-existent 'hint' command -* [SHL-87] - sample app not working anymore -* [SHL-114] - After initial creation, the plugin's ApplicationContext is refreshed one time too often - - - -** Improvement -* [SHL-68] - Make help for built-in commands consistent -* [SHL-69] - Extract "version" command from AbstractShell -* [SHL-70] - Add a command to clear the console -* [SHL-71] - Reference docs do not mention PluginProvider interface -* [SHL-73] - Typo in reference docs: CliOptions iso CliOption -* [SHL-75] - Change repository used to pull in custom jline dependency in sample application -* [SHL-77] - Update the build to use later versions of JUnit and SLF4J -* [SHL-78] - Add an if check in JLineShellComponent's stop method. -* [SHL-79] - Update gradle wrapper to 1.2 -* [SHL-82] - Improve detection of apple terminal -* [SHL-86] - Change bootstrapping procedure so JLineShellComponent can resolve its own dependencies. -* [SHL-92] - Decoupled commands 'date' and 'system properties' from AbstractShell -* [SHL-93] - Decouple script command from AbstractShell -* [SHL-100] - Rename PluginProvider to NamedProvider and name() method to getProviderName() -* [SHL-101] - Add top level ShellException -* [SHL-102] - Remove parent/child context hierarchy -* [SHL-104] - Remove compiler warnings -* [SHL-105] - Add option to run helloworld example as a gradle run task - -** New Feature -* [SHL-66] - Plugins should have access to command line options -* [SHL-103] - Create simple way to test the execution of shell commands - - -Changes in version 1.0 RELEASE (2012-10-02) -------------------------------------------- - -** Bug -* [SHL-62] - customized prompt doesn't works - - - -** Improvement -* [SHL-63] - sample moved from Maven to Gradle -* [SHL-111] - Change prompt during running application - - -Changes in version 1.0 RC1 (2012-09-20) ---------------------------------------- - -** Bug -* [SHL-14] - History from previous session is not loaded into JLine history buffer -* [SHL-48] - Remove duplicated classes from Spring Framework and old Roo code base in util package -* [SHL-52] - Missing Maven dependency JLine -* [SHL-60] - Jansi terminal support not working under cygwin -* [SHL-61] - Remove unused Hint classes - -** Improvement -* [SHL-53] - Documentation Corrections -* [SHL-54] - Dynamic prompt -* [SHL-57] - Miscellaneous documentation cleanup - -** New Feature -* [SHL-55] - ascii art/text should be loaded from a file -* [SHL-56] - SHL contains a lot of duplicated classes from Spring - -** Task -* [SHL-51] - Correct Maven groupId - - -Changes in version 1.0 M1 (2012-07-18) --------------------------------------- - -* Moved Spring Roo code into Spring Shell, removing OSGi dependency - -** New Feature -* [SHL-12] - Allow shell comnand prompt text to be customized by plugins -* [SHL-13] - Allow name of history file to be customized by plugins -* [SHL-40] - Provide an interception mechanism for the command class to intercept invocation of command methods - -** Improvement -* [SHL-24] - Should not ignore the optional parameter if no parameter value is set in the command -* [SHL-31] - Move providers & ApplicationContext to JLineShellComponent from JLineShell. -* [SHL-32] - Sub-classes of AbstractShell should be able to handle results of execution as required. -* [SHL-39] - Remove NAPA specific environment option, replace with Spring 3.1 profile support -* [SHL-41] - Improve error handling for command line options when staring shell - -** Bug -* [SHL-6] - Spring Shell does not support "help" -* [SHL-19] - When running spring shell in the script mode, the output shout not include the Spring Shell interative information -* [SHL-35] - Improve the parsing command line options to gracefully handle invalid values. - -** Task -* [SHL-1] - Change build system to use gradle -* [SHL-4] - Adding a constructor in JlineShell to provide ConsoleReader. -* [SHL-9] - Create Bamboo build project on CI farm -* [SHL-10] - Publish CI builds to springsource maven snapshot repository -* [SHL-23] - Create docbook based reference guide -* [SHL-25] - Enable unit test on CI build -* [SHL-50] - Add sample application diff --git a/docs/src/info/license.txt b/docs/src/info/license.txt deleted file mode 100644 index 261eeb9e..00000000 --- a/docs/src/info/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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 [yyyy] [name of copyright owner] - - 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/docs/src/info/notice.txt b/docs/src/info/notice.txt deleted file mode 100644 index e3343e92..00000000 --- a/docs/src/info/notice.txt +++ /dev/null @@ -1,22 +0,0 @@ - ====================================================================== - == NOTICE file corresponding to section 4 d of the Apache License, == - == Version 2.0, for the Spring Framework distribution. == - ====================================================================== - - This product includes software developed by - the Apache Software Foundation (http://www.apache.org). - - The end-user documentation included with a redistribution, if any, - must include the following acknowledgement: - - "This product includes software developed by the Spring Framework - Project (http://www.springframework.org)." - - Alternately, this acknowledgement may appear in the software itself, - if and wherever such third-party acknowledgements normally appear. - - The names "Spring", "Spring Framework", and "Spring Shell" must - not be used to endorse or promote products derived from this - software without prior written permission. For written permission, - please contact enquiries@springsource.com. - diff --git a/docs/src/info/readme.txt b/docs/src/info/readme.txt deleted file mode 100644 index db1f498e..00000000 --- a/docs/src/info/readme.txt +++ /dev/null @@ -1,26 +0,0 @@ -SPRING SHELL ------------- -https://github.com/spring-projects/spring-shell - -1. INTRODUCTION - -Spring Shell is an interactive shell that can be easily extended with commands using a Spring based programming model. - -2. RELEASE NOTES - -This release comes with complete reference documentation. For further -details, consult the provided javadoc for specific packages and classes. - -3. DISTRIBUTION JAR FILES - -The Spring Shell jar files can be found in the 'dist' directory. - -4. GETTING STARTED - -Please see the reference documentation. -Additionally, consult the blog at https://spring.io/blog as well -as sections of interest in the reference documentation. - -5. ADDITIONAL RESOURCES - -Spring Shell homepage: http://www.springsource.org/spring-shell diff --git a/docs/src/reference/docbook/images/logo.png b/docs/src/reference/docbook/images/logo.png deleted file mode 100644 index a9f6d959..00000000 Binary files a/docs/src/reference/docbook/images/logo.png and /dev/null differ diff --git a/docs/src/reference/docbook/images/shell-arch-overview.png b/docs/src/reference/docbook/images/shell-arch-overview.png deleted file mode 100644 index 5b7f791e..00000000 Binary files a/docs/src/reference/docbook/images/shell-arch-overview.png and /dev/null differ diff --git a/docs/src/reference/docbook/images/shell-example-enum.jpg b/docs/src/reference/docbook/images/shell-example-enum.jpg deleted file mode 100644 index a12af2d4..00000000 Binary files a/docs/src/reference/docbook/images/shell-example-enum.jpg and /dev/null differ diff --git a/docs/src/reference/docbook/images/shell-example.jpg b/docs/src/reference/docbook/images/shell-example.jpg deleted file mode 100644 index 4148897c..00000000 Binary files a/docs/src/reference/docbook/images/shell-example.jpg and /dev/null differ diff --git a/docs/src/reference/docbook/index.xml b/docs/src/reference/docbook/index.xml deleted file mode 100644 index ae9352ba..00000000 --- a/docs/src/reference/docbook/index.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - Spring Shell Documentation - Spring Shell ${version} - ${version} - Spring Shell - - - - Mark - Pollack - SpringSource - - - Costin - Leau - SpringSource - - - Jarred - Li - VMware - - - - - - Copies of this document may be made for your own use and for distribution - to others, provided that you do not charge any fee for such copies and - further provided that each copy contains this Copyright Notice, whether - distributed in print or electronically. - - - - - - - - - - Introduction - - - - - - Reference Documentation - - - - - - Developing Spring Shell Applications - - - - - - Spring Shell Sample application - - - - - \ No newline at end of file diff --git a/docs/src/reference/docbook/introduction/introduction.xml b/docs/src/reference/docbook/introduction/introduction.xml deleted file mode 100644 index f794e8aa..00000000 --- a/docs/src/reference/docbook/introduction/introduction.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - The Spring Shell provides an interactive shell that lets you - contribute commands using a simple Spring based programming model. - - This document is the reference guide for the Spring Shell and covers - the key classes that are part of the Shell infrastructure, the plugin model, - how to create commands for the shell as well as discussion of the sample - application. - diff --git a/docs/src/reference/docbook/introduction/requirements.xml b/docs/src/reference/docbook/introduction/requirements.xml deleted file mode 100644 index 9cf5c3d7..00000000 --- a/docs/src/reference/docbook/introduction/requirements.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - Requirements - - The Spring Shell requires JDK level 6.0 and above as well as the - Spring Framework 3.0 - (3.1 recommended) and above. - diff --git a/docs/src/reference/docbook/preface.xml b/docs/src/reference/docbook/preface.xml deleted file mode 100644 index d9bc1b89..00000000 --- a/docs/src/reference/docbook/preface.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - Preface - - The Spring Shell provides an interactive shell that allows you to - plugin your own custom commands using a Spring based programming - model. - - The shell has been extracted from the Spring Roo - project, giving it a strong foundation and rich feature set. One - significant change from Spring Roo is that the plugin model is no longer - based on OSGi but instead uses the Spring IoC container to discover commands - through classpath scanning. There is currently no classloader isolation - between plugins, however that maybe added in future versions. - - Spring Shell's features include - - - - A simple, annotation driven, programming model to contribute - custom commands - - - - Use of Spring's classpath scanning functionality as the basis for - a command plugin strategy and command development - - - - Inheritance of the Roo - Shell features, most notably tab completion, colorization, and - script execution. - - - - Customization of command prompt, banner, shell history file - name. - - - - This document assumes that the reader already has a basic familiarity - with the Spring Framework. - - While every effort has been made to ensure that this documentation is - comprehensive and there are no errors, nevertheless some topics might - require more explanation and some typos might have crept in. If you do spot - any mistakes or even more serious errors and you can spare a few cycles - during lunch, please do bring the error to the attention of the Spring Shell - team by raising an - issue. - diff --git a/docs/src/reference/docbook/reference/dev-guide/dev-spring-shell.xml b/docs/src/reference/docbook/reference/dev-guide/dev-spring-shell.xml deleted file mode 100644 index 8fee889b..00000000 --- a/docs/src/reference/docbook/reference/dev-guide/dev-spring-shell.xml +++ /dev/null @@ -1,225 +0,0 @@ - - - Developing Spring Shell Applications - - Contributing commands to the shell is very easy. There are only a few - annotations you need to learn. The implementation style of the command is - the same as developing classes for an application that uses dependency - injection. You can leverage all the features of the Spring container to - implement your command classes. - -
- Marker Interface - - The first step to creating a command is to implement the marker - interface CommandMarker and to annotate - your class with Spring's @Component annotation. - (Note there is an open JIRA issue to provide a - @CliCommand meta-annotation to avoid having to use - a marker interface). Using the code from the helloworld sample - application, the code of a HelloWorldCommands class - is shown below: - - @Component -public class HelloWorldCommands implements CommandMarker { - - // use any Spring annotations for Dependency Injection or other Spring interfaces - // as required. - - // methods with @Cli annotations go here - -} -
- -
- Logging - - Logging is currently done using JDK logging. Due to the intricacies - of console, JLine and Ansi handling, it is generally advised to display - messages as return values to the method commands. However, when logging is - required, the typical JDK logger declaration should suffice. - - @Component -public class HelloWorldCommands implements CommandMarker { - - protected final Logger LOG = Logger.getLogger(getClass().getName()); - - // methods with @Cli annotations go here - -} - - - Note: it is the responsibility of the packager/developer to handle logging for third-party libraries. Typically one wants to reduce the logging level so the console/shell does not get affected by logging messages. - -
- -
- CLI Annotations - - There are three annotations used on methods and method arguments - that define the main contract for interacting with the shell. These - are: - - - - CliAvailabilityIndicator - Placed on a - method that returns a boolean value and indicates if a particular - command can be presented in the shell. This decision is usually based - on the history of commands that have been executed previously. It - prevents extraneous commands being presented until some preconditions - are met, for example the execution of a 'configuration' - command. - - - - CliCommand - Placed on a method that - provides a command to the shell. Its value provides one or more - strings that serve as the start of a particular command name. These - must be unique within the entire application, across all - plugins. - - - - CliOption - Placed on the arguments of a - command method, allowing it to declare the argument value as mandatory - or optional with a default value. - - - - Here is a simple use of these annotations in a command class - - @Component -public class HelloWorldCommands implements CommandMarker { - - @CliAvailabilityIndicator({"hw simple"}) - public boolean isCommandAvailable() { - return true; - } - - @CliCommand(value = "hw simple", help = "Print a simple hello world message") - public String simple( - @CliOption(key = { "message" }, mandatory = true, help = "The hello world message") - final String message, - - @CliOption(key = { "location" }, mandatory = false, - help = "Where you are saying hello", specifiedDefaultValue="At work") - final String location) { - - return "Message = [" + message + "] Location = [" + location + "]"; - - } -} - - The method annotated with @CliAvailabilityIndicator - is returning true so that the one and only command in this - class is exposed to the shell to be invoked. If there were more commands - in the class, you would list them as comma separated value. - - The @CliCommand annotation is creating the - command 'hw simple' in the shell. The help message is - what will be printed if you use the build in help - command. The method name is 'simple' but it could - just have been any other name. - - The @CliOption annotation on each of the - command arguments is where you will spend most of your time authoring - commands. You need to decide which arguments are required, which are - optional, and if they are optional is there a default value. In this case - there are two arguments or options to the command: message and location. - The message option is required and a help message is provided to give - guidance to the user when tabbing to get completion for the - command. - - The implementation of the 'simple' method - is trivial, just a log statement, but this is where you would typically - call other collaborating objects that were injected into the class via - Spring. - - The method argument types in this example are - String, which doesn't present any issue with type - conversion. You can specify methods with any rich object type as well as - basic primitive types such as int, float etc. For all types other than - those handled by the shell by default (basic types, - Date, File) you will need to - register your own implementation of the - org.springframework.shell.core.Converter - interface with the container in your plugin. - - Note that the method return argument can be non-void - in our - example, it is the actual message we want to display. Whenever an object - is returned, the shell will display its toString() - representation. -
- -
- Testing shell commands - - To perform a test of the shell commands you can instantiate the shell inside a test case, - execute the command and then perform assertions on the return value CommandResult. - A simple base class to set this up is shown below. - public abstract class AbstractShellIntegrationTest { - - private static JLineShellComponent shell; - - @BeforeClass - public static void startUp() throws InterruptedException { - Bootstrap bootstrap = new Bootstrap(); - shell = bootstrap.getJLineShellComponent(); - } - - @AfterClass - public static void shutdown() { - shell.stop(); - } - - public static JLineShellComponent getShell() { - return shell; - } - -} - Here is an example testing the Date command - public class BuiltInCommandTests extends AbstractShellIntegrationTest { - - @Test - public void dateTest() throws ParseException { - - //Execute command - CommandResult cr = getShell().executeCommand("date"); - - //Get result - DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL,Locale.US); - Date result = df.parse(cr.getResult().toString()); - - //Make assertions - DateMaters is an external dependency not shown here. - Date now = new Date(); - MatcherAssert.assertThat(now, DateMatchers.within(5, TimeUnit.SECONDS, result)); - } -} - The java.lang.Class of CommandResult's getResult method will match that of the return value of - the method annotated with @CliCommand. You should cast to the appropriate type to help perform your assertions. - -
-
- Building and running the shell - - In our opinion, the easiest way to build and execute the shell is to - cut-n-paste the gradle script in the example application. This uses the - application plugin from gradle to create a bin directory with a startup - script for windows and Unix and places all dependent jars in a lib - directory. Maven has a similar plugin - the AppAssembler - plugin. - - The main class of the shell is - org.springframework.shell.Bootstrap. As long as you - place other plugins, perhaps developed independently, on the classpath, - the Bootstrap class will incorporate them into the shell. -
-
diff --git a/docs/src/reference/docbook/reference/dev-guide/introduction.xml b/docs/src/reference/docbook/reference/dev-guide/introduction.xml deleted file mode 100644 index a0f0a240..00000000 --- a/docs/src/reference/docbook/reference/dev-guide/introduction.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - This section provides some guidance on how one can create commands for - the Spring Shell. - diff --git a/docs/src/reference/docbook/reference/introduction.xml b/docs/src/reference/docbook/reference/introduction.xml deleted file mode 100644 index 7bad5ca8..00000000 --- a/docs/src/reference/docbook/reference/introduction.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - This part of the reference documentation explains the core components - of the Spring Shell. - diff --git a/docs/src/reference/docbook/reference/shell.xml b/docs/src/reference/docbook/reference/shell.xml deleted file mode 100644 index a4d01b18..00000000 --- a/docs/src/reference/docbook/reference/shell.xml +++ /dev/null @@ -1,312 +0,0 @@ - - - Spring Shell - - The core components of the shell are its plugin model, built-in - commands, and converters. - -
- Plugin Model - - The plugin model is based on Spring. Each plugin jar is required to - contain the file - META-INF/spring/spring-shell-plugin.xml. These files - will be loaded to bootstrap a Spring - ApplicationContext when the shell is - started. The essential boostrapping code that looks for your contributions - looks like this: new ClassPathXmlApplicationContext("classpath*:/META-INF/spring/spring-shell-plugin.xml"); - - In the spring-shell-plugin.xml file you should - define the command classes and any other collaborating objects that - support the command's actions. The plugin model is depicted in the - following diagram - - - - - - - - - - - Note that the current plugin model loads all plugins under the same - class loader. An open JIRA issue - suggests providing a classloader per plugin to provide isolation. - -
- Commands - - An easy way to declare the commands is to use Spring's component - scanning functionality. Here is an example - spring-shell-plugin.xml from the sample - application: - - <beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:context="http://www.springframework.org/schema/context" - xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-3.1.xsd"> - - <context:component-scan - base-package="org.springframework.shell.samples.helloworld.commands" /> - -</beans> - - The commands are Spring components, demarcated as such using the - @Component annotation. For example, the shell of the - HelloWorldCommands class from the sample - application looks like this - - @Component -public class HelloWorldCommands implements CommandMarker { - - // use any Spring annotations for Dependency Injection or other Spring - // interfaces as required. - - // methods with @Cli annotations go here - -} - - Once the commands are registered and instantiated by the Spring - container, they are registered with the core shell parser so that the - @Cli annotations can be processed. The way the - commands are identified is through the use of the - CommandMarker interface. -
- -
- Converters - - The - org.springframework.shell.core.Converter - interface provides the contract to convert the strings that are entered - on the command line to rich Java types passed into the arguments of - @Cli-annotated methods. - - By default converters for common types are registered. These cover - primitive types (boolean, int, float...) as well as Date, Character, and - File. - - If you need to register any additional - Converter instances, register them with - the Spring container in the - spring-shell-plugin.xml file and they will be - picked up automatically. -
-
- -
- Built in commands - - There are a few built in commands. Here is a listing of their class - name and functionality - - - - ConsoleCommands - - clr and clear - to clear the console. - - - - DateCommands - - date - show the current date and time. - - - - ExitCommands - - exit and quit - to exit the - shell. - - - - HelpCommands - help - - list all commands and their usage - - - - InlineCommentCommands - // and ; shows the valid characters to use for inline comments - - - - OsCommands - the keyword for this command - is the exclamation point, !. After the exclamation - point you can pass in a unix/windows command string to be - executed. - - - - SystemPropertyCommands - system properties- shows the shell's system properties - - - - VersionCommands - version- shows the shell's version - - - - - There are two commands in provided by the - AbstractShell class related to useage of block comments - - - - - /* and */- The begin and end characters for block comments - - - -
- -
- Customizing the shell - - There are a few extension points that allow you to customize the - shell. The extension points are the interfaces - - - - BannerProvider - Specifies the - banner text, welcome message, and version number that will be - displayed when the shell is started - - - - PromptProvider - Specifies the - command prompt text, eg. "shell>" or - "#" or "$". This will be called - after every command execution so it does not need to be a static - string. - - - - HistoryFileNameProvider - - Specifies the name of the command history file - - - - There is a default implementation for these interfaces but you - should create your own implementations for your own shell application. - All of these interfaces extend from - NamedProvider. Use - Spring's @Order annotation to set the priority of the - provider. This allows your provider implementations to take precedence - over any other implementations that maybe present on the classpath from - other plugins. - - To make cool "ASCII art" - banners the website http://patorjk.com/software/taag - is quite neat! -
- -
- Communicating between plugins - - As this is a standard Spring application you can use Spring's - ApplicationContext event infrastructure to - communicate across plugins. -
- -
- Command method interception - - It has shown to be useful to provide a simple form of interception - around the invocation of a command method. This enables the command class - to check for updates to state, such as configuration information modified - by other plugins, before the command method is executed. The interface - ExecutionProcessor should be implemented - instead of CommandMarker to access this - functionality. The ExecutionProcessor - interface is shown below - - public interface ExecutionProcessor extends CommandMarker { - - /** - * Method called before invoking the target command (described by {@link ParseResult}). - * Additionally, for advanced cases, the parse result itself effectively changing the - * invocation calling site. - * - * @param invocationContext target command context - * @return the invocation target - */ - ParseResult beforeInvocation(ParseResult invocationContext); - - /** - * Method called after successfully invoking the target command (described by - * {@link ParseResult}). - * - * @param invocationContext target command context - * @param result the invocation result - */ - void afterReturningInvocation(ParseResult invocationContext, Object result); - - /** - * Method called after invoking the target command (described by {@link ParseResult}) - * had thrown an exception . - * - * @param invocationContext target command context - * @param thrown the thrown object - */ - void afterThrowingInvocation(ParseResult invocationContext, Throwable thrown); - -} -
- -
- Command line options - - There are a few command line options that can be specified when - starting the shell. They are - - - - --profiles - Specifies values for the system - property spring.profiles.active so that Spring 3.1 and greater profile - support is enabled. - - - - --cmdfile - Specifies a file to read that - contains shell commands - - - - --histsize - Specifies the maximum number of - lines to store in the command history file. Default value is - 3000. - - - - --disableInternalCommands - Flag that disables all commands that would - be pre-registered with the shell. There is no argument to this option. You can selectively add - back any internal commands by referencing them in your shell plugin file. Look at the - Spring Shell javadocs for specific commands located in the - org.springframework.shell.commands package as well as the section in this documentation - of Built in commands. - - -
- -
- Scripts and comments - - Scripts can be executed either by passing in the - --cmdfile argument at startup or by executing the - script command inside the shell. When using scripts it - helps to add comments and this can be done using block comments that start - and end with /* and */ or an inline - one line comment using the // or ; - characters. -
-
diff --git a/docs/src/reference/docbook/samples/introduction.xml b/docs/src/reference/docbook/samples/introduction.xml deleted file mode 100644 index fba417d0..00000000 --- a/docs/src/reference/docbook/samples/introduction.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - This part of the reference documentation covers the sample - applications included with Spring Shell that demonstrate the features in a - code centric manner. - - Describes a simple Spring Shell - application that echo's the command parameters to the console. - diff --git a/docs/src/reference/docbook/samples/simple-application.xml b/docs/src/reference/docbook/samples/simple-application.xml deleted file mode 100644 index 83533603..00000000 --- a/docs/src/reference/docbook/samples/simple-application.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - Simple sample application using the Spring Shell - -
- Introduction - - The sample application named 'helloworld' contains three - 'hw' commands, they are 'hw simple', - 'hw complex' and 'hw enum' and - demonstrate simple to intermediate level usage of the - @Cli annotation classes for creating commands. - - The example code is located in the distribution directory - <spring-shell-install-dir>/samples/helloworld. - - To build the example cd to the helloworld directory and execute - gradlew installApp (you first need to add the gradlew - gradle wrapper to your path). To run the application cd to - build\install\helloworld\bin and execute the helloworld - script. -
- -
- HelloWorldCommands - - The HelloWorldCommands class is show - below - - package org.springframework.shell.samples.helloworld.commands; - -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.annotation.CliAvailabilityIndicator; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; -import org.springframework.stereotype.Component; - -@Component -public class HelloWorldCommands implements CommandMarker { - - private boolean simpleCommandExecuted = false; - - @CliAvailabilityIndicator({"hw simple"}) - public boolean isSimpleAvailable() { - //always available - return true; - } - - @CliAvailabilityIndicator({"hw complex", "hw enum"}) - public boolean isComplexAvailable() { - if (simpleCommandExecuted) { - return true; - } else { - return false; - } - } - - @CliCommand(value = "hw simple", help = "Print a simple hello world message") - public String simple( - @CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message, - @CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello", specifiedDefaultValue="At work") final String location) { - simpleCommandExecuted = true; - return "Message = [" + message + "] Location = [" + location + "]"; - } - - @CliCommand(value = "hw complex", help = "Print a complex hello world message") - public String hello( - @CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message, - @CliOption(key = { "name1"}, mandatory = true, help = "Say hello to the first name") final String name1, - @CliOption(key = { "name2" }, mandatory = true, help = "Say hello to a second name") final String name2, - @CliOption(key = { "time" }, mandatory = false, specifiedDefaultValue="now", help = "When you are saying hello") final String time, - @CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello") final String location) { - return "Hello " + name1 + " and " + name2 + ". Your special message is " + message + ". time=[" + time + "] location=[" + location + "]"; - } - - @CliCommand(value = "hw enum", help = "Print a simple hello world message from an enumerated value") - public String eenum( - @CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final MessageType message){ - return "Hello. Your special enumerated message is " + message; - } - - enum MessageType { - Type1("type1"), - Type2("type2"), - Type3("type3"); - - private String type; - - private MessageType(String type){ - this.type = type; - } - - public String getType(){ - return type; - } - } -} - - - The use of the @CliAvailabilityIndicator - annotation on two methods, isSimpleAvailable and - isComplexAvailable shows how you can enable the - presence of the 'hw complex' and 'hw - enum' commands only if the 'hw simple' - command was executed. - - Here is an example session showing the behavior. - - - - - - - - - - - The 'hw enum' command shows how the shell - supports the use of an enumeration as command method arguments. - - - - - - - - - -
-
diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index 3c3dbb67..00000000 --- a/gradle.properties +++ /dev/null @@ -1,8 +0,0 @@ -slf4jVersion=1.7.13 -jlineVersion=2.12 -junitVersion=4.12 -springVersion=4.2.4.RELEASE -commonsioVersion=2.4 -hamcrestVersion=1.3 -version=1.2.1.BUILD-SNAPSHOT -mockitoVersion=1.10.19 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index b7612167..00000000 Binary files a/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index b25698f5..00000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Thu Jun 29 11:35:25 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip diff --git a/gradlew b/gradlew deleted file mode 100755 index 91a7e269..00000000 --- a/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index aec99730..00000000 --- a/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/maven.gradle b/maven.gradle deleted file mode 100644 index 40ea7c76..00000000 --- a/maven.gradle +++ /dev/null @@ -1,60 +0,0 @@ -apply plugin: 'maven' - -ext.optionalDeps = [] -ext.providedDeps = [] - -ext.optional = { optionalDeps << it } -ext.provided = { providedDeps << it } - -install { - repositories.mavenInstaller { - customizePom(pom, project) - } -} - -def customizePom(pom, gradleProject) { - pom.whenConfigured { generatedPom -> - // respect 'optional' and 'provided' dependencies - gradleProject.optionalDeps.each { dep -> - generatedPom.dependencies.find { it.artifactId == dep.name }?.optional = true - } - gradleProject.providedDeps.each { dep -> - generatedPom.dependencies.find { it.artifactId == dep.name }?.scope = 'provided' - } - - // eliminate test-scoped dependencies (no need in maven central poms) - generatedPom.dependencies.removeAll { dep -> - dep.scope == 'test' - } - - // add all items necessary for maven central publication - generatedPom.project { - name = gradleProject.description - description = gradleProject.description - url = 'http://github.com/SpringSource/spring-shell' - organization { - name = 'SpringSource' - url = 'http://www.springsource.org/spring-shell' - } - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - scm { - url = 'http://github.com/SpringSource/spring-shell' - connection = 'scm:git:git://github.com/SpringSource/spring-shell' - developerConnection = 'scm:git:git://github.com/SpringSource/spring-shell' - } - developers { - developer { - id = 'markpollack' - name = 'Mark Pollack' - email = 'mpollack@vmware.com' - } - } - } - } -} \ No newline at end of file diff --git a/readme.dev b/readme.dev deleted file mode 100644 index 0c5797cb..00000000 --- a/readme.dev +++ /dev/null @@ -1,32 +0,0 @@ -====================================================================== -DEBUGGING VIA ECLIPSE -====================================================================== - -Most of the time we just use the spring-shell line tool directly -from the command line. This we have found is the fastest approach and -also lets us see exactly what a user would see, including the TAB -completion features. Still, sometimes you have a tricky issue you'd -prefer to work through via the STS/Eclipse debugger. When you do this -you need to be aware that you lose the full capabilities of the shell, -as the JLine library (used for command line parsing) is unable to -fully hook into your operating system's keyboard and ANSI services. -Anyhow, for some issues a debugger is worth the minor price of losing -your full keyboard and colour services! :-) - -To setup debugging, open org.springframework.shell.Bootstrap. -Note it has a Java "main" method. Execute the class using Run As > -Java Application. Note the "Console" tab in Eclipse/STS will open. -Type "quit" then hit enter. Now select Run > Debug Configurations. -Select the Java Application > Bootstrap entry. Click on Arguments -and then add the following VM Arguments: - -*nix machines: - -Djline.terminal=org.springframework.shell.core.IdeTerminal - -Windows machines: - -Djline.WindowsTerminal.directConsole=false - -Djline.terminal=jline.UnsupportedTerminal - -Finally, set the working directory to "Other" and a location on your -disk where you'd like the spring-shell to be loaded. This is usually a -project you're intending to test with. \ No newline at end of file diff --git a/samples/helloworld/.gitignore b/samples/helloworld/.gitignore deleted file mode 100644 index 5d1172ac..00000000 --- a/samples/helloworld/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/.classpath -/.project -.settings/ -target/ -/log.roo -*.log - -/bin/ diff --git a/samples/helloworld/.project b/samples/helloworld/.project deleted file mode 100644 index cdac73f2..00000000 --- a/samples/helloworld/.project +++ /dev/null @@ -1,16 +0,0 @@ - - - helloworld - Spring Shell Example - - - org.eclipse.jdt.core.javanature - - - - org.eclipse.jdt.core.javabuilder - - - - - diff --git a/samples/helloworld/build.gradle b/samples/helloworld/build.gradle deleted file mode 100644 index 8e19f117..00000000 --- a/samples/helloworld/build.gradle +++ /dev/null @@ -1,32 +0,0 @@ -description = 'Spring Shell Example' -apply plugin: 'base' -apply plugin: 'java' -apply plugin: 'eclipse' -apply plugin: 'application' - -repositories { - maven { url "http://repo.springsource.org/libs-milestone" } - maven { url "http://repo.springsource.org/libs-release" } - mavenLocal() - mavenCentral() -} - -dependencies { - compile "org.springframework.shell:spring-shell:$springShellVersion" - testCompile "junit:junit:$junitVersion" - runtime "log4j:log4j:$log4jVersion" -} - -mainClassName = "org.springframework.shell.Bootstrap" - -defaultTasks 'installApp' - -run { - standardInput = System.in -} - -task wrapper(type: Wrapper) { - description = 'Generates gradlew[.bat] scripts' - gradleVersion = '1.2' -} - diff --git a/samples/helloworld/gradle.properties b/samples/helloworld/gradle.properties deleted file mode 100644 index 72634061..00000000 --- a/samples/helloworld/gradle.properties +++ /dev/null @@ -1,7 +0,0 @@ -springShellVersion = 1.2.0.RELEASE -junitVersion = 4.10 -log4jVersion = 1.2.17 -version = 1.0.0.RELEASE - - - diff --git a/samples/helloworld/gradle/wrapper/gradle-wrapper.jar b/samples/helloworld/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 42d9b0e9..00000000 Binary files a/samples/helloworld/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/samples/helloworld/gradle/wrapper/gradle-wrapper.properties b/samples/helloworld/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 0b5aba0e..00000000 --- a/samples/helloworld/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Thu Jul 25 19:49:28 EDT 2013 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.2-bin.zip diff --git a/samples/helloworld/gradlew b/samples/helloworld/gradlew deleted file mode 100755 index 91a7e269..00000000 --- a/samples/helloworld/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/samples/helloworld/gradlew.bat b/samples/helloworld/gradlew.bat deleted file mode 100644 index aec99730..00000000 --- a/samples/helloworld/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/samples/helloworld/pom.xml b/samples/helloworld/pom.xml deleted file mode 100644 index 5e8a03d0..00000000 --- a/samples/helloworld/pom.xml +++ /dev/null @@ -1,101 +0,0 @@ - - 4.0.0 - - org.springframework.shell.samples - helloworld - 1.1.0.RELEASE - jar - - helloworld - http://maven.apache.org - - - 1.2.0.RELEASE - org.springframework.shell.Bootstrap - 1.2.17 - 4.10 - - - - - - org.springframework.shell - spring-shell - ${spring.shell.version} - - - log4j - log4j - ${log4j.version} - - - junit - junit-dep - ${junit.version} - test - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.5 - 1.5 - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/lib - true - true - true - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - false - lib/ - ${jar.mainclass} - - - ${project.version} - - - - - - - - - - - - libs-milestone - http://repo.spring.io/libs-milestone/ - - - libs-release - http://repo.spring.io/libs-release/ - - - diff --git a/samples/helloworld/readme.txt b/samples/helloworld/readme.txt deleted file mode 100644 index 110843b2..00000000 --- a/samples/helloworld/readme.txt +++ /dev/null @@ -1,21 +0,0 @@ -Maven 3: - -1.Build the project - $>mvn package - -2.run spring shell - $>java -jar target/helloworld-1.1.0.RELEASE.jar - - - -Gradle: - -1.Build and install the project - $>./gradlew installApp - -2.run spring shell - $>./build/install/helloworld/bin/helloworld - -or - $>./gradlew -q run - diff --git a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/Main.java b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/Main.java deleted file mode 100644 index 1ce398e3..00000000 --- a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/Main.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.samples.helloworld; - -import java.io.IOException; - -import org.springframework.shell.Bootstrap; - -/** - * Driver class to run the helloworld example. - * - * @author Mark Pollack - * - */ -public class Main { - - /** - * Main class that delegates to Spring Shell's Bootstrap class in order to simplify debugging inside an IDE - * @param args - * @throws IOException - */ - public static void main(String[] args) throws IOException { - Bootstrap.main(args); - - } - -} diff --git a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/HelloWorldCommands.java b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/HelloWorldCommands.java deleted file mode 100644 index 1ef7ac56..00000000 --- a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/HelloWorldCommands.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.springframework.shell.samples.helloworld.commands; - -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.annotation.CliAvailabilityIndicator; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; -import org.springframework.stereotype.Component; - -@Component -public class HelloWorldCommands implements CommandMarker { - - private boolean simpleCommandExecuted = false; - - @CliAvailabilityIndicator({"hw simple"}) - public boolean isSimpleAvailable() { - //always available - return true; - } - - @CliAvailabilityIndicator({"hw complex", "hw enum"}) - public boolean isComplexAvailable() { - if (simpleCommandExecuted) { - return true; - } else { - return false; - } - } - - @CliCommand(value = "hw simple", help = "Print a simple hello world message") - public String simple( - @CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message, - @CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello", specifiedDefaultValue="At work") final String location) { - simpleCommandExecuted = true; - return "Message = [" + message + "] Location = [" + location + "]"; - } - - @CliCommand(value = "hw complex", help = "Print a complex hello world message (run 'hw simple' once first)") - public String hello( - @CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final String message, - @CliOption(key = { "name1"}, mandatory = true, help = "Say hello to the first name") final String name1, - @CliOption(key = { "name2" }, mandatory = true, help = "Say hello to a second name") final String name2, - @CliOption(key = { "time" }, mandatory = false, specifiedDefaultValue="now", help = "When you are saying hello") final String time, - @CliOption(key = { "location" }, mandatory = false, help = "Where you are saying hello") final String location) { - return "Hello " + name1 + " and " + name2 + ". Your special message is " + message + ". time=[" + time + "] location=[" + location + "]"; - } - - @CliCommand(value = "hw enum", help = "Print a simple hello world message from an enumerated value (run 'hw simple' once first)") - public String eenum( - @CliOption(key = { "message" }, mandatory = true, help = "The hello world message") final MessageType message){ - return "Hello. Your special enumerated message is " + message; - } - - enum MessageType { - Type1("type1"), - Type2("type2"), - Type3("type3"); - - private String type; - - private MessageType(String type){ - this.type = type; - } - - public String getType(){ - return type; - } - } -} diff --git a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyBannerProvider.java b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyBannerProvider.java deleted file mode 100644 index 62579c92..00000000 --- a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyBannerProvider.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.samples.helloworld.commands; - -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.shell.plugin.support.DefaultBannerProvider; -import org.springframework.shell.support.util.OsUtils; -import org.springframework.stereotype.Component; - -/** - * @author Jarred Li - * - */ -@Component -@Order(Ordered.HIGHEST_PRECEDENCE) -public class MyBannerProvider extends DefaultBannerProvider { - - public String getBanner() { - StringBuffer buf = new StringBuffer(); - buf.append("=======================================" + OsUtils.LINE_SEPARATOR); - buf.append("* *"+ OsUtils.LINE_SEPARATOR); - buf.append("* HelloWorld *" +OsUtils.LINE_SEPARATOR); - buf.append("* *"+ OsUtils.LINE_SEPARATOR); - buf.append("=======================================" + OsUtils.LINE_SEPARATOR); - buf.append("Version:" + this.getVersion()); - return buf.toString(); - } - - public String getVersion() { - return "1.2.3"; - } - - public String getWelcomeMessage() { - return "Welcome to HelloWorld CLI"; - } - - @Override - public String getProviderName() { - return "Hello World Banner"; - } -} \ No newline at end of file diff --git a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyHistoryFileNameProvider.java b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyHistoryFileNameProvider.java deleted file mode 100644 index 77c745c4..00000000 --- a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyHistoryFileNameProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.samples.helloworld.commands; - -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.shell.plugin.support.DefaultHistoryFileNameProvider; -import org.springframework.stereotype.Component; - -/** - * - * @author Jarred Li - * - */ -@Component -@Order(Ordered.HIGHEST_PRECEDENCE) -public class MyHistoryFileNameProvider extends DefaultHistoryFileNameProvider { - - public String getHistoryFileName() { - return "my.log"; - } - - @Override - public String getProviderName() { - return "My history file name provider"; - } - -} diff --git a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyPromptProvider.java b/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyPromptProvider.java deleted file mode 100644 index ba875c27..00000000 --- a/samples/helloworld/src/main/java/org/springframework/shell/samples/helloworld/commands/MyPromptProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.samples.helloworld.commands; - -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.shell.plugin.support.DefaultPromptProvider; -import org.springframework.stereotype.Component; - -/** - * @author Jarred Li - * - */ -@Component -@Order(Ordered.HIGHEST_PRECEDENCE) -public class MyPromptProvider extends DefaultPromptProvider { - - @Override - public String getPrompt() { - return "hw-shell>"; - } - - - @Override - public String getProviderName() { - return "My prompt provider"; - } - -} diff --git a/samples/helloworld/src/main/resources/META-INF/spring/spring-shell-plugin.xml b/samples/helloworld/src/main/resources/META-INF/spring/spring-shell-plugin.xml deleted file mode 100644 index 9c76b239..00000000 --- a/samples/helloworld/src/main/resources/META-INF/spring/spring-shell-plugin.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/samples/helloworld/src/main/resources/log4j.properties b/samples/helloworld/src/main/resources/log4j.properties deleted file mode 100644 index d43a9859..00000000 --- a/samples/helloworld/src/main/resources/log4j.properties +++ /dev/null @@ -1 +0,0 @@ -log4j.rootCategory=OFF \ No newline at end of file diff --git a/samples/helloworld/src/test/java/org/springframework/shell/samples/hellworld/commands/HelloWorldCommandTests.java b/samples/helloworld/src/test/java/org/springframework/shell/samples/hellworld/commands/HelloWorldCommandTests.java deleted file mode 100644 index e80f9654..00000000 --- a/samples/helloworld/src/test/java/org/springframework/shell/samples/hellworld/commands/HelloWorldCommandTests.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2013 the original author or authors. - * - * 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.springframework.shell.samples.hellworld.commands; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.springframework.shell.Bootstrap; -import org.springframework.shell.core.CommandResult; -import org.springframework.shell.core.JLineShellComponent; - -public class HelloWorldCommandTests { - - @Test - public void testSimple() { - Bootstrap bootstrap = new Bootstrap(); - - JLineShellComponent shell = bootstrap.getJLineShellComponent(); - - CommandResult cr = shell.executeCommand("hw simple --message hello"); - assertEquals(true, cr.isSuccess()); - assertEquals("Message = [hello] Location = [null]", cr.getResult()); - } -} diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index e3da39c3..00000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'spring-shell' diff --git a/src/main/java/org/springframework/shell/Bootstrap.java b/src/main/java/org/springframework/shell/Bootstrap.java deleted file mode 100644 index f948d6cb..00000000 --- a/src/main/java/org/springframework/shell/Bootstrap.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell; - -import java.io.IOException; -import java.util.logging.Logger; - -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.shell.core.ExitShellRequest; -import org.springframework.shell.core.JLineShellComponent; -import org.springframework.shell.core.Shell; -import org.springframework.shell.support.logging.HandlerUtils; -import org.springframework.util.StopWatch; - -/** - * Loads a {@link Shell} using Spring IoC container. - * - * @author Ben Alex (original Roo code) - * @author Mark Pollack - * @author David Winterfeldt - * - */ -public class Bootstrap { - - private final static String[] CONTEXT_PATH = { "classpath*:/META-INF/spring/spring-shell-plugin.xml" }; - - private CommandLine commandLine; - - private GenericApplicationContext ctx; - - public static void main(String[] args) throws IOException { - ExitShellRequest exitShellRequest; - try { - Bootstrap bootstrap = new Bootstrap(args); - exitShellRequest = bootstrap.run(); - } - catch (RuntimeException t) { - throw t; - } - finally { - HandlerUtils.flushAllHandlers(Logger.getLogger("")); - } - - System.exit(exitShellRequest.getExitCode()); - } - - public Bootstrap() { - this(null, CONTEXT_PATH); - } - - public Bootstrap(String[] args) throws IOException { - this(args, CONTEXT_PATH); - } - - public Bootstrap(String[] args, String[] contextPath) { - try { - commandLine = SimpleShellCommandLineOptions.parseCommandLine(args); - } - catch (IOException e) { - throw new ShellException(e.getMessage(), e); - } - - ctx = new GenericApplicationContext(); - ctx.registerShutdownHook(); - configureApplicationContext(ctx); - // built-in commands and converters - ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(ctx); - if (commandLine.getDisableInternalCommands()) { - scanner.scan("org.springframework.shell.converters", "org.springframework.shell.plugin.support"); - } - else { - scanner.scan("org.springframework.shell.commands", "org.springframework.shell.converters", - "org.springframework.shell.plugin.support"); - } - // user contributed commands - XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(ctx); - reader.loadBeanDefinitions(contextPath); - ctx.refresh(); - } - - public ApplicationContext getApplicationContext() { - return ctx; - } - - private void configureApplicationContext(GenericApplicationContext annctx) { - createAndRegisterBeanDefinition(annctx, org.springframework.shell.core.JLineShellComponent.class, "shell"); - annctx.getBeanFactory().registerSingleton("commandLine", commandLine); - } - - protected void createAndRegisterBeanDefinition(GenericApplicationContext annctx, Class clazz, String name) { - RootBeanDefinition rbd = new RootBeanDefinition(); - rbd.setBeanClass(clazz); - DefaultListableBeanFactory bf = (DefaultListableBeanFactory) annctx.getBeanFactory(); - if (name != null) { - bf.registerBeanDefinition(name, rbd); - } - else { - bf.registerBeanDefinition(clazz.getSimpleName(), rbd); - } - } - - public ExitShellRequest run() { - StopWatch sw = new StopWatch("Spring Shell"); - sw.start(); - String[] commandsToExecuteAndThenQuit = commandLine.getShellCommandsToExecute(); - // The shell is used - JLineShellComponent shell = ctx.getBean("shell", JLineShellComponent.class); - ExitShellRequest exitShellRequest; - - if (null != commandsToExecuteAndThenQuit) { - boolean successful = false; - exitShellRequest = ExitShellRequest.FATAL_EXIT; - - for (String cmd : commandsToExecuteAndThenQuit) { - successful = shell.executeCommand(cmd).isSuccess(); - if (!successful) - break; - } - - // if all commands were successful, set the normal exit status - if (successful) { - exitShellRequest = ExitShellRequest.NORMAL_EXIT; - } - } - else { - shell.start(); - exitShellRequest = shell.getExitShellRequest(); - if (exitShellRequest == null) { - // shouldn't really happen, but we'll fallback to this anyway - exitShellRequest = ExitShellRequest.NORMAL_EXIT; - } - shell.waitForComplete(); - } - - ctx.close(); - sw.stop(); - if (shell.isDevelopmentMode()) { - System.out.println("Total execution time: " + sw.getLastTaskTimeMillis() + " ms"); - } - return exitShellRequest; - } - - public JLineShellComponent getJLineShellComponent() { - return ctx.getBean("shell", JLineShellComponent.class); - } -} diff --git a/src/main/java/org/springframework/shell/CommandLine.java b/src/main/java/org/springframework/shell/CommandLine.java deleted file mode 100644 index 1481f37d..00000000 --- a/src/main/java/org/springframework/shell/CommandLine.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell; - - -/** - * Encapsulates the list of argument passed to the shell. - * - * @author Mark Pollack - */ -public class CommandLine { - - private String[] args; - private int historySize; - private String[] shellCommandsToExecute; - private boolean disableInternalCommands; - - /** - * Construct a new CommandLine - * @param args an array of strings from main(String[] args) - * @param historySize the size of this history buffer - * @param shellCommandsToExecute semi-colon delimited list of commands for the shell to execute - */ - public CommandLine(String[] args, int historySize, String[] shellCommandsToExecute) { - this(args,historySize,shellCommandsToExecute, false); - } - - - /** - * Construct a new CommandLine - * @param args an array of strings from main(String[] args) - * @param historySize the size of this history buffer - * @param shellCommandsToExecute semi-colon delimited list of commands for the shell to execute - * @param disableInternalCommands if true, do not load the built-in shell commands - */ - public CommandLine(String[] args, int historySize, String[] shellCommandsToExecute, boolean disableInternalCommands) { - this.args = args; - this.historySize = historySize; - this.shellCommandsToExecute = shellCommandsToExecute; - this.disableInternalCommands = disableInternalCommands; - } - - /** - * Return the command line arguments - * @return the command line arguments - */ - public String[] getArgs() { - return args; - } - - /** - * @return the historySize - */ - public int getHistorySize() { - return historySize; - } - - /** - * @return the shellCommandsToExecute - */ - public String[] getShellCommandsToExecute() { - return shellCommandsToExecute; - } - - /** - * - * @return the disableInternalCommands value - */ - public boolean getDisableInternalCommands() { - return disableInternalCommands; - } - -} diff --git a/src/main/java/org/springframework/shell/ShellException.java b/src/main/java/org/springframework/shell/ShellException.java deleted file mode 100644 index 3caa04d9..00000000 --- a/src/main/java/org/springframework/shell/ShellException.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011-2013 the original author or authors. - * - * 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.springframework.shell; - - -/** - * Shell exception. - * - * @author David Wintefeldt - */ -public class ShellException extends RuntimeException { - - private static final long serialVersionUID = 1123895874463364743L; - - public ShellException() {} - - public ShellException(String message) { - super(message); - } - - public ShellException(Throwable t) { - super(t); - } - - public ShellException(String message, Throwable t) { - super(message, t); - } - -} diff --git a/src/main/java/org/springframework/shell/SimpleShellCommandLineOptions.java b/src/main/java/org/springframework/shell/SimpleShellCommandLineOptions.java deleted file mode 100644 index 6890b0a1..00000000 --- a/src/main/java/org/springframework/shell/SimpleShellCommandLineOptions.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Logger; - -import org.apache.commons.io.FileUtils; -import org.springframework.shell.support.logging.HandlerUtils; - -/** - * Used to pass in command line options to customize the shell on launch - * - * @author vnagaraja - */ -public class SimpleShellCommandLineOptions { - - private static final Logger LOGGER = HandlerUtils.getLogger(SimpleShellCommandLineOptions.class); - public static final int DEFAULT_HISTORY_SIZE = 3000; - String[] executeThenQuit = null; - Map extraSystemProperties = new HashMap(); - int historySize = DEFAULT_HISTORY_SIZE; - boolean disableCommands; - - public static CommandLine parseCommandLine(String[] args) - throws IOException { - if (args == null) { - args = new String[] {}; - } - SimpleShellCommandLineOptions options = new SimpleShellCommandLineOptions(); - List commands = new ArrayList(); - int i = 0; - while (i < args.length) { - String arg = args[i++]; - if (arg.equals("--profiles")) { - try { - String profiles = args[i++]; - options.extraSystemProperties.put("spring.profiles.active", profiles); - } catch (ArrayIndexOutOfBoundsException e) { - LOGGER.warning("No value specified for --profiles option"); - } - } else if (arg.equals("--cmdfile")) { - try { - File f = new File(args[i++]); - commands.addAll(FileUtils.readLines(f)); - } catch (IOException e) { - LOGGER.warning("Could not read lines from command file: " + e.getMessage()); - } catch (ArrayIndexOutOfBoundsException e) { - LOGGER.warning("No value specified for --cmdfile option"); - } - } else if (arg.equals("--histsize")) { - try { - String histSizeArg = args[i++]; - int histSize = Integer.parseInt(histSizeArg); - if (histSize <= 0) { - LOGGER.warning("histsize option must be > 0, using default value of " + DEFAULT_HISTORY_SIZE); - } else { - options.historySize = histSize; - } - } catch (NumberFormatException e) { - LOGGER.warning("Unable to parse histsize value to an integer "); - } catch (ArrayIndexOutOfBoundsException ae) { - LOGGER.warning("No value specified for --histsize option"); - } - } else if (arg.equals("--disableInternalCommands")) { - options.disableCommands = true; - } else if (arg.equals("--help")) { - printUsage(); - System.exit(0); - } else { - i--; - break; - } - } - - StringBuilder sb = new StringBuilder(); - for (; i < args.length; i++) { - if (sb.length() > 0) { - sb.append(" "); - } - sb.append(args[i]); - } - - if (sb.length() > 0) { - String[] cmdLineCommands = sb.toString().split(";"); - for (String s : cmdLineCommands) { - // add any command line commands after the commands loaded from the file - commands.add(s.trim()); - } - } - - if (commands.size() > 0) { - options.executeThenQuit = commands.toArray(new String[commands.size()]); - } - - for (Map.Entry entry : options.extraSystemProperties.entrySet()) { - System.setProperty(entry.getKey(), entry.getValue()); - } - - return new CommandLine(args, options.historySize, options.executeThenQuit, options.disableCommands); - } - - private static void printUsage() { - System.out.println("Usage: --help --histsize [size] --cmdfile [file name] --profiles [comma-separated list of profile names]"); - } -} diff --git a/src/main/java/org/springframework/shell/TerminalSizeAware.java b/src/main/java/org/springframework/shell/TerminalSizeAware.java deleted file mode 100644 index a9fa6d77..00000000 --- a/src/main/java/org/springframework/shell/TerminalSizeAware.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.springframework.shell; - -/** - * To be implemented by command result objects that can adapt to the terminal size when they are being rendered. - * - *

An object which does not implement this interface will simply be rendered by invoking its {@link #toString()} - * method.

- * - * @author Eric Bottard - */ -public interface TerminalSizeAware { - - CharSequence render(int terminalWidth); -} diff --git a/src/main/java/org/springframework/shell/commands/ConsoleCommands.java b/src/main/java/org/springframework/shell/commands/ConsoleCommands.java deleted file mode 100644 index d9d2caac..00000000 --- a/src/main/java/org/springframework/shell/commands/ConsoleCommands.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.commands; - -import static org.fusesource.jansi.Ansi.ansi; - -import org.fusesource.jansi.AnsiConsole; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.stereotype.Component; - -/** - * Commands related to the manipulation of the jline console. - * - * @author Mark Pollack - * - */ -@Component -public class ConsoleCommands implements CommandMarker { - - @CliCommand(value = { "cls", "clear" }, help = "Clears the console") - public void clear() { - AnsiConsole.out().print(ansi().eraseScreen().cursor(0, 0)); - } - -} diff --git a/src/main/java/org/springframework/shell/commands/DateCommands.java b/src/main/java/org/springframework/shell/commands/DateCommands.java deleted file mode 100644 index bc3d11cd..00000000 --- a/src/main/java/org/springframework/shell/commands/DateCommands.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.commands; - -import java.text.DateFormat; -import java.util.Date; -import java.util.Locale; - -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.stereotype.Component; - -/** - * Commands related to the dates - * - */ -@Component -public class DateCommands implements CommandMarker { - - @CliCommand(value = { "date" }, help = "Displays the local date and time") - public String date() { - return DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.getDefault()).format(new Date()); - } - -} diff --git a/src/main/java/org/springframework/shell/commands/ExitCommands.java b/src/main/java/org/springframework/shell/commands/ExitCommands.java deleted file mode 100644 index d0c6dd69..00000000 --- a/src/main/java/org/springframework/shell/commands/ExitCommands.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.commands; - -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.ExitShellRequest; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.stereotype.Component; - -/** - * Commands related to exiting the shell - * - */ -@Component -public class ExitCommands implements CommandMarker { - - @CliCommand(value={"exit", "quit"}, help="Exits the shell") - public ExitShellRequest quit() { - return ExitShellRequest.NORMAL_EXIT; - } - -} diff --git a/src/main/java/org/springframework/shell/commands/HelpCommands.java b/src/main/java/org/springframework/shell/commands/HelpCommands.java deleted file mode 100644 index af0f947b..00000000 --- a/src/main/java/org/springframework/shell/commands/HelpCommands.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.commands; - -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.JLineShellComponent; -import org.springframework.shell.core.SimpleParser; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; -import org.springframework.stereotype.Component; - -/** - * Provides a listing of commands known to the shell. - * - * @author Ben Alex - * @author Mark Pollack - * @author Jarred Li - * - */ -@Component -public class HelpCommands implements CommandMarker, ApplicationContextAware { - - private ApplicationContext ctx; - - @CliCommand(value = "help", help = "List all commands usage") - public void obtainHelp( - @CliOption(key = { "", "command" }, optionContext = "disable-string-converter availableCommands", help = "Command name to provide help for") - String buffer) { - JLineShellComponent shell = ctx.getBean("shell", JLineShellComponent.class); - SimpleParser parser = shell.getSimpleParser(); - parser.obtainHelp(buffer); - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.ctx = applicationContext; - } -} diff --git a/src/main/java/org/springframework/shell/commands/InlineCommentCommands.java b/src/main/java/org/springframework/shell/commands/InlineCommentCommands.java deleted file mode 100644 index ca870626..00000000 --- a/src/main/java/org/springframework/shell/commands/InlineCommentCommands.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.commands; - -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.stereotype.Component; - -/** - * Commands relating to inline comments - * - */ -@Component -public class InlineCommentCommands implements CommandMarker { - - @CliCommand(value = { "//", ";" }, help = "Inline comment markers (start of line only)") - public void inlineComment() {} - -} diff --git a/src/main/java/org/springframework/shell/commands/OsCommands.java b/src/main/java/org/springframework/shell/commands/OsCommands.java deleted file mode 100644 index 67fcb5a7..00000000 --- a/src/main/java/org/springframework/shell/commands/OsCommands.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.commands; - -import java.io.IOException; -import java.util.logging.Logger; - -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; -import org.springframework.shell.support.logging.HandlerUtils; -import org.springframework.stereotype.Component; - -/** - * Command type to allow execution of native OS commands from the Spring Shell. - * - * @author Stefan Schmidt - * @since 1.2.0 - */ -@Component -public class OsCommands implements CommandMarker { - - private static final Logger LOGGER = HandlerUtils - .getLogger(OsCommands.class); - - private OsOperations osOperations = new OsOperationsImpl(); - - @CliCommand(value = "!", help = "Allows execution of operating system (OS) commands") - public void command( - @CliOption(key = { "", "command" }, mandatory = false, specifiedDefaultValue = "", unspecifiedDefaultValue = "", help = "The command to execute") final String command) { - - System.out.println("command is:" + command); - if (command != null && command.length() > 0) { - try { - osOperations.executeCommand(command); - } - catch (final IOException e) { - LOGGER.severe("Unable to execute command " + command + " [" - + e.getMessage() + "]"); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/commands/OsOperations.java b/src/main/java/org/springframework/shell/commands/OsOperations.java deleted file mode 100644 index bba29236..00000000 --- a/src/main/java/org/springframework/shell/commands/OsOperations.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.commands; - -import java.io.IOException; - -/** - * Operations type to allow execution of native OS commands from the Spring Roo - * shell. - * - * @author Stefan Schmidt - * @since 1.2.0 - */ -public interface OsOperations { - - /** - * Attempts the execution of a commands and delegates the output to the - * standard logger. - * - * @param command the command to execute - * @throws IOException if an error occurs - */ - void executeCommand(String command) throws IOException; -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/commands/OsOperationsImpl.java b/src/main/java/org/springframework/shell/commands/OsOperationsImpl.java deleted file mode 100644 index d0ae9515..00000000 --- a/src/main/java/org/springframework/shell/commands/OsOperationsImpl.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.commands; - -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.logging.Logger; - -import org.apache.commons.io.IOUtils; -import org.springframework.shell.support.logging.HandlerUtils; -import org.springframework.stereotype.Component; - -/** - * Implementation of {@link OsOperations} interface. - * - * @author Stefan Schmidt - * @since 1.2.0 - */ -@Component -public class OsOperationsImpl implements OsOperations { - private static final Logger LOGGER = HandlerUtils.getLogger(OsOperationsImpl.class); - - public void executeCommand(final String command) throws IOException { - final File root = new File("."); - final Process p = Runtime.getRuntime().exec(command, null, root); - Reader input = new InputStreamReader(p.getInputStream()); - Reader errors = new InputStreamReader(p.getErrorStream()); - - for (String line : IOUtils.readLines(input)) { - if (line.startsWith("[ERROR]")) { - LOGGER.severe(line); - } - else if (line.startsWith("[WARNING]")) { - LOGGER.warning(line); - } - else { - LOGGER.info(line); - } - } - - - for (String line : IOUtils.readLines(errors)) { - if (line.startsWith("[ERROR]")) { - LOGGER.severe(line); - } - else if (line.startsWith("[WARNING]")) { - LOGGER.warning(line); - } - else { - LOGGER.info(line); - } - } - - - p.getOutputStream().close(); - - - try { - if (p.waitFor() != 0) { - LOGGER.warning("The command '" + command + "' did not complete successfully"); - } - } catch (final InterruptedException e) { - throw new IllegalStateException(e); - } - } - -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/commands/ScriptCommands.java b/src/main/java/org/springframework/shell/commands/ScriptCommands.java deleted file mode 100644 index 439ae4ac..00000000 --- a/src/main/java/org/springframework/shell/commands/ScriptCommands.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.commands; - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.logging.Logger; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.core.io.Resource; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.JLineShellComponent; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; -import org.springframework.shell.support.logging.HandlerUtils; -import org.springframework.shell.support.util.IOUtils; -import org.springframework.shell.support.util.MathUtils; -import org.springframework.stereotype.Component; -import org.springframework.util.Assert; - -@Component -public class ScriptCommands implements CommandMarker { - protected final Logger logger = HandlerUtils.getLogger(getClass()); - - @Autowired - private ApplicationContext applicationContext; - - @Autowired - private JLineShellComponent shell; - @CliCommand(value = { "script" }, help = "Parses the specified resource file and executes its commands") - public void script( - @CliOption(key = { "", "file" }, help = "The file to locate and execute", mandatory = true) final File script, - @CliOption(key = "lineNumbers", mandatory = false, specifiedDefaultValue = "true", unspecifiedDefaultValue = "false", help = "Display line numbers when executing the script") final boolean lineNumbers) { - - Assert.notNull(script, "Script file to parse is required"); - double startedNanoseconds = System.nanoTime(); - final InputStream inputStream = openScript(script); - - BufferedReader in = null; - try { - in = new BufferedReader(new InputStreamReader(inputStream)); - String line; - int i = 0; - while ((line = in.readLine()) != null) { - i++; - if (lineNumbers) { - logger.fine("Line " + i + ": " + line); - } else { - logger.fine(line); - } - if (!"".equals(line.trim())) { - boolean success = shell.executeScriptLine(line); - if (success && ((line.trim().startsWith("q") || line.trim().startsWith("ex")))) { - break; - } else if (!success) { - // Abort script processing, given something went wrong - throw new IllegalStateException("Script execution aborted"); - } - } - } - } catch (IOException e) { - throw new IllegalStateException(e); - } finally { - IOUtils.closeQuietly(inputStream, in); - double executionDurationInSeconds = (System.nanoTime() - startedNanoseconds) / 1000000000D; - logger.fine("Script required " + MathUtils.round(executionDurationInSeconds, 3) + " seconds to execute"); - } - } - - /** - * Opens the given script for reading - * - * @param script the script to read (required) - * @return a non-null input stream - */ - private InputStream openScript(final File script) { - try { - return new BufferedInputStream(new FileInputStream(script)); - } catch (final FileNotFoundException fnfe) { - // Try to find the script via the classloader - final Collection urls = findResources(script.getName()); - - // Handle search failure - Assert.notNull(urls, "Unexpected error looking for '" + script.getName() + "'"); - - // Handle the search being OK but the file simply not being present - Assert.notEmpty(urls, "Script '" + script + "' not found on disk or in classpath"); - Assert.isTrue(urls.size() == 1, "More than one '" + script + "' was found in the classpath; unable to continue"); - try { - return urls.iterator().next().openStream(); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - } - - protected Collection findResources(final String path) { - try { - Resource[] resources = applicationContext.getResources(path); - Collection list = new ArrayList(resources.length); - for (Resource resource : resources) { - list.add(resource.getURL()); - } - return list; - } catch (IOException ex) { - logger.fine("Cannot find path " + path); - // return Collections.emptyList(); - throw new RuntimeException(ex); - } - } - -} diff --git a/src/main/java/org/springframework/shell/commands/SystemPropertyCommands.java b/src/main/java/org/springframework/shell/commands/SystemPropertyCommands.java deleted file mode 100644 index 3279ba3a..00000000 --- a/src/main/java/org/springframework/shell/commands/SystemPropertyCommands.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.commands; - -import static org.springframework.shell.support.util.OsUtils.LINE_SEPARATOR; - -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeSet; - -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; - -/** - * Commands related to system properties - * - */ -@Component -public class SystemPropertyCommands implements CommandMarker { - - @CliCommand(value = { "system properties" }, help = "Shows the shell's properties") - public String props() { - final Set data = new TreeSet(); // For repeatability - for (final Entry entry : System.getProperties().entrySet()) { - data.add(entry.getKey() + " = " + entry.getValue()); - } - - return StringUtils.collectionToDelimitedString(data, LINE_SEPARATOR) + LINE_SEPARATOR; - } - -} diff --git a/src/main/java/org/springframework/shell/commands/VersionCommands.java b/src/main/java/org/springframework/shell/commands/VersionCommands.java deleted file mode 100644 index f9c70f24..00000000 --- a/src/main/java/org/springframework/shell/commands/VersionCommands.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.springframework.shell.commands; - -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.plugin.BannerProvider; -import org.springframework.shell.plugin.PluginUtils; -import org.springframework.stereotype.Component; - -/** - * Essential built-in shell commands. - * - * @author Mark Pollack - * @author Erwin Vervaet - */ -@Component -public class VersionCommands implements CommandMarker, ApplicationContextAware { - - private ApplicationContext ctx; - - @CliCommand(value = { "version" }, help = "Displays shell version") - public String version() { - return PluginUtils.getHighestPriorityProvider(ctx, BannerProvider.class).getVersion(); - } - - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - this.ctx = applicationContext; - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/ArrayConverter.java b/src/main/java/org/springframework/shell/converters/ArrayConverter.java deleted file mode 100644 index b3398bfe..00000000 --- a/src/main/java/org/springframework/shell/converters/ArrayConverter.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.springframework.shell.converters; - -import java.io.File; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * A converter that knows how to use other converters to create arrays of supported types. - * - * @author Eric Bottard - */ -@Component -public class ArrayConverter implements Converter{ - - private Set> converters; - - @Autowired - public void setConverters(Set> converters) { - this.converters = converters; - } - - @Override - public boolean supports(Class type, String optionContext) { - return findComponentConverter(type, optionContext) != null && !optionContext.contains("disable-array-converter"); - - } - - private Converter findComponentConverter(Class targetType, String optionContext) { - if (!targetType.isArray()) { - return null; - } - Class componentType = targetType.getComponentType(); - for (Converter converter : converters) { - if (converter.supports(componentType, optionContext)) { - return converter; - } - } - return null; - } - - @Override - public Object[] convertFromText(String value, Class targetType, String optionContext) { - Class componentType = targetType.getComponentType(); - - String splittingRegex = inferSplittingRegex(targetType, optionContext); - String[] splits = value.split(splittingRegex); - Object[] result = (Object[]) Array.newInstance(componentType, splits.length); - Converter converter = findComponentConverter(targetType, optionContext); - - for (int i = 0; i < splits.length; i++) { - result[i] = converter.convertFromText(splits[i], componentType, optionContext); - } - return result; - } - - /** - * Return a regex used to split the string representation of items. - *

The default delimiter is a comma, unless we're dealing with Files, in which case - * {@link java.io.File.pathSeparator} is used.

- *

Delimiters can be protected by an escape character, which is '\' by default.

- *

Command methods may override bot the delimiter and the escape through the {@code splittingRegex} option context - * string.

- */ - private String inferSplittingRegex(Class targetType, String optionContext) { - String regex = extract(optionContext, "splittingRegex"); - if (regex == null) { - // Default for files is to use system separator with no way to escape - if (File[].class.isAssignableFrom(targetType)) { - regex = File.pathSeparator; - } else { - String delimiter = ","; - String escape = "\\"; - regex = String.format("(? completions, Class targetType, String existingData, String optionContext, MethodTarget target) { - Class componentType = targetType.getComponentType(); - - String splittingRegex = inferSplittingRegex(targetType, optionContext); - String[] splits = existingData.split(splittingRegex); - Converter converter = findComponentConverter(targetType, optionContext); - - // Search for completions with the last part only, prefixing the results by everything that was - // before the delimiter - String last = splits[splits.length - 1]; - int end = existingData.lastIndexOf(last); - String prefix = existingData.substring(0, end); - List ours = new ArrayList(); - - // Passing our method target below, as we can't do better. Obviously, method sig will be wrong - boolean result = converter.getAllPossibleValues(ours, componentType, last, optionContext, target); - for (Completion completion : ours) { - completions.add(new Completion(prefix + completion.getValue(), completion.getValue(), null, 0)); - } - - return result; - } - - private String extract(String optionContext, String key) { - String[] splits = optionContext.split(" "); - String prefix = key + "="; - for (String split : splits) { - if (split.startsWith(prefix)) { - return split.substring(prefix.length()); - } - } - return null; - } -} diff --git a/src/main/java/org/springframework/shell/converters/AvailableCommandsConverter.java b/src/main/java/org/springframework/shell/converters/AvailableCommandsConverter.java deleted file mode 100644 index 2c8529db..00000000 --- a/src/main/java/org/springframework/shell/converters/AvailableCommandsConverter.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.JLineShellComponent; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * Available commands converter. - * - * @author Ben Alex - * @author Eric Bottard - * @since 1.0 - */ -@Component -public class AvailableCommandsConverter implements Converter { - - @Autowired - private JLineShellComponent shell; - - @Override - public String convertFromText(final String text, final Class requiredType, final String optionContext) { - return text; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return String.class.isAssignableFrom(requiredType) && optionContext.contains("availableCommands"); - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - - for (String s : shell.getSimpleParser().getEveryCommand()) { - completions.add(new Completion(s)); - } - return true; - } -} diff --git a/src/main/java/org/springframework/shell/converters/BigDecimalConverter.java b/src/main/java/org/springframework/shell/converters/BigDecimalConverter.java deleted file mode 100644 index 144fd9f3..00000000 --- a/src/main/java/org/springframework/shell/converters/BigDecimalConverter.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.math.BigDecimal; -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link BigDecimal}. - * - * @author Stefan Schmidt - * @since 1.0 - */ -@Component -public class BigDecimalConverter implements Converter { - - @Override - public BigDecimal convertFromText(final String value, final Class requiredType, final String optionContext) { - return new BigDecimal(value); - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return BigDecimal.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/BigIntegerConverter.java b/src/main/java/org/springframework/shell/converters/BigIntegerConverter.java deleted file mode 100644 index 7ab5c168..00000000 --- a/src/main/java/org/springframework/shell/converters/BigIntegerConverter.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.math.BigInteger; -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link BigInteger}. - * - * @author Stefan Schmidt - * @since 1.0 - */ -@Component -public class BigIntegerConverter implements Converter { - - @Override - public BigInteger convertFromText(final String value, final Class requiredType, final String optionContext) { - return new BigInteger(value); - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return BigInteger.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/BooleanConverter.java b/src/main/java/org/springframework/shell/converters/BooleanConverter.java deleted file mode 100644 index d197fad6..00000000 --- a/src/main/java/org/springframework/shell/converters/BooleanConverter.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link Boolean}. - * - * @author Stefan Schmidt - * @since 1.0 - */ -@Component -public class BooleanConverter implements Converter { - - @Override - public Boolean convertFromText(final String value, final Class requiredType, final String optionContext) { - if ("true".equalsIgnoreCase(value) || "1".equals(value) || "yes".equalsIgnoreCase(value)) { - return true; - } - else if ("false".equalsIgnoreCase(value) || "0".equals(value) || "no".equalsIgnoreCase(value)) { - return false; - } - else { - throw new IllegalArgumentException("Cannot convert " + value + " to type Boolean."); - } - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - completions.add(new Completion("true")); - completions.add(new Completion("false")); - completions.add(new Completion("yes")); - completions.add(new Completion("no")); - completions.add(new Completion("1")); - completions.add(new Completion("0")); - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return Boolean.class.isAssignableFrom(requiredType) || boolean.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/CharacterConverter.java b/src/main/java/org/springframework/shell/converters/CharacterConverter.java deleted file mode 100644 index 895cd18a..00000000 --- a/src/main/java/org/springframework/shell/converters/CharacterConverter.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link Character}. - * - * @author Stefan Schmidt - * @since 1.0 - */ -@Component -public class CharacterConverter implements Converter { - - @Override - public Character convertFromText(final String value, final Class requiredType, final String optionContext) { - return value.charAt(0); - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return Character.class.isAssignableFrom(requiredType) || char.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/DateConverter.java b/src/main/java/org/springframework/shell/converters/DateConverter.java deleted file mode 100644 index fd3f6e82..00000000 --- a/src/main/java/org/springframework/shell/converters/DateConverter.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.text.DateFormat; -import java.text.ParseException; -import java.util.Date; -import java.util.List; -import java.util.Locale; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link Date}. - * - * @author Stefan Schmidt - * @since 1.0 - */ -@Component -public class DateConverter implements Converter { - - // Fields - private final DateFormat dateFormat; - - public DateConverter() { - this.dateFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.getDefault()); - } - - public DateConverter(final DateFormat dateFormat) { - this.dateFormat = dateFormat; - } - - @Override - public Date convertFromText(final String value, final Class requiredType, final String optionContext) { - try { - return dateFormat.parse(value); - } - catch (ParseException e) { - throw new IllegalArgumentException("Could not parse date: " + e.getMessage()); - } - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return Date.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/DoubleConverter.java b/src/main/java/org/springframework/shell/converters/DoubleConverter.java deleted file mode 100644 index 8964fd31..00000000 --- a/src/main/java/org/springframework/shell/converters/DoubleConverter.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link Double}. - * - * @author Stefan Schmidt - * @since 1.0 - */ -@Component -public class DoubleConverter implements Converter { - - @Override - public Double convertFromText(final String value, final Class requiredType, final String optionContext) { - return new Double(value); - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return Double.class.isAssignableFrom(requiredType) || double.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/EnumConverter.java b/src/main/java/org/springframework/shell/converters/EnumConverter.java deleted file mode 100644 index f22f60ca..00000000 --- a/src/main/java/org/springframework/shell/converters/EnumConverter.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link Enum}. - * - * @author Ben Alex - * @author Alan Stewart - * @since 1.0 - */ -@SuppressWarnings("all") -@Component -public class EnumConverter implements Converter> { - - @Override - @SuppressWarnings("unchecked") - public Enum convertFromText(final String value, final Class requiredType, final String optionContext) { - if (!Enum.class.isAssignableFrom(requiredType)) { - return null; - } - Class enumClass = (Class) requiredType; - return Enum.valueOf(enumClass, value); - } - - @Override - @SuppressWarnings("unchecked") - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - if (!Enum.class.isAssignableFrom(requiredType)) { - return false; - } - Class enumClass = (Class) requiredType; - for (Enum enumValue : enumClass.getEnumConstants()) { - String candidate = enumValue.name(); - if ("".equals(existingData) || candidate.startsWith(existingData) || existingData.startsWith(candidate) - || candidate.toUpperCase().startsWith(existingData.toUpperCase()) - || existingData.toUpperCase().startsWith(candidate.toUpperCase())) { - completions.add(new Completion(candidate)); - } - } - return true; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return Enum.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/FileConverter.java b/src/main/java/org/springframework/shell/converters/FileConverter.java deleted file mode 100644 index 5e3fac76..00000000 --- a/src/main/java/org/springframework/shell/converters/FileConverter.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.io.File; -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.shell.support.util.FileUtils; -import org.springframework.util.Assert; - -/** - * {@link Converter} for {@link File}. - * - * @author Stefan Schmidt - * @author Roman Kuzmik - * @author Ben Alex - * @since 1.0 - */ -public abstract class FileConverter implements Converter { - - private static final String HOME_DIRECTORY_SYMBOL = "~"; - // Constants - private static final String home = System.getProperty("user.home"); - - // Fields - - /** - * @return the "current working directory" this {@link FileConverter} should use if the user fails to provide - * an explicit directory in their input (required) - */ - protected abstract File getWorkingDirectory(); - - public File convertFromText(final String value, final Class requiredType, final String optionContext) { - return new File(convertUserInputIntoAFullyQualifiedPath(value)); - } - - public boolean getAllPossibleValues(final List completions, final Class requiredType, final String originalUserInput, final String optionContext, final MethodTarget target) { - String adjustedUserInput = convertUserInputIntoAFullyQualifiedPath(originalUserInput); - - String directoryData = adjustedUserInput.substring(0, adjustedUserInput.lastIndexOf(File.separator) + 1); - adjustedUserInput = adjustedUserInput.substring(adjustedUserInput.lastIndexOf(File.separator) + 1); - - populate(completions, adjustedUserInput, originalUserInput, directoryData); - - return false; - } - - protected void populate(final List completions, final String adjustedUserInput, final String originalUserInput, final String directoryData) { - File directory = new File(directoryData); - - if (!directory.isDirectory()) { - return; - } - - for (File file : directory.listFiles()) { - if (adjustedUserInput == null || adjustedUserInput.length() == 0 || - file.getName().startsWith(adjustedUserInput)) { - - String completion = ""; - if (directoryData.length() > 0) - completion += directoryData; - completion += file.getName(); - - completion = convertCompletionBackIntoUserInputStyle(originalUserInput, completion); - - if (file.isDirectory()) { - completions.add(new Completion(completion + File.separator)); - } else { - completions.add(new Completion(completion)); - } - } - } - } - - public boolean supports(final Class requiredType, final String optionContext) { - return File.class.isAssignableFrom(requiredType); - } - - private String convertCompletionBackIntoUserInputStyle(final String originalUserInput, final String completion) { - if (FileUtils.denotesAbsolutePath(originalUserInput)) { - // Input was originally as a fully-qualified path, so we just keep the completion in that form - return completion; - } - if (originalUserInput.startsWith(HOME_DIRECTORY_SYMBOL)) { - // Input originally started with this symbol, so replace the user's home directory with it again - Assert.notNull(home, "Home directory could not be determined from system properties"); - return HOME_DIRECTORY_SYMBOL + completion.substring(home.length()); - } - // The path was working directory specific, so strip the working directory given the user never typed it - return completion.substring(getWorkingDirectoryAsString().length()); - } - - /** - * If the user input starts with a tilde character (~), replace the tilde character with the - * user's home directory. If the user input does not start with a tilde, simply return the original - * user input without any changes if the input specifies an absolute path, or return an absolute path - * based on the working directory if the input specifies a relative path. - * - * @param userInput the user input, which may commence with a tilde (required) - * @return a string that is guaranteed to no longer contain a tilde as the first character (never null) - */ - private String convertUserInputIntoAFullyQualifiedPath(final String userInput) { - if (FileUtils.denotesAbsolutePath(userInput)) { - // Input is already in a fully-qualified path form - return userInput; - } - if (userInput.startsWith(HOME_DIRECTORY_SYMBOL)) { - // Replace this symbol with the user's actual home directory - Assert.notNull(home, "Home directory could not be determined from system properties"); - if (userInput.length() > 1) { - return home + userInput.substring(1); - } - } - // The path is working directory specific, so prepend the working directory - String fullPath = getWorkingDirectoryAsString() + userInput; - return fullPath; - } - - private String getWorkingDirectoryAsString() { - try { - return getWorkingDirectory().getCanonicalPath() + File.separator; - } catch (Exception e) { - throw new IllegalStateException(e); - } - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/FloatConverter.java b/src/main/java/org/springframework/shell/converters/FloatConverter.java deleted file mode 100644 index 24136e67..00000000 --- a/src/main/java/org/springframework/shell/converters/FloatConverter.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link Float}. - * - * @author Stefan Schmidt - * @since 1.0 - */ -@Component -public class FloatConverter implements Converter { - - @Override - public Float convertFromText(final String value, final Class requiredType, final String optionContext) { - return new Float(value); - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return Float.class.isAssignableFrom(requiredType) || float.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/IntegerConverter.java b/src/main/java/org/springframework/shell/converters/IntegerConverter.java deleted file mode 100644 index 05dd2a71..00000000 --- a/src/main/java/org/springframework/shell/converters/IntegerConverter.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.springframework.shell.converters; - -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link Integer}. - * - * @author Stefan Schmidt - * @since 1.0 - */ -@Component -public class IntegerConverter implements Converter { - - @Override - public Integer convertFromText(final String value, final Class requiredType, final String optionContext) { - return new Integer(value); - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return Integer.class.isAssignableFrom(requiredType) || int.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/LocaleConverter.java b/src/main/java/org/springframework/shell/converters/LocaleConverter.java deleted file mode 100644 index e546ce15..00000000 --- a/src/main/java/org/springframework/shell/converters/LocaleConverter.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.util.List; -import java.util.Locale; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link Locale}. Supports locales with ISO-639 (ie 'en') or a combination of ISO-639 and - * ISO-3166 (ie 'en_AU'). - * - * @author Stefan Schmidt - * @since 1.1 - */ -@Component -public class LocaleConverter implements Converter { - - @Override - public Locale convertFromText(final String value, final Class requiredType, final String optionContext) { - if (value.length() == 2) { - // In case only a simpele ISO-639 code is provided we use that code also for the country (ie 'de_DE') - return new Locale(value, value.toUpperCase()); - } - else if (value.length() == 5) { - String[] split = value.split("_"); - return new Locale(split[0], split[1]); - } - else { - return null; - } - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return Locale.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/LongConverter.java b/src/main/java/org/springframework/shell/converters/LongConverter.java deleted file mode 100644 index 8f176b98..00000000 --- a/src/main/java/org/springframework/shell/converters/LongConverter.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link Long}. - * - * @author Stefan Schmidt - * @since 1.0 - */ -@Component -public class LongConverter implements Converter { - - @Override - public Long convertFromText(final String value, final Class requiredType, final String optionContext) { - return new Long(value); - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return Long.class.isAssignableFrom(requiredType) || long.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/ShortConverter.java b/src/main/java/org/springframework/shell/converters/ShortConverter.java deleted file mode 100644 index e33450dc..00000000 --- a/src/main/java/org/springframework/shell/converters/ShortConverter.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link Short}. - * - * @author Stefan Schmidt - * @since 1.0 - */ -@Component -public class ShortConverter implements Converter { - - @Override - public Short convertFromText(final String value, final Class requiredType, final String optionContext) { - return new Short(value); - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return Short.class.isAssignableFrom(requiredType) || short.class.isAssignableFrom(requiredType); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/SimpleFileConverter.java b/src/main/java/org/springframework/shell/converters/SimpleFileConverter.java deleted file mode 100644 index ab069844..00000000 --- a/src/main/java/org/springframework/shell/converters/SimpleFileConverter.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.io.File; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.shell.core.Shell; -import org.springframework.stereotype.Component; - -@Component -public class SimpleFileConverter extends FileConverter { - @Autowired - private Shell shell; - - @Override - protected File getWorkingDirectory() { - return shell.getHome(); - } -} diff --git a/src/main/java/org/springframework/shell/converters/StaticFieldConverter.java b/src/main/java/org/springframework/shell/converters/StaticFieldConverter.java deleted file mode 100644 index a155a061..00000000 --- a/src/main/java/org/springframework/shell/converters/StaticFieldConverter.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import org.springframework.shell.core.Converter; - -/** - * Interface for adding and removing classes that provide static fields which should - * be made available via a {@link Converter}. - * - * @author Ben Alex - * @since 1.0 - */ -public interface StaticFieldConverter extends Converter { - - void add(Class clazz); - - void remove(Class clazz); -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/converters/StaticFieldConverterImpl.java b/src/main/java/org/springframework/shell/converters/StaticFieldConverterImpl.java deleted file mode 100644 index 2cbf0230..00000000 --- a/src/main/java/org/springframework/shell/converters/StaticFieldConverterImpl.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * A simple {@link Converter} for those classes which provide public static fields to represent possible textual values. - * - * @author Stefan Schmidt - * @author Ben Alex - * @since 1.0 - */ -@Component -public class StaticFieldConverterImpl implements StaticFieldConverter { - - // Fields - private final Map, Map> fields = new HashMap, Map>(); - - @Override - public void add(final Class clazz) { - Assert.notNull(clazz, "A class to provide conversion services is required"); - Assert.isNull(fields.get(clazz), "Class '" + clazz + "' is already registered for completion services"); - Map ffields = new HashMap(); - for (Field field : clazz.getFields()) { - int modifier = field.getModifiers(); - if (Modifier.isStatic(modifier) && Modifier.isPublic(modifier)) { - ffields.put(field.getName(), field); - } - } - Assert.notEmpty(ffields, "Zero public static fields accessible in '" + clazz + "'"); - fields.put(clazz, ffields); - } - - @Override - public void remove(final Class clazz) { - Assert.notNull(clazz, "A class that was providing conversion services is required"); - fields.remove(clazz); - } - - @Override - public Object convertFromText(final String value, final Class requiredType, final String optionContext) { - if (!StringUtils.hasText(value)) { - return null; - } - Map ffields = fields.get(requiredType); - if (ffields == null) { - return null; - } - Field f = ffields.get(value); - if (f == null) { - // Fallback to case insensitive search - for (Field candidate : ffields.values()) { - if (candidate.getName().equalsIgnoreCase(value)) { - f = candidate; - break; - } - } - if (f == null) { - // Still not found, despite a case-insensitive search - return null; - } - } - try { - return f.get(null); - } - catch (Exception ex) { - throw new IllegalStateException("Unable to acquire field '" + value + "' from '" + requiredType.getName() - + "'", ex); - } - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - Map ffields = fields.get(requiredType); - if (ffields == null) { - return true; - } - for (String field : ffields.keySet()) { - completions.add(new Completion(field)); - } - return true; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return fields.get(requiredType) != null; - } -} diff --git a/src/main/java/org/springframework/shell/converters/StringConverter.java b/src/main/java/org/springframework/shell/converters/StringConverter.java deleted file mode 100644 index e17079b7..00000000 --- a/src/main/java/org/springframework/shell/converters/StringConverter.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.converters; - -import java.util.List; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.MethodTarget; -import org.springframework.stereotype.Component; - -/** - * {@link Converter} for {@link String}. - * - * @author Ben Alex - * @since 1.0 - */ -@Component -public class StringConverter implements Converter { - - @Override - public String convertFromText(final String value, final Class requiredType, final String optionContext) { - return value; - } - - @Override - public boolean getAllPossibleValues(final List completions, final Class requiredType, - final String existingData, final String optionContext, final MethodTarget target) { - return false; - } - - @Override - public boolean supports(final Class requiredType, final String optionContext) { - return String.class.isAssignableFrom(requiredType) - && (optionContext == null || !optionContext.contains("disable-string-converter")); - } -} diff --git a/src/main/java/org/springframework/shell/core/AbstractShell.java b/src/main/java/org/springframework/shell/core/AbstractShell.java deleted file mode 100644 index 28e90eed..00000000 --- a/src/main/java/org/springframework/shell/core/AbstractShell.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright 2011-2016 the original author or authors. - * - * 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.springframework.shell.core; - -import java.io.File; -import java.util.logging.Level; -import java.util.logging.Logger; - -import jline.TerminalFactory; - -import org.springframework.shell.TerminalSizeAware; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.event.AbstractShellStatusPublisher; -import org.springframework.shell.event.ParseResult; -import org.springframework.shell.event.ShellStatus; -import org.springframework.shell.event.ShellStatus.Status; -import org.springframework.shell.support.logging.HandlerUtils; -import org.springframework.shell.support.util.VersionUtils; -import org.springframework.util.Assert; - -/** - * Provides a base {@link Shell} implementation. - * - * @author Ben Alex - * @author Gunnar Hillert - */ -public abstract class AbstractShell extends AbstractShellStatusPublisher implements Shell { - - // Constants - private static final String MY_SLOT = AbstractShell.class.getName(); - - //TODO Abstract out to make configurable. - protected static final String ROO_PROMPT = "spring> "; - - // Public static fields; don't rename, make final, or make non-public, as - // they are part of the public API, e.g. are changed by STS. - public static String completionKeys = "TAB"; - public static String shellPrompt = ROO_PROMPT; - - // Instance fields - protected final Logger logger = HandlerUtils.getLogger(getClass()); - - protected final Logger exceptionLogger = Logger.getLogger(getClass().getName() + ".exceptions"); - - protected boolean inBlockComment; - protected ExitShellRequest exitShellRequest; - - protected abstract String getHomeAsString(); - - protected abstract ExecutionStrategy getExecutionStrategy(); - - protected abstract Parser getParser(); - - - /** - * Execute the single line from a script. - *

- * This method can be overridden by sub-classes to pre-process script lines. - */ - public boolean executeScriptLine(final String line) { - return executeCommand(line).isSuccess(); - } - - public CommandResult executeCommand(String line) { - // Another command was attempted - setShellStatus(ShellStatus.Status.PARSING); - - final ExecutionStrategy executionStrategy = getExecutionStrategy(); - boolean flashedMessage = false; - while (executionStrategy == null || !executionStrategy.isReadyForCommands()) { - // Wait - try { - Thread.sleep(500); - } catch (InterruptedException ignore) {} - if (!flashedMessage) { - flash(Level.INFO, "Please wait - still loading", MY_SLOT); - flashedMessage = true; - } - } - if (flashedMessage) { - flash(Level.INFO, "", MY_SLOT); - } - - ParseResult parseResult = null; - try { - // We support simple block comments; ie a single pair per line - if (!inBlockComment && line.contains("/*") && line.contains("*/")) { - blockCommentBegin(); - String lhs = line.substring(0, line.lastIndexOf("/*")); - if (line.contains("*/")) { - line = lhs + line.substring(line.lastIndexOf("*/") + 2); - blockCommentFinish(); - } else { - line = lhs; - } - } - if (inBlockComment) { - if (!line.contains("*/")) { - return new CommandResult(true); - } - blockCommentFinish(); - line = line.substring(line.lastIndexOf("*/") + 2); - } - // We also support inline comments (but only at start of line, otherwise valid - // command options like http://www.helloworld.com will fail as per ROO-517) - if (!inBlockComment && (line.trim().startsWith("//") || line.trim().startsWith("#"))) { // # support in ROO-1116 - line = ""; - } - // Convert any TAB characters to whitespace (ROO-527) - line = line.replace('\t', ' '); - if ("".equals(line.trim())) { - setShellStatus(Status.EXECUTION_SUCCESS); - return new CommandResult(true); - } - parseResult = getParser().parse(line); - if (parseResult == null) { - return new CommandResult(false); - } - - setShellStatus(Status.EXECUTING); - Object result = executionStrategy.execute(parseResult); - setShellStatus(Status.EXECUTION_RESULT_PROCESSING); - if (result != null) { - if (result instanceof ExitShellRequest) { - exitShellRequest = (ExitShellRequest) result; - // Give ProcessManager a chance to close down its threads before the overall OSGi framework is terminated (ROO-1938) - executionStrategy.terminate(); - } else { - handleExecutionResult(result); - } - } - - logCommandIfRequired(line, true); - setShellStatus(Status.EXECUTION_SUCCESS, line, parseResult); - return new CommandResult(true, result, null); - } catch (RuntimeException e) { - setShellStatus(Status.EXECUTION_FAILED, line, parseResult); - exceptionLogger.log(Level.WARNING, e.getMessage(), e); - // We rely on execution strategy to log it - try { - logCommandIfRequired(line, false); - } catch (Exception ignored) {} - return new CommandResult(false, null, e); - } finally { - setShellStatus(Status.USER_INPUT); - } - } - - /** - * Allows a subclass to log the execution of a well-formed command. This is invoked after a command - * has completed, and indicates whether the command returned normally or returned an exception. Note - * that attempted commands that are not well-formed (eg they are missing a mandatory argument) will - * never be presented to this method, as the command execution is never actually attempted in those - * cases. This method is only invoked if an attempt is made to execute a particular command. - * - *

- * Implementations should consider specially handling the "script" commands, and also - * indicating whether a command was successful or not. Implementations that wish to behave - * consistently with other {@link AbstractShell} subclasses are encouraged to simply override - * {@link #logCommandToOutput(String)} instead, and only override this method if you actually - * need to fine-tune the output logic. - * - * @param line the parsed line (any comments have been removed; never null) - * @param successful if the command was successful or not - */ - protected void logCommandIfRequired(final String line, final boolean successful) { - if (line.startsWith("script")) { - logCommandToOutput((successful ? "// " : "// [failed] ") + line); - } else { - logCommandToOutput((successful ? "" : "// [failed] ") + line); - } - } - - /** - * Allows a subclass to actually write the resulting logged command to some form of output. This - * frees subclasses from needing to implement the logic within {@link #logCommandIfRequired(String, boolean)}. - * - *

- * Implementations should invoke {@link #getExitShellRequest()} to monitor any attempts to exit the shell and - * release resources such as output log files. - * - * @param processedLine the line that should be appended to some type of output (excluding the \n character) - */ - protected void logCommandToOutput(final String processedLine) {} - - /** - * Base implementation of the {@link Shell#setPromptPath(String)} method, designed for simple shell - * implementations. Advanced implementations (eg those that support ANSI codes etc) will likely want - * to override this method and set the {@link #shellPrompt} variable directly. - * - * @param path to set (can be null or empty; must NOT be formatted in any special way eg ANSI codes) - */ - public void setPromptPath(final String path) { - if (path == null || "".equals(path)) { - shellPrompt = ROO_PROMPT; - } else { - shellPrompt = path + " " + ROO_PROMPT; - } - } - - /** - * Default implementation of {@link Shell#setPromptPath(String, boolean))} method to satisfy STS compatibility. - * - * @param path to set (can be null or empty) - * @param overrideStyle - */ - public void setPromptPath(String path, boolean overrideStyle) { - setPromptPath(path); - } - - public ExitShellRequest getExitShellRequest() { - return exitShellRequest; - } - - @CliCommand(value = { "/*" }, help = "Start of block comment") - public void blockCommentBegin() { - Assert.isTrue(!inBlockComment, "Cannot open a new block comment when one already active"); - inBlockComment = true; - } - - @CliCommand(value = { "*/" }, help = "End of block comment") - public void blockCommentFinish() { - Assert.isTrue(inBlockComment, "Cannot close a block comment when it has not been opened"); - inBlockComment = false; - } - - public String versionInfo(){ - return VersionUtils.versionInfo(); - } - - public String getShellPrompt() { - return shellPrompt; - } - - /** - * Obtains the home directory for the current shell instance. - * - *

- * Note: calls the {@link #getHomeAsString()} method to allow subclasses to provide the home directory location as - * string using different environment-specific strategies. - * - *

- * If the path indicated by {@link #getHomeAsString()} exists and refers to a directory, that directory - * is returned. - * - *

- * If the path indicated by {@link #getHomeAsString()} exists and refers to a file, an exception is thrown. - * - *

- * If the path indicated by {@link #getHomeAsString()} does not exist, it will be created as a directory. - * If this fails, an exception will be thrown. - * - * @return the home directory for the current shell instance (which is guaranteed to exist and be a directory) - */ - public File getHome() { - String rooHome = getHomeAsString(); - File f = new File(rooHome); - Assert.isTrue(!f.exists() || (f.exists() && f.isDirectory()), "Path '" + f.getAbsolutePath() + "' must be a directory, or it must not exist"); - if (!f.exists()) { - f.mkdirs(); - } - Assert.isTrue(f.exists() && f.isDirectory(), "Path '" + f.getAbsolutePath() + "' is not a directory; please specify roo.home system property correctly"); - return f; - } - - /** - * Simple implementation of {@link #flash(Level, String, String)} that simply displays the message via the logger. It is - * strongly recommended shell implementations override this method with a more effective approach. - */ - public void flash(final Level level, final String message, final String slot) { - Assert.notNull(level, "Level is required for a flash message"); - Assert.notNull(message, "Message is required for a flash message"); - Assert.hasText(slot, "Slot name must be specified for a flash message"); - if (!("".equals(message))) { - logger.log(level, message); - } - } - - /** - * Handles the result of execution of a command. Given result is - * expected to be not null. If result is a - * {@link java.lang.Iterable} object, it will be iterated through to print - * the output of toString. For other type of objects, simply output - * of toString is shown. Subclasses can alter this implementation - * to handle the result differently. - * - * @param result not null result of execution of a command. - */ - protected void handleExecutionResult(Object result) { - if (result instanceof Iterable) { - for (Object o : (Iterable) result) { - handleExecutionResult(o); - } - } else if (result instanceof TerminalSizeAware) { - int width = TerminalFactory.get().getWidth(); - logger.info(((TerminalSizeAware) result).render(width).toString()); - } else { - logger.info(result.toString()); - } - } -} diff --git a/src/main/java/org/springframework/shell/core/CommandMarker.java b/src/main/java/org/springframework/shell/core/CommandMarker.java deleted file mode 100644 index 8f05751a..00000000 --- a/src/main/java/org/springframework/shell/core/CommandMarker.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -/** - * Marker interface indicating a provider of one or more shell commands. - */ -public interface CommandMarker {} diff --git a/src/main/java/org/springframework/shell/core/CommandResult.java b/src/main/java/org/springframework/shell/core/CommandResult.java deleted file mode 100644 index b2002310..00000000 --- a/src/main/java/org/springframework/shell/core/CommandResult.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2013 the original author or authors. - * - * 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.springframework.shell.core; - -public class CommandResult { - - private boolean success; - - private Object result; - - private Throwable exception; - - public CommandResult(boolean success) { - this.success = success; - } - public CommandResult(boolean success, Object result, Throwable exception) { - super(); - this.success = success; - this.result = result; - this.exception = exception; - } - - public boolean isSuccess() { - return success; - } - - public Object getResult() { - return result; - } - - public Throwable getException() { - return exception; - } - - @Override - public String toString() { - return "CommandResult [success=" + success + ", result=" + result - + ", exception=" + exception + "]"; - } - - -} diff --git a/src/main/java/org/springframework/shell/core/Completion.java b/src/main/java/org/springframework/shell/core/Completion.java deleted file mode 100644 index d1c8fc4a..00000000 --- a/src/main/java/org/springframework/shell/core/Completion.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import org.springframework.shell.support.util.AnsiEscapeCode; -import org.springframework.util.StringUtils; - -public class Completion { - - // Fields - private final int order; - private final String formattedValue; - private final String heading; - private final String value; - - /** - * Constructor - * - * @param value - */ - public Completion(final String value) { - this(value, value, null, 0); - } - - /** - * Constructor - * - * @param value - * @param formattedValue - * @param heading - * @param order - */ - public Completion(final String value, final String formattedValue, String heading, final int order) { - this.formattedValue = formattedValue; - this.order = order; - this.value = value; - if (StringUtils.hasText(heading)) { - heading = AnsiEscapeCode.decorate(heading, AnsiEscapeCode.UNDERSCORE, AnsiEscapeCode.FG_GREEN); - } - this.heading = heading; - } - - public String getValue() { - return value; - } - - public String getFormattedValue() { - return formattedValue; - } - - public String getHeading() { - return heading; - } - - public int getOrder() { - return order; - } - - @Override - public String toString() { - return order + ". " + heading + " - " + value; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - final Completion that = (Completion) o; - if (formattedValue != null ? !formattedValue.equals(that.formattedValue) : that.formattedValue != null) { - return false; - } - if (heading != null ? !heading.equals(that.heading) : that.heading != null) { - return false; - } - if (value != null ? !value.equals(that.value) : that.value != null) { - return false; - } - return true; - } - - @Override - public int hashCode() { - int result = value != null ? value.hashCode() : 0; - result = 31 * result + (formattedValue != null ? formattedValue.hashCode() : 0); - result = 31 * result + (heading != null ? heading.hashCode() : 0); - return result; - } -} - diff --git a/src/main/java/org/springframework/shell/core/Converter.java b/src/main/java/org/springframework/shell/core/Converter.java deleted file mode 100644 index 16a9718c..00000000 --- a/src/main/java/org/springframework/shell/core/Converter.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import java.util.List; - -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; - -/** - * Converts between Strings (as displayed by and entered via the shell) and Java objects - * - * @author Ben Alex - * @param the type being converted to/from - */ -public interface Converter { - - /** - * The prefix for the option context property that indicates how many successive tab completion requests have - * occurred. - */ - public static final String TAB_COMPLETION_COUNT_PREFIX = "tab-completion-count-"; - - /** - * Indicates whether this converter supports the given type in the given option context - * - * @param type the type being checked - * @param optionContext a non-null string that customises the behaviour of this converter for a given - * {@link CliOption} of a given {@link CliCommand}; the contents will have special meaning to this converter (e.g. - * be a comma-separated list of keywords known to this converter) - * @return see above - */ - boolean supports(Class type, String optionContext); - - /** - * Converts from the given String value to type T - * - * @param value the value to convert - * @param targetType the type being converted to; can't be null - * @param optionContext a non-null string that customises the behaviour of this converter for a given - * {@link CliOption} of a given {@link CliCommand}; the contents will have special meaning to this converter (e.g. - * be a comma-separated list of keywords known to this converter) - * @return see above - * @throws RuntimeException if the given value could not be converted - */ - T convertFromText(String value, Class targetType, String optionContext); - - /** - * Populates the given list with the possible completions - * - * @param completions the list to populate; can't be null - * @param targetType the type of parameter for which a string is being entered - * @param existingData what the user has typed so far - * @param optionContext a non-null string that customises the behaviour of this converter for a given - * {@link CliOption} of a given {@link CliCommand}; the contents will have special meaning to this converter (e.g. - * be a comma-separated list of keywords known to this converter) - * @param target - * @return true if all the added completions are complete values, or false if the user can - * press TAB to add further information to some or all of them - */ - boolean getAllPossibleValues(List completions, Class targetType, String existingData, - String optionContext, MethodTarget target); -} diff --git a/src/main/java/org/springframework/shell/core/ExecutionProcessor.java b/src/main/java/org/springframework/shell/core/ExecutionProcessor.java deleted file mode 100644 index d98ee81d..00000000 --- a/src/main/java/org/springframework/shell/core/ExecutionProcessor.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import org.springframework.shell.event.ParseResult; - -/** - * Extension interface allowing command provider to be called - * in a generic fashion just before, and right after, executing a command. - * - * @author Costin Leau - */ -public interface ExecutionProcessor extends CommandMarker { - - /** - * Method called before invoking the target command (described by {@link ParseResult}). - * Additionally, for advanced cases, the parse result itself effectively changing the invocation - * calling site. - * - * @param invocationContext target command context - * @return the invocation target - */ - ParseResult beforeInvocation(ParseResult invocationContext); - - /** - * Method called after successfully invoking the target command (described by {@link ParseResult}). - * - * @param invocationContext target command context - * @param result the invocation result - */ - void afterReturningInvocation(ParseResult invocationContext, Object result); - - /** - * Method called after invoking the target command (described by {@link ParseResult}) had thrown an exception . - * - * @param invocationContext target command context - * @param thrown the thrown object - */ - void afterThrowingInvocation(ParseResult invocationContext, Throwable thrown); - -} diff --git a/src/main/java/org/springframework/shell/core/ExecutionStrategy.java b/src/main/java/org/springframework/shell/core/ExecutionStrategy.java deleted file mode 100644 index 2510e95f..00000000 --- a/src/main/java/org/springframework/shell/core/ExecutionStrategy.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import org.springframework.shell.event.ParseResult; - -/** - * Strategy interface to permit the controlled execution of methods. - * - *

- * This interface is used to enable a {@link Shell} to execute methods in a consistent, system-wide - * manner. A typical use case is to ensure user interface commands are not executed concurrently - * when other background threads are performing certain operations. - * - * @author Ben Alex - * @since 1.0 - * - */ -public interface ExecutionStrategy { - - /** - * Executes the method indicated by the {@link ParseResult}. - * - * @param parseResult that should be executed (never presented as null) - * @return an object which will be rendered by the {@link Shell} implementation (may return null) - * @throws RuntimeException which is handled by the {@link Shell} implementation - */ - Object execute(ParseResult parseResult) throws RuntimeException; - - /** - * Indicates commands are able to be presented. This generally means all important - * system startup activities have completed. - * - * @return whether commands can be presented for processing at this time - */ - boolean isReadyForCommands(); - - /** - * Indicates the execution runtime should be terminated. This allows it to cleanup before returning - * control flow to the caller. Necessary for clean shutdowns. - */ - void terminate(); -} diff --git a/src/main/java/org/springframework/shell/core/ExitShellRequest.java b/src/main/java/org/springframework/shell/core/ExitShellRequest.java deleted file mode 100644 index 9683efdb..00000000 --- a/src/main/java/org/springframework/shell/core/ExitShellRequest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -/** - * An immutable representation of a request to exit the shell. - * - *

- * Implementations of the shell are free to handle these requests in whatever - * way they wish. Callers should not expect an exit request to be completed. - * - * @author Ben Alex - */ -public class ExitShellRequest { - - // Constants - public static final ExitShellRequest NORMAL_EXIT = new ExitShellRequest(0); - public static final ExitShellRequest FATAL_EXIT = new ExitShellRequest(1); - public static final ExitShellRequest JVM_TERMINATED_EXIT = new ExitShellRequest(99); // Ensure 99 is maintained in o.s.r.bootstrap.Main as it's the default for a null roo.exit code - - // Fields - private final int exitCode; - - private ExitShellRequest(final int exitCode) { - this.exitCode = exitCode; - } - - public int getExitCode() { - return exitCode; - } -} diff --git a/src/main/java/org/springframework/shell/core/IdeTerminal.java b/src/main/java/org/springframework/shell/core/IdeTerminal.java deleted file mode 100644 index 36764676..00000000 --- a/src/main/java/org/springframework/shell/core/IdeTerminal.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import jline.UnsupportedTerminal; - -/** - * Terminal used for debugging inside an IDE. See the development instructions. - */ -public class IdeTerminal extends UnsupportedTerminal { - - public boolean isANSISupported() { - return false; - } -} diff --git a/src/main/java/org/springframework/shell/core/JLineLogHandler.java b/src/main/java/org/springframework/shell/core/JLineLogHandler.java deleted file mode 100644 index 44bd0ce6..00000000 --- a/src/main/java/org/springframework/shell/core/JLineLogHandler.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import static org.fusesource.jansi.Ansi.ansi; -import static org.fusesource.jansi.Ansi.Color.GREEN; -import static org.fusesource.jansi.Ansi.Color.MAGENTA; -import static org.fusesource.jansi.Ansi.Color.RED; -import static org.springframework.shell.support.util.OsUtils.LINE_SEPARATOR; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.logging.Formatter; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogRecord; - -import jline.console.ConsoleReader; - -import org.fusesource.jansi.Ansi; -import org.fusesource.jansi.Ansi.Attribute; -import org.springframework.shell.support.util.IOUtils; -import org.springframework.util.Assert; - -/** - * JDK logging {@link Handler} that emits log messages to a JLine {@link ConsoleReader}. - * - * @author Ben Alex - * @since 1.0 - */ -public class JLineLogHandler extends Handler { - - // Fields - private ConsoleReader reader; - - private ShellPromptAccessor shellPromptAccessor; - - private static ThreadLocal redrawProhibit = new ThreadLocal(); - - private static String lastMessage; - - private static boolean includeThreadName = false; - - private boolean ansiSupported; - - private String userInterfaceThreadName; - - private static boolean suppressDuplicateMessages = true; - - public JLineLogHandler(final ConsoleReader reader, final ShellPromptAccessor shellPromptAccessor) { - Assert.notNull(reader, "Console reader required"); - Assert.notNull(shellPromptAccessor, "Shell prompt accessor required"); - this.reader = reader; - this.shellPromptAccessor = shellPromptAccessor; - this.userInterfaceThreadName = Thread.currentThread().getName(); - this.ansiSupported = reader.getTerminal().isAnsiSupported(); - - setFormatter(new Formatter() { - @Override - public String format(final LogRecord record) { - StringBuffer sb = new StringBuffer(); - if (record.getMessage() != null) { - sb.append(record.getMessage()).append(LINE_SEPARATOR); - } - if (record.getThrown() != null) { - PrintWriter pw = null; - try { - StringWriter sw = new StringWriter(); - pw = new PrintWriter(sw); - record.getThrown().printStackTrace(pw); - sb.append(sw.toString()); - } - catch (Exception ex) { - } - finally { - IOUtils.closeQuietly(pw); - } - } - return sb.toString(); - } - }); - } - - @Override - public void flush() { - } - - @Override - public void close() throws SecurityException { - } - - public static void prohibitRedraw() { - redrawProhibit.set(true); - } - - public static void cancelRedrawProhibition() { - redrawProhibit.remove(); - } - - public static void setIncludeThreadName(final boolean include) { - includeThreadName = include; - } - - public static void resetMessageTracking() { - lastMessage = null; // see ROO-251 - } - - public static boolean isSuppressDuplicateMessages() { - return suppressDuplicateMessages; - } - - public static void setSuppressDuplicateMessages(final boolean suppressDuplicateMessages) { - JLineLogHandler.suppressDuplicateMessages = suppressDuplicateMessages; - } - - @Override - public void publish(final LogRecord record) { - try { - // Avoid repeating the same message that displayed immediately before the current message (ROO-30, ROO-1873) - String toDisplay = toDisplay(record); - if (toDisplay.equals(lastMessage) && suppressDuplicateMessages) { - return; - } - lastMessage = toDisplay; - - StringBuilder buffer = reader.getCursorBuffer().copy().buffer; - int cursor = reader.getCursorBuffer().cursor; - if (reader.getCursorBuffer().length() > 0) { - // The user has semi-typed something, so put a new line in so the debug message is separated - reader.println(); - - // We need to cancel whatever they typed (it's reset later on), so the line appears empty - reader.getCursorBuffer().clear(); - } - - // This ensures nothing is ever displayed when redrawing the line - reader.setPrompt(""); - reader.redrawLine(); - // Now restore the line formatting settings back to their original - reader.setPrompt(shellPromptAccessor.getShellPrompt()); - - reader.getCursorBuffer().write(buffer.toString()); - reader.getCursorBuffer().cursor = cursor; - - reader.print(toDisplay); - - Boolean prohibitingRedraw = redrawProhibit.get(); - if (prohibitingRedraw == null) { - reader.redrawLine(); - } - - reader.flush(); - } - catch (Exception e) { - reportError("Could not publish log message", e, Level.SEVERE.intValue()); - } - } - - private String toDisplay(final LogRecord event) { - StringBuilder sb = new StringBuilder(); - - String threadName; - String eventString; - if (includeThreadName && !userInterfaceThreadName.equals(Thread.currentThread().getName()) - && !"".equals(Thread.currentThread().getName())) { - threadName = "[" + Thread.currentThread().getName() + "]"; - - // Build an event string that will indent nicely given the left hand side now contains a thread name - StringBuilder lineSeparatorAndIndentingString = new StringBuilder(); - for (int i = 0; i <= threadName.length(); i++) { - lineSeparatorAndIndentingString.append(" "); - } - - eventString = " " - + getFormatter().format(event).replace(LINE_SEPARATOR, - LINE_SEPARATOR + lineSeparatorAndIndentingString.toString()); - if (eventString.endsWith(lineSeparatorAndIndentingString.toString())) { - eventString = eventString.substring(0, eventString.length() - lineSeparatorAndIndentingString.length()); - } - } - else { - threadName = ""; - eventString = getFormatter().format(event); - } - - if (ansiSupported) { - Ansi ansi = ansi(sb); - if (event.getLevel().intValue() >= Level.SEVERE.intValue()) { - ansi.a(Attribute.NEGATIVE_ON).a(threadName).a(Attribute.NEGATIVE_OFF).fg(RED).a(eventString).reset(); - } - else if (event.getLevel().intValue() >= Level.WARNING.intValue()) { - ansi.a(Attribute.NEGATIVE_ON).a(threadName).a(Attribute.NEGATIVE_OFF).fg(MAGENTA).a(eventString) - .reset(); - } - else if (event.getLevel().intValue() >= Level.INFO.intValue()) { - ansi.a(Attribute.NEGATIVE_ON).a(threadName).a(Attribute.NEGATIVE_OFF).fg(GREEN).a(eventString).reset(); - } - else { - ansi.a(Attribute.NEGATIVE_ON).a(threadName).a(Attribute.NEGATIVE_OFF).a(eventString); - } - - } - else { - sb.append(threadName).append(eventString); - } - - return sb.toString(); - } - -} diff --git a/src/main/java/org/springframework/shell/core/JLineShell.java b/src/main/java/org/springframework/shell/core/JLineShell.java deleted file mode 100644 index 402322d7..00000000 --- a/src/main/java/org/springframework/shell/core/JLineShell.java +++ /dev/null @@ -1,704 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import static org.fusesource.jansi.Ansi.ansi; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.nio.charset.Charset; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; - -import jline.WindowsTerminal; -import jline.console.ConsoleReader; -import jline.console.UserInterruptException; -import jline.console.history.History; -import jline.console.history.MemoryHistory; - -import org.apache.commons.io.input.ReversedLinesFileReader; -import org.fusesource.jansi.Ansi; -import org.fusesource.jansi.Ansi.Attribute; -import org.fusesource.jansi.Ansi.Color; -import org.fusesource.jansi.Ansi.Erase; -import org.fusesource.jansi.AnsiConsole; -import org.springframework.shell.event.ShellStatus; -import org.springframework.shell.event.ShellStatus.Status; -import org.springframework.shell.event.ShellStatusListener; -import org.springframework.shell.support.util.IOUtils; -import org.springframework.shell.support.util.OsUtils; -import org.springframework.shell.support.util.VersionUtils; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; - -/** - * Uses the feature-rich JLine library to provide an interactive - * shell. - * - *

- * Due to Windows' lack of color ANSI services out-of-the-box, this implementation automatically detects the classpath - * presence of Jansi and uses it if present. This library is not necessary - * for *nix machines, which support colour ANSI without any special effort. This implementation has been written to use - * reflection in order to avoid hard dependencies on Jansi. - * - * @author Ben Alex - * @author Jarred Li - * @author Glenn Renfro - * @since 1.0 - */ -public abstract class JLineShell extends AbstractShell implements Shell, Runnable { - - // Constants - private static final String ANSI_CONSOLE_CLASSNAME = "org.fusesource.jansi.AnsiConsole"; - - private static final boolean JANSI_AVAILABLE = ClassUtils.isPresent(ANSI_CONSOLE_CLASSNAME, - JLineShell.class.getClassLoader()); - - private static final char ESCAPE = 27; - - private static final String BEL = "\007"; - - // Fields - protected volatile ConsoleReader reader; - - private boolean developmentMode = false; - - private FileWriter fileLog; - - private final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - protected ShellStatusListener statusListener; // ROO-836 - - /** key: slot name, value: flashInfo instance */ - private final Map flashInfoMap = new HashMap(); - - /** key: row number, value: eraseLineFromPosition */ - private final Map rowErasureMap = new HashMap(); - - private boolean shutdownHookFired = false; // ROO-1599 - - private int historySize; - - public void run() { - reader = createConsoleReader(); - - setPromptPath(null); - - JLineLogHandler handler = new JLineLogHandler(reader, this); - JLineLogHandler.prohibitRedraw(); // Affects this thread only - Logger mainLogger = Logger.getLogger(""); - removeHandlers(mainLogger); - mainLogger.addHandler(handler); - - reader.addCompleter(new ParserCompleter(getParser())); - - reader.setBellEnabled(true); - if (Boolean.getBoolean("jline.nobell")) { - reader.setBellEnabled(false); - } - - // reader.setDebug(new PrintWriter(new FileWriter("writer.debug", true))); - - openFileLogIfPossible(); - History history = this.reader.getHistory(); - if (history instanceof MemoryHistory) { - ((MemoryHistory) history).setMaxSize(getHistorySize()); - } - // Try to build previous command history from the project's log - String[] filteredLogEntries = filterLogEntry(); - for (String logEntry : filteredLogEntries) { - reader.getHistory().add(logEntry); - } - - flashMessageRenderer(); - flash(Level.FINE, this.getProductName() + " " + this.getVersion(), Shell.WINDOW_TITLE_SLOT); - printBannerAndWelcome(); - - String startupNotifications = getStartupNotifications(); - if (StringUtils.hasText(startupNotifications)) { - logger.info(startupNotifications); - } - - setShellStatus(Status.STARTED); - - try { - // Monitor CTRL+C initiated shutdowns (ROO-1599) - Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { - public void run() { - shutdownHookFired = true; - } - }, getProductName() + " JLine Shutdown Hook")); - } - catch (Throwable t) { - } - - // Handle any "execute-then-quit" operation - - String rooArgs = System.getProperty("roo.args"); - if (rooArgs != null && !"".equals(rooArgs)) { - setShellStatus(Status.USER_INPUT); - boolean success = executeCommand(rooArgs).isSuccess(); - if (exitShellRequest == null) { - // The command itself did not specify an exit shell code, so we'll fall back to something sensible here - executeCommand("quit"); // ROO-839 - exitShellRequest = success ? ExitShellRequest.NORMAL_EXIT : ExitShellRequest.FATAL_EXIT; - } - setShellStatus(Status.SHUTTING_DOWN); - } - else { - // Normal RPEL processing - promptLoop(); - } - - } - - /** - * read history commands from history log. the history size if determined by --histsize options. - * - * @return history commands - */ - private String[] filterLogEntry() { - ArrayList entries = new ArrayList(); - ReversedLinesFileReader reversedReader = null; - try { - reversedReader = new ReversedLinesFileReader(new File(getHistoryFileName()), 4096, Charset.forName("UTF-8")); - int size = 0; - String line = null; - while ((line = reversedReader.readLine()) != null) { - if (!line.startsWith("//")) { - size++; - if (size > historySize) { - break; - } - else { - entries.add(line); - } - } - } - } - catch (IOException e) { - logger.warning("read history file failed. Reason:" + e.getMessage()); - } - finally { - closeReversedReader(reversedReader); - } - Collections.reverse(entries); - return entries.toArray(new String[0]); - } - - private void closeReversedReader(ReversedLinesFileReader reversedReader) { - if (reversedReader != null) { - try { - reversedReader.close(); - } - catch (IOException ex) { - logger.warning("Cloud not close ReversedLinesFileReader: " + ex); - } - } - - } - - /** - * Creates new jline ConsoleReader. On Windows if jansi is available, uses createAnsiWindowsReader(). Otherwise, - * always creates a default ConsoleReader. Sub-classes of this class can plug in their version of ConsoleReader by - * overriding this method, if required. - * - * @return a jline ConsoleReader instance - */ - protected ConsoleReader createConsoleReader() { - ConsoleReader consoleReader = null; - try { - if (isJansiAvailable()) { - try { - consoleReader = createAnsiWindowsReader(); - } - catch (Exception e) { - // Try again using default ConsoleReader constructor - logger.warning("Can't initialize jansi AnsiConsole, falling back to default: " + e); - } - } - if (consoleReader == null) { - consoleReader = new ConsoleReader(); - } - } - catch (IOException ioe) { - throw new IllegalStateException("Cannot start console class", ioe); - } - consoleReader.setExpandEvents(false); - consoleReader.setHandleUserInterrupt(true); - return consoleReader; - } - - private boolean isJansiAvailable() { - return JANSI_AVAILABLE && OsUtils.isWindows() && System.getProperty("jline.terminal") == null; - } - - public void printBannerAndWelcome() { - } - - public String getStartupNotifications() { - return null; - } - - private void removeHandlers(final Logger l) { - Handler[] handlers = l.getHandlers(); - if (handlers != null && handlers.length > 0) { - for (Handler h : handlers) { - l.removeHandler(h); - } - } - } - - @Override - public void setPromptPath(final String path) { - setPromptPath(path, false); - } - - @Override - public void setPromptPath(final String path, final boolean overrideStyle) { - if (reader.getTerminal().isAnsiSupported()) { - // ANSIBuffer ansi = JLineLogHandler.getANSIBuffer(); - Ansi ansi = ansi(); - if (path == null || "".equals(path)) { - shellPrompt = ansi.fg(Color.YELLOW).a(getPromptText()).reset().toString(); - } - else { - if (overrideStyle) { - ansi.a(path); - } - else { - ansi.fg(Color.CYAN).a(path).reset(); - } - shellPrompt = ansi.fg(Color.YELLOW).a(" " + getPromptText()).toString(); - } - } - else { - // The superclass will do for this non-ANSI terminal - super.setPromptPath(path); - } - - // The shellPrompt is now correct; let's ensure it now gets used - reader.setPrompt(AbstractShell.shellPrompt); - } - - protected ConsoleReader createAnsiWindowsReader() throws Exception { - // Get decorated OutputStream that parses ANSI-codes - final PrintStream ansiOut = (PrintStream) ClassUtils - .forName(ANSI_CONSOLE_CLASSNAME, JLineShell.class.getClassLoader()).getMethod("out").invoke(null); - WindowsTerminal ansiTerminal = new WindowsTerminal() { - @Override - public synchronized boolean isAnsiSupported() { - return true; - } - }; - ansiTerminal.init(); - // Make sure to reset the original shell's colors on shutdown by closing the stream - statusListener = new ShellStatusListener() { - public void onShellStatusChange(final ShellStatus oldStatus, final ShellStatus newStatus) { - if (newStatus.getStatus().equals(Status.SHUTTING_DOWN)) { - ansiOut.close(); - } - } - }; - addShellStatusListener(statusListener); - - // return new ConsoleReader(new FileInputStream(FileDescriptor.in), new PrintWriter(new OutputStreamWriter( - // ansiOut, - // // Default to Cp850 encoding for Windows console output (ROO-439) - // System.getProperty("jline.WindowsTerminal.output.encoding", "Cp850"))), null, ansiTerminal); - - OutputStream out = AnsiConsole.wrapOutputStream(ansiOut); - return new ConsoleReader(new FileInputStream(FileDescriptor.in), out, ansiTerminal); - } - - private void flashMessageRenderer() { - if (!reader.getTerminal().isAnsiSupported()) { - return; - } - // Setup a thread to ensure flash messages are displayed and cleared correctly - Thread t = new Thread(new Runnable() { - public void run() { - while (!shellStatus.getStatus().equals(Status.SHUTTING_DOWN) && !shutdownHookFired) { - synchronized (flashInfoMap) { - long now = System.currentTimeMillis(); - - Set toRemove = new HashSet(); - for (String slot : flashInfoMap.keySet()) { - FlashInfo flashInfo = flashInfoMap.get(slot); - - if (flashInfo.flashMessageUntil < now) { - // Message has expired, so clear it - toRemove.add(slot); - doAnsiFlash(flashInfo.rowNumber, Level.ALL, ""); - } - else { - // The expiration time for this message has not been reached, so preserve it - doAnsiFlash(flashInfo.rowNumber, flashInfo.flashLevel, flashInfo.flashMessage); - } - } - for (String slot : toRemove) { - flashInfoMap.remove(slot); - } - } - try { - Thread.sleep(200); - } - catch (InterruptedException ignore) { - } - } - } - }, getProductName() + " JLine Flash Message Manager"); - t.start(); - } - - @Override - public void flash(final Level level, final String message, final String slot) { - Assert.notNull(level, "Level is required for a flash message"); - Assert.notNull(message, "Message is required for a flash message"); - Assert.hasText(slot, "Slot name must be specified for a flash message"); - - if (Shell.WINDOW_TITLE_SLOT.equals(slot)) { - if (reader != null && reader.getTerminal().isAnsiSupported()) { - // We can probably update the window title, as requested - if (!StringUtils.hasText(message)) { - System.out.println("No text"); - } - - Ansi ansi = ansi(); - ansi.a(ESCAPE + "]0;").a(message).a(BEL); - try { - reader.print(ansi.toString()); - reader.flush(); - } - catch (IOException ignored) { - } - } - - return; - } - if ((reader != null && !reader.getTerminal().isAnsiSupported())) { - super.flash(level, message, slot); - return; - } - synchronized (flashInfoMap) { - FlashInfo flashInfo = flashInfoMap.get(slot); - - if ("".equals(message)) { - // Request to clear the message, but give the user some time to read it first - if (flashInfo == null) { - // We didn't have a record of displaying it in the first place, so just quit - return; - } - flashInfo.flashMessageUntil = System.currentTimeMillis() + 1500; - } - else { - // Display this message displayed until further notice - if (flashInfo == null) { - // Find a row for this new slot; we basically take the first line number we discover - flashInfo = new FlashInfo(); - flashInfo.rowNumber = Integer.MAX_VALUE; - outer: for (int i = 1; i < Integer.MAX_VALUE; i++) { - for (FlashInfo existingFlashInfo : flashInfoMap.values()) { - if (existingFlashInfo.rowNumber == i) { - // Veto, let's try the new candidate row number - continue outer; - } - } - // If we got to here, nobody owns this row number, so use it - flashInfo.rowNumber = i; - break outer; - } - - // Store it - flashInfoMap.put(slot, flashInfo); - } - // Populate the instance with the latest data - flashInfo.flashMessageUntil = Long.MAX_VALUE; - flashInfo.flashLevel = level; - flashInfo.flashMessage = message; - - // Display right now - doAnsiFlash(flashInfo.rowNumber, flashInfo.flashLevel, flashInfo.flashMessage); - } - } - } - - // Externally synchronized via the two calling methods having a mutex on flashInfoMap - private void doAnsiFlash(final int row, final Level level, final String message) { - Ansi ansi = ansi(); - if (isAppleTerminal()) { - ansi.a(ESCAPE + "7"); - } - else { - ansi.saveCursorPosition(); - } - - // Figure out the longest line we're presently displaying (or were) and erase the line from that position - int mostFurtherLeftColNumber = Integer.MAX_VALUE; - for (Integer candidate : rowErasureMap.values()) { - if (candidate < mostFurtherLeftColNumber) { - mostFurtherLeftColNumber = candidate; - } - } - - if (mostFurtherLeftColNumber == Integer.MAX_VALUE) { - // There is nothing to erase - } - else { - ansi.cursor(row, mostFurtherLeftColNumber); - ansi.eraseLine(Erase.FORWARD); // Clear what was present on the line - } - - if (("".equals(message))) { - // They want the line blank; we've already achieved this if needed via the erasing above - // Just need to record we no longer care about this line the next time doAnsiFlash is invoked - rowErasureMap.remove(row); - } - else { - if (shutdownHookFired) { - return; // ROO-1599 - } - // They want some message displayed - int startFrom = reader.getTerminal().getWidth() - message.length() + 1; - if (startFrom < 1) { - startFrom = 1; - } - ansi.cursor(row, startFrom); - ansi.a(Attribute.NEGATIVE_ON).a(message).a(Attribute.NEGATIVE_OFF); - // Record we want to erase from this positioning next time (so we clean up after ourselves) - rowErasureMap.put(row, startFrom); - } - if (isAppleTerminal()) { - ansi.a(ESCAPE + "8"); - } - else { - ansi.restorCursorPosition(); - } - - try { - reader.print(ansi.toString()); - reader.flush(); - } - catch (IOException ignored) { - } - } - /** - * Awaits user input, executes the command and displays the prompt to the user. - */ - public void promptLoop() { - setShellStatus(Status.USER_INPUT); - String line = null; - String prompt = getPromptText(); - - try { - while (exitShellRequest == null) { - try { - line = reader.readLine(); - } - catch (UserInterruptException e) { - if (e.getPartialLine().length() == 0) { - exitShellRequest = ExitShellRequest.FATAL_EXIT; - } - } - JLineLogHandler.resetMessageTracking(); - setShellStatus(Status.USER_INPUT); - - if (StringUtils.hasText(line)) { - executeCommand(line); - } - //update the prompt after the command has been executed in case an application event listener in the - //command changes state in the prompt provider. - prompt = generatePromptUpdate(prompt); - - } - } - catch (IOException ioe) { - throw new IllegalStateException("Shell line reading failure", ioe); - } - setShellStatus(Status.SHUTTING_DOWN); - } - - /** - * Retrieves the latest prompt and if the latest prompt is different than the existing prompt, - * the shellPrompt is updated. - * @param existingPrompt The prompt that is recognized as the current prompt. - * @return The prompt that the shellPrompt displays. - */ - public String generatePromptUpdate(String existingPrompt) { - String newPrompt = getPromptText(); - if (!ObjectUtils.nullSafeEquals(existingPrompt, newPrompt)) { - setPromptPath(null); - } - return newPrompt; - } - - public void setDevelopmentMode(final boolean developmentMode) { - JLineLogHandler.setIncludeThreadName(developmentMode); - JLineLogHandler.setSuppressDuplicateMessages(!developmentMode); // We want to see duplicate messages during - // development time (ROO-1873) - this.developmentMode = developmentMode; - } - - public boolean isDevelopmentMode() { - return this.developmentMode; - } - - private void openFileLogIfPossible() { - try { - fileLog = new FileWriter(getHistoryFileName(), true); - // First write, so let's record the date and time of the first user command - fileLog.write("// " + getProductName() + " " + versionInfo() + " log opened at " + df.format(new Date()) - + "\n"); - fileLog.flush(); - } - catch (IOException ignoreIt) { - } - } - - @Override - protected void logCommandToOutput(final String processedLine) { - if (fileLog == null) { - openFileLogIfPossible(); - if (fileLog == null) { - // Still failing, so give up - return; - } - } - try { - fileLog.write(processedLine + "\n"); // Unix line endings only from Roo - fileLog.flush(); // So tail -f will show it's working - if (getExitShellRequest() != null) { - // Shutting down, so close our file (we can always reopen it later if needed) - fileLog.write("// " + getProductName() + " " + versionInfo() + " log closed at " - + df.format(new Date()) + "\n"); - IOUtils.closeQuietly(fileLog); - fileLog = null; - } - } - catch (IOException ignoreIt) { - } - } - - /** - * Obtains the "roo.home" from the system property, falling back to the current working directory if missing. - * - * @return the 'roo.home' system property - */ - @Override - protected String getHomeAsString() { - String rooHome = System.getProperty("roo.home"); - if (rooHome == null) { - try { - rooHome = new File(".").getCanonicalPath(); - } - catch (Exception e) { - throw new IllegalStateException(e); - } - } - return rooHome; - } - - /** - * Should be called by a subclass before deactivating the shell. - */ - protected void closeShell() { - // Notify we're closing down (normally our status is already shutting_down, but if it was a CTRL+C via the - // o.s.r.bootstrap.Main hook) - setShellStatus(Status.SHUTTING_DOWN); - if (statusListener != null) { - removeShellStatusListener(statusListener); - } - } - - private static class FlashInfo { - String flashMessage; - - long flashMessageUntil; - - Level flashLevel; - - int rowNumber; - } - - /** - * get history file name from provider. The provider has highest order - * org.springframework.core.Ordered.getOder will win. - * - * @return history file name - */ - abstract protected String getHistoryFileName(); - - /** - * get prompt text from provider. The provider has highest order - * org.springframework.core.Ordered.getOder will win. - * - * @return prompt text - */ - abstract protected String getPromptText(); - - /** - * get product name - * - * @return Product Name - */ - abstract protected String getProductName(); - - /** - * get version information - * - * @return Version - */ - protected String getVersion() { - return VersionUtils.versionInfo(); - } - - /** - * @return the historySize - */ - public int getHistorySize() { - return historySize; - } - - /** - * @param historySize the historySize to set - */ - public void setHistorySize(int historySize) { - this.historySize = historySize; - } - - private static boolean isAppleTerminal() { - final String terminalName = System.getenv("TERM_PROGRAM"); - return ("Apple_Terminal".equalsIgnoreCase(terminalName) || Boolean.getBoolean("is.apple.terminal")); - } - -} diff --git a/src/main/java/org/springframework/shell/core/JLineShellComponent.java b/src/main/java/org/springframework/shell/core/JLineShellComponent.java deleted file mode 100644 index 39d44b50..00000000 --- a/src/main/java/org/springframework/shell/core/JLineShellComponent.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import java.util.Map; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.SmartLifecycle; -import org.springframework.shell.CommandLine; -import org.springframework.shell.plugin.BannerProvider; -import org.springframework.shell.plugin.HistoryFileNameProvider; -import org.springframework.shell.plugin.PluginUtils; -import org.springframework.shell.plugin.PromptProvider; - -/** - * Launcher for {@link JLineShell}. - * - * @author Ben Alex - * @since 1.1 - */ -public class JLineShellComponent extends JLineShell implements SmartLifecycle, ApplicationContextAware, InitializingBean { - - @Autowired - private CommandLine commandLine; - - private volatile boolean running = false; - private Thread shellThread; - - private ApplicationContext applicationContext; - private boolean printBanner = true; - - private String historyFileName; - private String promptText; - private String productName; - private String banner; - private String version; - private String welcomeMessage; - - private ExecutionStrategy executionStrategy = new SimpleExecutionStrategy(); - private SimpleParser parser = new SimpleParser(); - - public SimpleParser getSimpleParser() { - return parser; - } - - public boolean isAutoStartup() { - return false; - } - - public void stop(Runnable callback) { - stop(); - callback.run(); - } - - public int getPhase() { - return 1; - } - - public void start() { - //customizePlug must run before start thread to take plugin's configuration into effect - customizePlugin(); - shellThread = new Thread(this, "Spring Shell"); - shellThread.start(); - running = true; - } - - - public void stop() { - if (running) { - closeShell(); - running = false; - } - } - - public boolean isRunning() { - return running; - } - - @SuppressWarnings("rawtypes") - public void afterPropertiesSet() { - - Map commands = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, CommandMarker.class); - for (CommandMarker command : commands.values()) { - getSimpleParser().add(command); - } - - Map converters = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, Converter.class); - for (Converter converter : converters.values()) { - getSimpleParser().add(converter); - } - - setHistorySize(commandLine.getHistorySize()); - if (commandLine.getShellCommandsToExecute() != null) { - setPrintBanner(false); - } - } - - /** - * wait the shell command to complete by typing "quit" or "exit" - * - */ - public void waitForComplete() { - try { - shellThread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - @Override - protected ExecutionStrategy getExecutionStrategy() { - return executionStrategy; - } - - @Override - protected Parser getParser() { - return parser; - } - - @Override - public String getStartupNotifications() { - return null; - } - - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - public void customizePlugin() { - this.historyFileName = getHistoryFileName(); - this.promptText = getPromptText(); - String[] banner = getBannerText(); - this.banner = banner[0]; - this.welcomeMessage = banner[1]; - this.version = banner[2]; - this.productName = banner[3]; - } - - /** - * get history file name from provider. The provider has highest order - * org.springframework.core.Ordered.getOder will win. - * - * @return history file name - */ - protected String getHistoryFileName() { - HistoryFileNameProvider historyFileNameProvider = PluginUtils.getHighestPriorityProvider(this.applicationContext,HistoryFileNameProvider.class); - String providerHistoryFileName = historyFileNameProvider.getHistoryFileName(); - if (providerHistoryFileName != null) { - return providerHistoryFileName; - } else { - return historyFileName; - } - } - - /** - * get prompt text from provider. The provider has highest order - * org.springframework.core.Ordered.getOder will win. - * - * @return prompt text - */ - protected String getPromptText() { - PromptProvider promptProvider = PluginUtils.getHighestPriorityProvider(this.applicationContext,PromptProvider.class); - String providerPromptText = promptProvider.getPrompt(); - if (providerPromptText != null) { - return providerPromptText; - } else { - return promptText; - } - } - - /** - * Get Banner and Welcome Message from provider. The provider has highest order - * org.springframework.core.Ordered.getOder will win. - * @return BannerText[0]: Banner - * BannerText[1]: Welcome Message - * BannerText[2]: Version - * BannerText[3]: Product Name - */ - private String[] getBannerText() { - String[] bannerText = new String[4]; - BannerProvider provider = PluginUtils.getHighestPriorityProvider(this.applicationContext,BannerProvider.class); - bannerText[0] = provider.getBanner(); - bannerText[1] = provider.getWelcomeMessage(); - bannerText[2] = provider.getVersion(); - bannerText[3] = provider.getProviderName(); - return bannerText; - } - - - public void printBannerAndWelcome() { - if (printBanner) { - logger.info(this.banner); - logger.info(getWelcomeMessage()); - } - } - - - /** - * get the welcome message at start. - * - * @return welcome message - */ - public String getWelcomeMessage() { - return this.welcomeMessage; - } - - - /** - * @param printBanner the printBanner to set - */ - public void setPrintBanner(boolean printBanner) { - this.printBanner = printBanner; - } - - protected String getProductName() { - return productName; - } - - protected String getVersion() { - return version; - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/core/MethodTarget.java b/src/main/java/org/springframework/shell/core/MethodTarget.java deleted file mode 100644 index 15d910a3..00000000 --- a/src/main/java/org/springframework/shell/core/MethodTarget.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import java.lang.reflect.Method; - -import org.springframework.core.style.ToStringCreator; -import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; - -/** - * A method that can be executed via a shell command. - *

- * Immutable since 1.2.0. - * - * @author Ben Alex - */ -public class MethodTarget { - - // Fields - private final Method method; - - private final Object target; - - private final String remainingBuffer; - - private final String key; - - /** - * Constructor for a null remainingBuffer and key - * - * @param method the method to invoke (required) - * @param target the object on which the method is to be invoked (required) - * @since 1.2.0 - */ - public MethodTarget(final Method method, final Object target) { - this(method, target, null, null); - } - - /** - * Constructor that allows all fields to be set - * - * @param method the method to invoke (required) - * @param target the object on which the method is to be invoked (required) - * @param remainingBuffer can be blank - * @param key can be blank - * @since 1.2.0 - */ - public MethodTarget(final Method method, final Object target, final String remainingBuffer, final String key) { - Assert.notNull(method, "Method is required"); - Assert.notNull(target, "Target is required"); - this.key = StringUtils.trimWhitespace(key); - this.method = method; - this.remainingBuffer = remainingBuffer; - this.target = target; - } - - @Override - public boolean equals(final Object other) { - if (other == this) { - return true; - } - if (!(other instanceof MethodTarget)) { - return false; - } - final MethodTarget otherMethodTarget = (MethodTarget) other; - return this.method.equals(otherMethodTarget.getMethod()) && this.target.equals(otherMethodTarget.getTarget()); - } - - @Override - public int hashCode() { - return ObjectUtils.nullSafeHashCode(method) + ObjectUtils.nullSafeHashCode(target); - } - - @Override - public final String toString() { - final ToStringCreator tsc = new ToStringCreator(this); - tsc.append("target", target); - tsc.append("method", method); - tsc.append("remainingBuffer", remainingBuffer); - tsc.append("key", key); - return tsc.toString(); - } - - /** - * @since 1.2.0 - */ - public String getKey() { - return this.key; - } - - /** - * @return a non-null method - * @since 1.2.0 - */ - public Method getMethod() { - return this.method; - } - - /** - * @since 1.2.0 - */ - public String getRemainingBuffer() { - return this.remainingBuffer; - } - - /** - * @return a non-null Object - * @since 1.2.0 - */ - public Object getTarget() { - return this.target; - } -} diff --git a/src/main/java/org/springframework/shell/core/Parser.java b/src/main/java/org/springframework/shell/core/Parser.java deleted file mode 100644 index 2e095407..00000000 --- a/src/main/java/org/springframework/shell/core/Parser.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import java.util.List; - -import org.springframework.shell.event.ParseResult; - -/** - * Interface for {@link SimpleParser}. - * - * @author Ben Alex - * @author Alan Stewart - * @since 1.0 - */ -public interface Parser { - - ParseResult parse(String buffer); - - /** - * Populates a list of completion candidates. This method is required for backward compatibility for STS versions up to 2.8.0. - * - * @param buffer - * @param cursor - * @param candidates - * @return - */ - int complete(String buffer, int cursor, List candidates); - - /** - * Populates a list of completion candidates. - * - * @param buffer - * @param cursor - * @param candidates - * @return - */ - int completeAdvanced(String buffer, int cursor, List candidates); -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/core/ParserCompleter.java b/src/main/java/org/springframework/shell/core/ParserCompleter.java deleted file mode 100644 index b0c9ede5..00000000 --- a/src/main/java/org/springframework/shell/core/ParserCompleter.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import java.util.ArrayList; -import java.util.List; - -import jline.console.completer.Completer; - -import org.springframework.util.Assert; - -/** - * An implementation of JLine's {@link Completer} interface that delegates to a {@link Parser}. - * - * @author Ben Alex - * @since 1.0 - */ -public class ParserCompleter implements Completer { - - // Fields - private final Parser parser; - - public ParserCompleter(final Parser parser) { - Assert.notNull(parser, "Parser required"); - this.parser = parser; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public int complete(final String buffer, final int cursor, final List candidates) { - int result; - try { - JLineLogHandler.cancelRedrawProhibition(); - List completions = new ArrayList(); - result = parser.completeAdvanced(buffer, cursor, completions); - for (Completion completion : completions) { - candidates.add(completion.getValue()); - } - } - finally { - JLineLogHandler.prohibitRedraw(); - } - return result; - } -} diff --git a/src/main/java/org/springframework/shell/core/Shell.java b/src/main/java/org/springframework/shell/core/Shell.java deleted file mode 100644 index 9fbce5e2..00000000 --- a/src/main/java/org/springframework/shell/core/Shell.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import java.io.File; -import java.util.logging.Level; - -import org.springframework.shell.event.ShellStatusProvider; - -/** - * Specifies the contract for an interactive shell. - * - *

- * Any interactive shell class which implements these methods can be launched by the roo-bootstrap mechanism. - * - *

- * It is envisaged implementations will be provided for JLine initially, with possible implementations for - * Eclipse in the future. - * - * @author Ben Alex - * @since 1.0 - */ -public interface Shell extends ShellStatusProvider, ShellPromptAccessor { - - /** - * The slot name to use with {@link #flash(Level, String, String)} if a caller wishes to modify the window title. - * This may not be supported by all operating system shells. It is provided on a best-effort basis only. - */ - String WINDOW_TITLE_SLOT = "WINDOW_TITLE_SLOT"; - - /** - * Presents a console prompt and allows the user to interact with the shell. The shell should not return - * to the caller until the user has finished their session (by way of a "quit" or similar command). - */ - void promptLoop(); - - /** - * @return null if no exit was requested, otherwise the last exit code indicated to the shell to use - */ - ExitShellRequest getExitShellRequest(); - - /** - * Runs the specified command. Control will return to the caller after the command is run. - * - * @param line to execute (required) - * @return true if the command was successful, false if there was an exception - */ - CommandResult executeCommand(String line); - - /** - * Indicates the shell should switch into a lower-level development mode. The exact meaning varies by - * shell implementation. - * - * @param developmentMode true if development mode should be enabled, false otherwise - */ - void setDevelopmentMode(boolean developmentMode); - - /** - * Displays a progress notification to the user. This notification will ideally be displayed in a - * consistent screen location by the shell implementation. - * - *

- * An implementation may allow multiple messages to be displayed concurrently. So an implementation can - * determine when a flash message replaces a previous flash message, callers should allocate a unique - * "slot" name for their messages. It is suggested the class name of the caller be used. This way a - * slot will be updated without conflicting with flash message sequences from other slots. - * - *

- * Passing an empty string in as the "message" indicates the slot should be cleared. - * - *

- * An implementation need not necessarily use the level or slot concepts. They are expected to be - * used in most cases, though. - * - * @param level the importance of the message (cannot be null) - * @param message to display (cannot be null, but may be empty) - * @param slot the identification slot for the message (cannot be null or empty) - */ - void flash(Level level, String message, String slot); - - boolean isDevelopmentMode(); - - /** - * Changes the "path" displayed in the shell prompt. An implementation will ensure this path is - * included on the screen, taking care to merge it with the product name and handle any special - * formatting requirements (such as ANSI, if supported by the implementation). - * - * @param path to set (can be null or empty; must NOT be formatted in any special way eg ANSI codes) - */ - void setPromptPath(String path); - - void setPromptPath(String path, boolean overrideStyle); - - /** - * Returns the home directory of the current running shell instance - * - * @return the home directory of the current shell instance - */ - File getHome(); -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/core/ShellPromptAccessor.java b/src/main/java/org/springframework/shell/core/ShellPromptAccessor.java deleted file mode 100644 index 2b3e85a1..00000000 --- a/src/main/java/org/springframework/shell/core/ShellPromptAccessor.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - - -/** - * Obtains the prompt used by a {@link Shell}. - * - * @author Ben Alex - * @since 1.0 - */ -public interface ShellPromptAccessor { - - /** - * @return the shell prompt (never null; the result may include special characters such as ANSI - * escape codes if the implementation is using them) - */ - String getShellPrompt(); -} diff --git a/src/main/java/org/springframework/shell/core/SimpleExecutionStrategy.java b/src/main/java/org/springframework/shell/core/SimpleExecutionStrategy.java deleted file mode 100644 index 979767a0..00000000 --- a/src/main/java/org/springframework/shell/core/SimpleExecutionStrategy.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2011-2016 the original author or authors. - * - * 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.springframework.shell.core; - -import java.lang.reflect.Method; -import java.util.logging.Logger; - -import org.springframework.shell.event.ParseResult; -import org.springframework.shell.support.logging.HandlerUtils; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; - -/** - * Simple execution strategy for invoking a target method. - * Supports pre/post processing to allow {@link CommandMarker}s for aop-like behavior ( - * typically used for controlling stateful objects). - * - * @author Mark Pollack - * @author Costin Leau - * @author Oliver Gierke - */ -public class SimpleExecutionStrategy implements ExecutionStrategy { - - private static final Logger logger = HandlerUtils.getLogger(SimpleExecutionStrategy.class); - - private final Class mutex = SimpleExecutionStrategy.class; - - public Object execute(ParseResult parseResult) throws RuntimeException { - Assert.notNull(parseResult, "Parse result required"); - synchronized (mutex) { - Assert.isTrue(isReadyForCommands(), "SimpleExecutionStrategy not yet ready for commands"); - Object target = parseResult.getInstance(); - if (target instanceof ExecutionProcessor) { - ExecutionProcessor processor = ((ExecutionProcessor) target); - parseResult = processor.beforeInvocation(parseResult); - try { - Object result = invoke(parseResult); - processor.afterReturningInvocation(parseResult, result); - return result; - } catch (Throwable th) { - processor.afterThrowingInvocation(parseResult, th); - return handleThrowable(th); - } - } - else { - return invoke(parseResult); - } - } - } - - private Object invoke(ParseResult parseResult) { - try { - Method method = parseResult.getMethod(); - ReflectionUtils.makeAccessible(method); - return ReflectionUtils.invokeMethod(method, parseResult.getInstance(), parseResult.getArguments()); - } catch (Throwable th) { - logger.severe("Command failed " + th); - return handleThrowable(th); - } - } - - private Object handleThrowable(Throwable th) { - if (th instanceof Error) { - throw ((Error) th); - } - if (th instanceof RuntimeException) { - throw ((RuntimeException) th); - } - throw new RuntimeException(th); - } - - public boolean isReadyForCommands() { - return true; - } - - public void terminate() { - // do nothing - } - -} diff --git a/src/main/java/org/springframework/shell/core/SimpleParser.java b/src/main/java/org/springframework/shell/core/SimpleParser.java deleted file mode 100644 index a87d2107..00000000 --- a/src/main/java/org/springframework/shell/core/SimpleParser.java +++ /dev/null @@ -1,1149 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.logging.Logger; - -import org.springframework.shell.core.annotation.CliAvailabilityIndicator; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; -import org.springframework.shell.event.ParseResult; -import org.springframework.shell.support.logging.HandlerUtils; -import org.springframework.shell.support.util.ExceptionUtils; -import org.springframework.shell.support.util.NaturalOrderComparator; -import org.springframework.shell.support.util.OsUtils; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -/** - * Default implementation of {@link Parser}. - * @author Ben Alex - * @since 1.0 - */ -public class SimpleParser implements Parser { - - // Constants - private static final Logger LOGGER = HandlerUtils.getLogger(SimpleParser.class); - - private static final Comparator COMPARATOR = new NaturalOrderComparator(); - - // Fields - private final Object mutex = new Object(); - - private final Set> converters = new HashSet>(); - - private final Set commands = new HashSet(); - - private final Map availabilityIndicators = new HashMap(); - - /** - * The last buffer when completion was requested. - */ - private String previousCompletionBuffer; - - /** - * The number of times completion has been requested with the same buffer. - */ - private int successiveCompletionRequests = 1; - - private MethodTarget getAvailabilityIndicator(final String command) { - return availabilityIndicators.get(command); - } - - /** - * get all mandatory options keys. For the options with multiple keys, the keys will be in one row. - * @param cliOptions options - * @return mandatory options keys - */ - private List> getMandatoryOptionsKeys(Collection cliOptions) { - return getOptionsKeys(cliOptions, false); - } - - /** - * get all options key. - * @param cliOptions - * @param includeOptionalOptions - * @return options keys - */ - private List> getOptionsKeys(Collection cliOptions, boolean includeOptionalOptions) { - List> optionsKeys = new ArrayList>(); - for (CliOption option : cliOptions) { - if (includeOptionalOptions) { - List keys = new ArrayList(); - keys.addAll(Arrays.asList(option.key())); - optionsKeys.add(keys); - } - else if (option.mandatory()) { - List keys = new ArrayList(); - keys.addAll(Arrays.asList(option.key())); - optionsKeys.add(keys); - } - } - return optionsKeys; - } - - @Override - public ParseResult parse(final String rawInput) { - synchronized (mutex) { - Assert.notNull(rawInput, "Raw input required"); - final String input = rawInput.trim(); - - resetCompletionInvocations(); - - // Locate the applicable targets which match this buffer - final Collection matchingTargets = locateTargets(input, true, true); - if (matchingTargets.isEmpty()) { - // Before we just give up, let's see if we can offer a more informative message to the user - // by seeing the command is simply unavailable at this point in time - matchingTargets.addAll(locateTargets(input, true, false)); - if (matchingTargets.isEmpty()) { - commandNotFound(LOGGER, input); - } - else { - LOGGER.warning("Command '" - + input - + "' was found but is not currently available (type 'help' then ENTER to learn about this command)"); - } - return null; - } - MethodTarget methodTarget = null; - if (matchingTargets.size() > 1) { - // Any prefix of a valid command will do. Don't fail if the user used - // the exact key of a command though. - for (MethodTarget candidate : matchingTargets) { - if (candidate.getKey().equals(input) || input.startsWith(candidate.getKey() + " ")) { - methodTarget = candidate; - break; - } - } - if (methodTarget == null) { - LOGGER.warning("Ambigious command '" + input + "' (for assistance press " - + AbstractShell.completionKeys + " or type \"hint\" then hit ENTER)"); - return null; - } - } - else { - methodTarget = matchingTargets.iterator().next(); - } - - // Argument conversion time - Annotation[][] parameterAnnotations = methodTarget.getMethod().getParameterAnnotations(); - if (parameterAnnotations.length == 0) { - // No args - return new ParseResult(methodTarget.getMethod(), methodTarget.getTarget(), null); - } - - // Oh well, we need to convert some arguments - final List arguments = new ArrayList(methodTarget.getMethod().getParameterTypes().length); - - // Attempt to parse - Map options = null; - try { - options = new Tokenizer(methodTarget.getRemainingBuffer()).getTokens(); - } - catch (TokenizingException te) { - String commandKey = methodTarget.getKey(); - reportTokenizingException(commandKey, te); - return null; - } - catch (IllegalArgumentException e) { - LOGGER.warning(ExceptionUtils.extractRootCause(e).getMessage()); - return null; - } - - final Set cliOptions = getCliOptions(parameterAnnotations); - for (CliOption cliOption : cliOptions) { - Class requiredType = methodTarget.getMethod().getParameterTypes()[arguments.size()]; - - if (cliOption.systemProvided()) { - Object result; - if (SimpleParser.class.isAssignableFrom(requiredType)) { - result = this; - } - else { - LOGGER.warning("Parameter type '" + requiredType + "' is not system provided"); - return null; - } - arguments.add(result); - continue; - } - - // Obtain the value the user specified, taking care to ensure they only specified it via a single alias - String value = null; - String sourcedFrom = null; - for (String possibleKey : cliOption.key()) { - if (options.containsKey(possibleKey)) { - if (sourcedFrom != null) { - LOGGER.warning("You cannot specify option '" + possibleKey - + "' when you have also specified '" + sourcedFrom + "' in the same command"); - return null; - } - sourcedFrom = possibleKey; - value = options.get(possibleKey); - } - } - - // Ensure the user specified a value if the value is mandatory or - // key and value must appear in pair - boolean mandatory = cliOption.mandatory(); - boolean specifiedKey = options.containsKey(sourcedFrom); - boolean specifiedKeyWithoutValue = specifiedKey && "".equals(value); - if (mandatory && (!specifiedKey || specifiedKeyWithoutValue)) { - if (isDefaultOption(cliOption)) { - StringBuilder message = new StringBuilder("You should specify "); - message.append(optionAliases(cliOption)); - message.append(" for this command"); - LOGGER.warning(message.toString()); - } - else { - printHintMessage(cliOptions, options); - } - return null; - } - - // Accept a default if the user specified the option, but didn't provide a value - if (specifiedKeyWithoutValue) { - value = cliOption.specifiedDefaultValue(); - } - else if (!specifiedKey) { - // Accept a default if the user didn't specify the option at all - value = cliOption.unspecifiedDefaultValue(); - } - - // Special token that denotes a null value is sought (useful for default values) - if ("__NULL__".equals(value)) { - if (requiredType.isPrimitive()) { - LOGGER.warning("Nulls cannot be presented to primitive type " + requiredType.getSimpleName() - + " for option '" + StringUtils.arrayToCommaDelimitedString(cliOption.key()) + "'"); - return null; - } - arguments.add(null); - continue; - } - - // Now we're ready to perform a conversion - try { - Object result; - Converter c = null; - for (Converter candidate : converters) { - if (candidate.supports(requiredType, cliOption.optionContext())) { - // Found a usable converter - c = candidate; - break; - } - } - if (c == null) { - throw new IllegalStateException("TODO: Add basic type conversion"); - // TODO Fall back to a normal SimpleTypeConverter and attempt conversion - // SimpleTypeConverter simpleTypeConverter = new SimpleTypeConverter(); - // result = simpleTypeConverter.convertIfNecessary(value, requiredType, mp); - } - - // Use the converter - result = c.convertFromText(value, requiredType, cliOption.optionContext()); - - // If the option has been specified to be mandatory then the result should never be null - if (result == null && cliOption.mandatory()) { - throw new IllegalStateException(); - } - arguments.add(result); - } - catch (RuntimeException e) { - LOGGER.warning(e.getClass().getName() + ": Failed to convert '" + value + "' to type " - + requiredType.getSimpleName() + " for option '" - + StringUtils.arrayToCommaDelimitedString(cliOption.key()) + "'"); - if (StringUtils.hasText(e.getMessage())) { - LOGGER.warning(e.getMessage()); - } - return null; - } - } - - // Check for options specified by the user but are unavailable for the command - Set unavailableOptions = getSpecifiedUnavailableOptions(cliOptions, options); - if (!unavailableOptions.isEmpty()) { - StringBuilder message = new StringBuilder(); - if (unavailableOptions.size() == 1) { - message.append("Option '").append(unavailableOptions.iterator().next()) - .append("' is not available for this command. "); - } - else { - message.append("Options ") - .append(StringUtils.collectionToDelimitedString(unavailableOptions, ", ", "'", "'")) - .append(" are not available for this command. "); - } - message.append("Use tab assist or the \"help\" command to see the legal options"); - LOGGER.warning(message.toString()); - return null; - } - - return new ParseResult(methodTarget.getMethod(), methodTarget.getTarget(), arguments.toArray()); - } - } - - /** - * We're being asked to execute a command, so the next completion invocation will definitely refer to a different - * buffer. - */ - private void resetCompletionInvocations() { - previousCompletionBuffer = null; - successiveCompletionRequests = 1; - } - - /** - * Return true if the given option is the 'default' option, that is, one of its key is the empty String. - */ - private boolean isDefaultOption(CliOption option) { - for (String key : option.key()) { - if ("".equals(key)) { - return true; - } - } - return false; - } - - /** - * Return a plain string description of the available aliases for a given option. - */ - private CharSequence optionAliases(CliOption option) { - StringBuilder result = new StringBuilder(); - if (isDefaultOption(option)) { - result.append("a default option"); - } - if (option.key().length > 1) { - result.append(", otherwise known as "); - } - boolean comma = false; - for (String key : option.key()) { - if (!"".equals(key)) { - if (comma) { - result.append(", "); - } - result.append("'").append(key).append("'"); - comma = true; - } - } - return result; - } - - private void reportTokenizingException(String commandKey, TokenizingException te) { - StringBuilder caret = new StringBuilder(); - for (int i = 0; i < te.getOffendingOffset() + commandKey.length() + 1; i++) { - caret.append(" "); - } - LOGGER.warning(commandKey + " " + te.getBuffer()); - LOGGER.warning(caret + "^"); - LOGGER.warning(te.getReason()); - } - - /** - * @param cliOptions - * @param options - */ - private void printHintMessage(final Set cliOptions, Map options) { - boolean hintForOptions = true; - - StringBuilder optionBuilder = new StringBuilder(); - optionBuilder.append("You should specify option ("); - - StringBuilder valueBuilder = new StringBuilder(); - valueBuilder.append("You should specify value for option '"); - - List> optionsKeys = getOptionsKeys(cliOptions, true); - for (List keys : optionsKeys) { - boolean found = false; - for (String key : keys) { - if (options.containsKey(key)) { - if (!StringUtils.hasLength(options.get(key))) { - valueBuilder.append(key); - valueBuilder.append("' for this command"); - hintForOptions = false; - } - found = true; - break; - } - } - if (!found) { - optionBuilder.append("--"); - optionBuilder.append(keys.get(0)); - optionBuilder.append(", "); - } - } - // remove the ", " in the end. - String hintForOption = optionBuilder.toString(); - hintForOption = hintForOption.substring(0, hintForOption.length() - 2); - if (hintForOptions) { - LOGGER.warning(hintForOption + ") for this command"); - } - else { - LOGGER.warning(valueBuilder.toString()); - } - - } - - private Set getSpecifiedUnavailableOptions(final Set cliOptions, - final Map options) { - Set cliOptionKeySet = new LinkedHashSet(); - for (CliOption cliOption : cliOptions) { - for (String key : cliOption.key()) { - cliOptionKeySet.add(key); - } - } - Set unavailableOptions = new LinkedHashSet(); - for (String suppliedOption : options.keySet()) { - if (!cliOptionKeySet.contains(suppliedOption)) { - unavailableOptions.add(suppliedOption); - } - } - return unavailableOptions; - } - - private Set getCliOptions(final Annotation[][] parameterAnnotations) { - Set cliOptions = new LinkedHashSet(); - for (Annotation[] annotations : parameterAnnotations) { - for (Annotation annotation : annotations) { - if (annotation instanceof CliOption) { - CliOption cliOption = (CliOption) annotation; - cliOptions.add(cliOption); - } - } - } - return cliOptions; - } - - protected void commandNotFound(final Logger logger, final String buffer) { - logger.warning("Command '" + buffer + "' not found (for assistance press " + AbstractShell.completionKeys + ")"); - } - - private Collection locateTargets(final String buffer, final boolean strictMatching, - final boolean checkAvailabilityIndicators) { - Assert.notNull(buffer, "Buffer required"); - final Collection result = new HashSet(); - - // The reflection could certainly be optimised, but it's good enough for now (and cached reflection - // is unlikely to be noticeable to a human being using the CLI) - for (final CommandMarker command : commands) { - for (final Method method : command.getClass().getMethods()) { - CliCommand cmd = method.getAnnotation(CliCommand.class); - if (cmd != null) { - // We have a @CliCommand. - if (checkAvailabilityIndicators) { - // Decide if this @CliCommand is available at this moment - Boolean available = null; - for (String value : cmd.value()) { - MethodTarget mt = getAvailabilityIndicator(value); - if (mt != null) { - Assert.isNull(available, "More than one availability indicator is defined for '" - + method.toGenericString() + "'"); - try { - available = (Boolean) mt.getMethod().invoke(mt.getTarget()); - // We should "break" here, but we loop over all to ensure no conflicting - // availability indicators are defined - } - catch (Exception e) { - available = false; - } - } - } - // Skip this @CliCommand if it's not available - if (available != null && !available) { - continue; - } - } - - for (String value : cmd.value()) { - String remainingBuffer = isMatch(buffer, value, strictMatching); - if (remainingBuffer != null) { - result.add(new MethodTarget(method, command, remainingBuffer, value)); - } - } - } - } - } - return result; - } - - /** - * See whether 'buffer' could be an invocation of 'command', and if so, return the remaining part of the buffer. - * @param strictMatching true if ALL words of 'command' need to be matched - */ - static String isMatch(final String buffer, final String command, final boolean strictMatching) { - Assert.isTrue(command.charAt(command.length() - 1) != ' ', "Command must not end with a space"); - if ("".equals(buffer.trim())) { - return ""; - } - - if (buffer.length() <= command.length()) { - // Buffer is shorter or equal in length to command - int lastSpaceIndex = command.lastIndexOf(' '); - if (strictMatching && lastSpaceIndex >= 0) { - // Check buffer touches last command word - if (buffer.length() < lastSpaceIndex + 2) { - return null; - } - } - // Just need to check buffer is a prefix of command - if (command.startsWith(buffer)) { - return ""; - } - else { - return null; - } - } - else { - // Buffer is longer than command. Check command is a prefix of buffer. - if (!buffer.startsWith(command)) { - return null; - } - - String bufferRemaining = buffer.substring(command.length()); - if (bufferRemaining.length() > 0) { - // Check first char after command is a space - if (bufferRemaining.charAt(0) != ' ') { - return null; - } - return bufferRemaining.substring(1); - } - return bufferRemaining; - } - } - - @Override - public int complete(String buffer, int cursor, final List candidates) { - final List completions = new ArrayList(); - int result = completeAdvanced(buffer, cursor, completions); - for (final Completion completion : completions) { - candidates.add(completion.getValue()); - } - return result; - } - - @Override - public int completeAdvanced(String buffer, int cursor, final List candidates) { - synchronized (mutex) { - Assert.notNull(buffer, "Buffer required"); - Assert.notNull(candidates, "Candidates list required"); - - // Remove all spaces from beginning of command - while (buffer.startsWith(" ")) { - buffer = buffer.replaceFirst("^ ", ""); - cursor--; - } - - // Begin by only including the portion of the buffer represented to the present cursor position - String translated = buffer.substring(0, cursor); - - String successiveInvocationContext = trackSuccessiveCompletionRequests(translated); - - // Start by locating a method that matches - final Collection targets = locateTargets(translated, false, true); - SortedSet results = new TreeSet(COMPARATOR); - - if (targets.isEmpty()) { - // Nothing matches the buffer they've presented - return -1; - } - if (targets.size() > 1) { - // Assist them locate a particular target - for (MethodTarget target : targets) { - // Calculate the correct starting position - int startAt = translated.length(); - - // Only add the first word of each target - int stopAt = target.getKey().indexOf(" ", startAt); - if (stopAt == -1) { - stopAt = target.getKey().length(); - } - - results.add(new Completion(target.getKey().substring(0, stopAt) + " ")); - } - candidates.addAll(results); - return 0; - } - - // There is a single target of this method, so provide completion services for it - MethodTarget methodTarget = targets.iterator().next(); - - // Identify the command we're working with - CliCommand cmd = methodTarget.getMethod().getAnnotation(CliCommand.class); - Assert.notNull(cmd, "CliCommand unavailable for '" + methodTarget.getMethod().toGenericString() + "'"); - - // Make a reasonable attempt at parsing the remainingBuffer - Tokenizer tokenizer = null; - try { - tokenizer = new Tokenizer(methodTarget.getRemainingBuffer(), true); - } - catch (TokenizingException e) { - // Make sure we don't crash the main shell loop just - // because the user specified some option twice - return -1; - } - catch (IllegalArgumentException e) { - // Make sure we don't crash the main shell loop just - // because the user specified some option twice - return -1; - } - Map options = tokenizer.getTokens(); - - // Lookup arguments for this target - Annotation[][] parameterAnnotations = methodTarget.getMethod().getParameterAnnotations(); - - // If there aren't any parameters for the method, at least ensure they have typed the command properly - if (parameterAnnotations.length == 0) { - for (String value : cmd.value()) { - if (buffer.startsWith(value) || value.startsWith(buffer)) { - results.add(new Completion(value)); // no space at the end, as there's no need to continue the - // command further - } - } - candidates.addAll(results); - return 0; - } - - // If they haven't specified any parameters yet, at least verify the command name is fully completed - if (options.isEmpty()) { - for (String value : cmd.value()) { - if (value.startsWith(buffer)) { - // They are potentially trying to type this command - // We only need provide completion, though, if they failed to specify it fully - if (!buffer.startsWith(value)) { - // They failed to specify the command fully - results.add(new Completion(value + " ")); - } - } - } - - // Only quit right now if they have to finish specifying the command name - if (results.size() > 0) { - candidates.addAll(results); - return 0; - } - } - - // To get this far, we know there are arguments required for this CliCommand, and they specified a valid - // command name - - // Record all the CliOptions applicable to this command - List cliOptions = new ArrayList(); - for (Annotation[] annotations : parameterAnnotations) { - CliOption cliOption = null; - for (Annotation a : annotations) { - if (a instanceof CliOption) { - cliOption = (CliOption) a; - } - } - Assert.notNull(cliOption, "CliOption not found for parameter '" + Arrays.toString(annotations) + "'"); - cliOptions.add(cliOption); - } - - // Make a list of all CliOptions they've already included or are system-provided - List alreadySpecified = new ArrayList(); - for (CliOption option : cliOptions) { - for (String value : option.key()) { - if (options.containsKey(value)) { - alreadySpecified.add(option); - break; - } - } - if (option.systemProvided()) { - alreadySpecified.add(option); - } - } - - // Make a list of all CliOptions they have not provided - List unspecified = new ArrayList(cliOptions); - unspecified.removeAll(alreadySpecified); - - // Determine whether they're presently editing an option key or an option value - // (and if possible, the full or partial name of the said option key being edited) - String lastOptionKey = null; - String lastOptionValue = null; - - // The last item in the options map is *always* the option key they're editing (will never be null) - if (options.size() > 0) { - lastOptionKey = new ArrayList(options.keySet()).get(options.keySet().size() - 1); - lastOptionValue = options.get(lastOptionKey); - } - - // Handle if they are trying to find out the available option keys; always present option keys in order - // of their declaration on the method signature, thus we can stop when mandatory options are filled in - if (methodTarget.getRemainingBuffer().endsWith("--") && !tokenizer.openingQuotesHaveNotBeenClosed()) { - boolean showAllRemaining = true; - for (CliOption include : unspecified) { - if (include.mandatory()) { - showAllRemaining = false; - break; - } - } - - for (CliOption include : unspecified) { - for (String value : include.key()) { - if (!"".equals(value)) { - results.add(new Completion(translated + value + " ")); - } - } - if (!showAllRemaining) { - break; - } - } - candidates.addAll(results); - return 0; - } - - // Handle suggesting an option key if they haven't got one presently specified (or they've completed a full - // option key/value pair) - if (lastOptionKey == null - || (!"".equals(lastOptionKey) && !"".equals(lastOptionValue) && translated.endsWith(" ") && !tokenizer - .openingQuotesHaveNotBeenClosed())) { - // We have either NEVER specified an option key/value pair - // OR we have specified a full option key/value pair - - // Let's list some other options the user might want to try (naturally skip the "" option, as that's the - // default) - for (CliOption include : unspecified) { - for (String value : include.key()) { - // Manually determine if this non-mandatory but unspecifiedDefaultValue=* requiring option is - // able to be bound - if (!include.mandatory() && "*".equals(include.unspecifiedDefaultValue()) && !"".equals(value)) { - try { - for (Converter candidate : converters) { - // Find the target parameter - Class paramType = null; - int index = -1; - for (Annotation[] a : methodTarget.getMethod().getParameterAnnotations()) { - index++; - for (Annotation an : a) { - if (an instanceof CliOption) { - if (an.equals(include)) { - // Found the parameter, so store it - paramType = methodTarget.getMethod().getParameterTypes()[index]; - break; - } - } - } - } - if (paramType != null && candidate.supports(paramType, include.optionContext())) { - // Try to invoke this usable converter - candidate.convertFromText("*", paramType, include.optionContext()); - // If we got this far, the converter is happy with "*" so we need not bother the - // user with entering the data in themselves - break; - } - } - } - catch (RuntimeException notYetReady) { - if (translated.endsWith(" ")) { - results.add(new Completion(translated + "--" + value + " ")); - } - else { - results.add(new Completion(translated + " --" + value + " ")); - } - continue; - } - } - - // Handle normal mandatory options - if (!"".equals(value) && include.mandatory()) { - handleMandatoryCompletion(translated, unspecified, value, results); - } - } - } - - // Only abort at this point if we have some suggestions; - // otherwise we might want to try to complete the "" option - if (results.size() > 0) { - candidates.addAll(results); - return 0; - } - } - - // Handle completing the option key they're presently typing - if (lastOptionKey != null && "".equals(lastOptionValue) - && !translated.endsWith("" + tokenizer.getLastValueDelimiter())) { - // Given we haven't got an option value of any form, we must - // still be typing an option key. - for (CliOption option : unspecified) { - for (String value : option.key()) { - if (value != null && value.regionMatches(true, 0, lastOptionKey, 0, lastOptionKey.length())) { - String completionValue = translated.substring(0, - (translated.length() - lastOptionKey.length())) - + value + " "; - results.add(new Completion(completionValue)); - } - } - } - candidates.addAll(results); - return 0; - } - - // To be here, we are NOT typing an option key (or we might be, and there are no further option keys left) - if (lastOptionKey != null && !"".equals(lastOptionKey)) { - // Lookup the relevant CliOption that applies to this lastOptionKey - // We do this via the parameter type - Class[] parameterTypes = methodTarget.getMethod().getParameterTypes(); - for (int i = 0; i < parameterTypes.length; i++) { - CliOption option = cliOptions.get(i); - Class parameterType = parameterTypes[i]; - - for (String key : option.key()) { - if (key.equals(lastOptionKey)) { - List allValues = new ArrayList(); - // We'll append the closing delimiter to proposals - String suffix = "" + tokenizer.getLastValueDelimiter(); - if (!suffix.endsWith(" ")) { - suffix += " "; - } - // Let's use a Converter if one is available - for (Converter candidate : converters) { - String optionContext = successiveInvocationContext + " " + option.optionContext(); - if (candidate.supports(parameterType, optionContext)) { - // Found a usable converter - try { - boolean allComplete = candidate.getAllPossibleValues(allValues, parameterType, - lastOptionValue, optionContext, methodTarget); - if (!allComplete) { - suffix = ""; - } - } // Make sure completer thrown exceptions don't crash the whole process - catch (Exception e) { - LOGGER.warning(e.getMessage()); - } - break; - } - } - - if (allValues.isEmpty()) { - // Doesn't appear to be a custom Converter, so let's go and provide defaults - // for simple types - completeForSimpleTypes(parameterType, allValues); - } - - // Only include in the candidates those results which are compatible with the present buffer - for (Completion currentValue : allValues) { - // Only add the result **if** what they've typed is compatible *AND* they haven't - // already typed it in full - String proposal = currentValue.getValue(); - if (proposal.toLowerCase().startsWith(lastOptionValue.toLowerCase()) - && lastOptionValue.length() < proposal.length() - && (!tokenizer.lastValueIsComplete())) { - results.add(new Completion(tokenizer.escape(proposal) + suffix, currentValue - .getFormattedValue(), currentValue.getHeading(), currentValue.getOrder())); - } - } - - // ROO-389: give inline options given there's multiple choices available and we want to help - // the user - displayHelp(lastOptionKey, option); - - if (results.size() == 1) { - String suggestion = results.iterator().next().getValue().trim(); - if (suggestion.equals(tokenizer.escape(lastOptionValue))) { - // They have pressed TAB in the default value, and the default value has already - // been provided as an explicit option - return -1; - } - } - - if (results.size() > 0) { - candidates.addAll(results); - return methodTarget.getKey().length() + " ".length() - + tokenizer.getLastValueStartOffset(); - } - return 0; - } - } - } - } - - return -1; - } - } - - /** - * Track the number of times completion has been requested for the same buffer, resetting everytime the buffer - * changes. - * @return the portion of "option context" that indicates the number of invocation - */ - private String trackSuccessiveCompletionRequests(String translated) { - if (translated.equals(previousCompletionBuffer)) { - successiveCompletionRequests++; - } - else { - previousCompletionBuffer = translated; - successiveCompletionRequests = 1; - } - return Converter.TAB_COMPLETION_COUNT_PREFIX + successiveCompletionRequests; - } - - private void displayHelp(String lastOptionKey, CliOption option) { - StringBuilder help = new StringBuilder(); - help.append(OsUtils.LINE_SEPARATOR); - help.append(option.mandatory() ? "required --" : "optional --"); - if ("".equals(option.help())) { - help.append(lastOptionKey).append(": ").append("No help available"); - } - else { - help.append(lastOptionKey).append(": ").append(option.help()); - } - if (option.specifiedDefaultValue().equals(option.unspecifiedDefaultValue())) { - if (option.specifiedDefaultValue().equals("__NULL__")) { - help.append("; no default value"); - } - else { - help.append("; default: '").append(option.specifiedDefaultValue()).append("'"); - } - } - else { - if (!"".equals(option.specifiedDefaultValue()) && !"__NULL__".equals(option.specifiedDefaultValue())) { - help.append("; default if option present: '").append(option.specifiedDefaultValue()).append("'"); - } - if (!"".equals(option.unspecifiedDefaultValue()) && !"__NULL__".equals(option.unspecifiedDefaultValue())) { - help.append("; default if option not present: '").append(option.unspecifiedDefaultValue()).append("'"); - } - } - LOGGER.info(help.toString()); - } - - private void completeForSimpleTypes(Class parameterType, List allValues) { - // Provide some simple options for common types - if (Boolean.class.isAssignableFrom(parameterType) || Boolean.TYPE.isAssignableFrom(parameterType)) { - allValues.add(new Completion("true")); - allValues.add(new Completion("false")); - } - - if (Number.class.isAssignableFrom(parameterType)) { - allValues.add(new Completion("0")); - allValues.add(new Completion("1")); - allValues.add(new Completion("2")); - allValues.add(new Completion("3")); - allValues.add(new Completion("4")); - allValues.add(new Completion("5")); - allValues.add(new Completion("6")); - allValues.add(new Completion("7")); - allValues.add(new Completion("8")); - allValues.add(new Completion("9")); - } - } - - /** - * populate completion for mandatory options - * @param translated user's input - * @param unspecified unspecified options - * @param value the option key - * @param results completion list - */ - private void handleMandatoryCompletion(String translated, List unspecified, String value, - SortedSet results) { - StringBuilder strBuilder = new StringBuilder(translated); - if (!translated.endsWith(" ")) { - strBuilder.append(" "); - } - // Plan change for SHL-20. But usability is bad. - /* - * List> mandatoryOptions = getMandatoryOptions(unspecified); for (List option : - * mandatoryOptions) { strBuilder.append("--"); strBuilder.append(option.get(0)); strBuilder.append(" "); } - */ - strBuilder.append("--"); - strBuilder.append(value); - strBuilder.append(" "); - results.add(new Completion(strBuilder.toString())); - } - - public void obtainHelp( - @CliOption(key = {"", "command"}, optionContext = "availableCommands", help = "Command name to provide help for") - String buffer) { - synchronized (mutex) { - if (buffer == null) { - buffer = ""; - } - - StringBuilder sb = new StringBuilder(); - - // Figure out if there's a single command we can offer help for - Collection matchingTargets = locateTargets(buffer, false, false); - for (MethodTarget candidate : matchingTargets) { - if (buffer.equals(candidate.getKey())) { - matchingTargets = Collections.singleton(candidate); - break; - } - } - if (matchingTargets.size() == 1) { - // Single command help - MethodTarget methodTarget = matchingTargets.iterator().next(); - - // Argument conversion time - Annotation[][] parameterAnnotations = methodTarget.getMethod().getParameterAnnotations(); - if (parameterAnnotations.length > 0) { - // Offer specified help - CliCommand cmd = methodTarget.getMethod().getAnnotation(CliCommand.class); - Assert.notNull(cmd, "CliCommand not found"); - - for (String value : cmd.value()) { - sb.append("Keyword: ").append(value).append(OsUtils.LINE_SEPARATOR); - } - - sb.append("Description: ").append(cmd.help()).append(OsUtils.LINE_SEPARATOR); - - for (Annotation[] annotations : parameterAnnotations) { - CliOption cliOption = null; - for (Annotation a : annotations) { - if (a instanceof CliOption) { - cliOption = (CliOption) a; - - for (String key : cliOption.key()) { - if ("".equals(key)) { - key = "** default **"; - } - sb.append(" Keyword: ").append(key).append(OsUtils.LINE_SEPARATOR); - } - - sb.append(" Help: ").append(cliOption.help()) - .append(OsUtils.LINE_SEPARATOR); - sb.append(" Mandatory: ").append(cliOption.mandatory()) - .append(OsUtils.LINE_SEPARATOR); - sb.append(" Default if specified: '").append(cliOption.specifiedDefaultValue()) - .append("'").append(OsUtils.LINE_SEPARATOR); - sb.append(" Default if unspecified: '").append(cliOption.unspecifiedDefaultValue()) - .append("'").append(OsUtils.LINE_SEPARATOR); - sb.append(OsUtils.LINE_SEPARATOR); - } - - } - Assert.notNull(cliOption, "CliOption not found for parameter '" + Arrays.toString(annotations) - + "'"); - } - } - // Only a single argument, so default to the normal help operation - } - - SortedSet result = new TreeSet(COMPARATOR); - for (MethodTarget mt : matchingTargets) { - CliCommand cmd = mt.getMethod().getAnnotation(CliCommand.class); - if (cmd != null) { - for (String value : cmd.value()) { - if ("".equals(cmd.help())) { - result.add("* " + value); - } - else { - result.add("* " + value + " - " + cmd.help()); - } - } - } - } - - for (String s : result) { - sb.append(s).append(OsUtils.LINE_SEPARATOR); - } - - LOGGER.info(sb.toString()); - } - } - - public Set getEveryCommand() { - synchronized (mutex) { - SortedSet result = new TreeSet(COMPARATOR); - for (Object o : commands) { - Method[] methods = o.getClass().getMethods(); - for (Method m : methods) { - CliCommand cmd = m.getAnnotation(CliCommand.class); - if (cmd != null) { - result.addAll(Arrays.asList(cmd.value())); - } - } - } - return result; - } - } - - public final void add(final CommandMarker command) { - synchronized (mutex) { - commands.add(command); - for (final Method method : ReflectionUtils.getAllDeclaredMethods(command.getClass())) { - CliAvailabilityIndicator availability = method.getAnnotation(CliAvailabilityIndicator.class); - if (availability != null) { - Assert.isTrue( - method.getParameterTypes().length == 0, - "CliAvailabilityIndicator is only legal for 0 parameter methods (" - + method.toGenericString() + ")"); - Assert.isTrue( - method.getReturnType().equals(Boolean.TYPE), - "CliAvailabilityIndicator is only legal for primitive boolean return types (" - + method.toGenericString() + ")"); - for (String cmd : availability.value()) { - Assert.isTrue(!availabilityIndicators.containsKey(cmd), - "Cannot specify an availability indicator for '" + cmd + "' more than once"); - ReflectionUtils.makeAccessible(method); - availabilityIndicators.put(cmd, new MethodTarget(method, command)); - } - } - } - } - } - - public final Set getCommandMarkers() { - synchronized (mutex) { - return Collections.unmodifiableSet(commands); - } - } - - public final void remove(final CommandMarker command) { - synchronized (mutex) { - commands.remove(command); - for (Method m : command.getClass().getMethods()) { - CliAvailabilityIndicator availability = m.getAnnotation(CliAvailabilityIndicator.class); - if (availability != null) { - for (String cmd : availability.value()) { - availabilityIndicators.remove(cmd); - } - } - } - } - } - - public final void add(final Converter converter) { - synchronized (mutex) { - converters.add(converter); - } - } - - public final void remove(final Converter converter) { - synchronized (mutex) { - converters.remove(converter); - } - } - - public final Set> getConverters() { - synchronized (mutex) { - return Collections.unmodifiableSet(converters); - } - } -} diff --git a/src/main/java/org/springframework/shell/core/Tokenizer.java b/src/main/java/org/springframework/shell/core/Tokenizer.java deleted file mode 100644 index d815ea35..00000000 --- a/src/main/java/org/springframework/shell/core/Tokenizer.java +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright 2013 the original author or authors. - * - * 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.springframework.shell.core; - -import java.util.LinkedHashMap; -import java.util.Map; - -import org.springframework.util.Assert; - -/** - * Converts a particular buffer into a tokenized structure. - * - *

- * Properly treats double quotes (") as option delimiters. - * - *

- * Expects option names to be preceded by a double dash. We call this an "option marker". - * - *

- * Treats spaces as the default option tokenizer. - * - *

- * Any token without an option marker is considered the default. The default is returned in the Map as an element with - * an empty string key (""). There can only be a single default. - * - * @author Eric Bottard - * @since 1.1 - */ -public class Tokenizer { - - private static final char ESCAPE_CHAR = '\\'; - - private final char[] buffer; - - private int pos = 0; - - private final Map result = new LinkedHashMap(); - - /** Useful when trying to do auto complete. */ - private boolean allowUnbalancedLastQuotedValue; - - /** - * Used to indicate that the last value was indeed half enclosed in quotes. Useful so that parser can re-add it. - */ - private boolean openingQuotesHaveNotBeenClosed; - - private char lastValueDelimiter; - - private int lastValueStartOffset = -1; - - public Tokenizer(String text) { - this(text, false); - } - - public Tokenizer(String text, boolean allowUnbalancedLastQuotedValue) { - this.buffer = text.toCharArray(); - this.allowUnbalancedLastQuotedValue = allowUnbalancedLastQuotedValue; - tokenize(); - } - - private void eatWhiteSpace() { - while (lookAhead(' ')) { - pos++; - } - } - - public void tokenize() { - while (pos < buffer.length) { - eatWhiteSpace(); - if (pos < buffer.length) { - eatKeyValuePair(); - } - } - } - - public Map getTokens() { - return result; - } - - /** - * Return true if the remaining buffer matches the given String (return false if there is not enough input). - */ - private boolean lookAhead(char... toMatch) { - for (int i = 0; i < toMatch.length; i++) { - if (pos + i >= buffer.length || buffer[pos + i] != toMatch[i]) { - return false; - } - } - return true; - - } - - /** - * Consume either {@code --key[=value]} or just {@code value}, eating extra spaces. - */ - private void eatKeyValuePair() { - if (lookAhead('-', '-')) { - pos += 2; - eatKeyEqualsValue(); - } - else { - int offsetInCaseOfFailure = pos; - String value = eatValue(true); - store("", value, offsetInCaseOfFailure); - } - - } - - /** - * Store a command key/value pair, reporting a failure if a mapping with the same key is already present. - * @param key the command key - * @param value the command value - * @param failureOffset the buffer offset at which the mapping we're trying to store was tokenized - */ - private void store(String key, String value, int failureOffset) { - String alreadyThere = result.put(key, value); - if (alreadyThere != null) { - if ("".equals(key)) { - String explanation = String.format( - "You cannot specify '%s' as another value for the default ('') option in a single command.%n" - + "You already provided '%s' earlier.%n" - + "Did you forget to add quotes around the value of another option?", value, - alreadyThere); - throw new TokenizingException(failureOffset, buffer, explanation); - } - else { - String explanation = String.format( - "You cannot specify '%s' as another value for the '--%s' option in a single command.%n" - + "You already provided '%s' earlier.", value, key, alreadyThere); - throw new TokenizingException(failureOffset, buffer, explanation); - } - } - } - - /** - * Eat a value that may be enclosed in some delimiters. - * @param emptyKey if true, we're currently reading the value for the empty key - */ - private String eatValue(boolean emptyKey) { - StringBuilder sb = new StringBuilder(); - char endDelimiter = ' '; - if (buffer[pos] == '"' || buffer[pos] == '\'') { - endDelimiter = buffer[pos]; - pos++; - } - // So that it can be retrieved later (if this is actually the last value) - lastValueDelimiter = endDelimiter; - lastValueStartOffset = pos; - while (pos < buffer.length && buffer[pos] != endDelimiter) { - if (buffer[pos] == ESCAPE_CHAR) { - sb.append(processCharacterEscapeCodes(endDelimiter)); - continue; - } - if (lookAhead(ESCAPE_CHAR, endDelimiter)) { - sb.append(endDelimiter); - pos += 2; - continue; - } - sb.append(buffer[pos]); - pos++; - } - // If we're grabbing the key-less value, allow additional chunks, as long as - // 1) we don't hit '--' - // 2) we were not using a quote delimited value - if (emptyKey && endDelimiter == ' ') { - while (!lookAhead('-', '-') && pos < buffer.length) { - sb.append(buffer[pos++]); - } - // Trim to the right - while (Character.isWhitespace(sb.charAt(sb.length() - 1))) { - sb.setLength(sb.length() - 1); - } - return sb.toString(); - } - - // When here, we either ran out of input, or encountered our delim, or both - // Fail, unless we allow an unfinished quoted string to be reported - if (endDelimiter != ' ' && // we're using quotes - pos == buffer.length && // we ran of input - (buffer[pos - 1] != endDelimiter || // quotes are not properly closed - sb.length() == 0)) { // BUT it's ok if consumed nothing (pos-1 is *opening* quote then) - if (allowUnbalancedLastQuotedValue) { - openingQuotesHaveNotBeenClosed = true; - return sb.toString(); - } - else { - throw new TokenizingException(pos, buffer, "Cannot have an unbalanced number of quotation marks"); - } - } - // Eat our delim - pos++; - return sb.toString(); - } - - /** - * When the escape character is encountered, consume and return the escaped sequence. Note that depending on which - * end delimiter is currently in use, not all combinations need to be escaped - * @param endDelimiter the current endDelimiter - */ - private char processCharacterEscapeCodes(char endDelimiter) { - pos++; - if (pos >= buffer.length) { - throw new TokenizingException(buffer.length, buffer, "Ran out of input in escape sequence"); - } - switch (buffer[pos]) { - case ESCAPE_CHAR: - pos++; // consume the second escape char - return ESCAPE_CHAR; - case 't': - pos++; - return '\t'; - case 'r': - pos++; - return '\r'; - case 'n': - pos++; - return '\n'; - case 'f': - pos++; - return '\f'; - case 'u': - if (pos + 5 > buffer.length) { - throw new TokenizingException(buffer.length, buffer, "Ran out of input in unicode escape sequence"); - } - String hex = new String(buffer, pos + 1, 4); - try { - char code = (char) Integer.parseInt(hex, 16); - pos += 5; - return code; - } - catch (NumberFormatException e) { - throw new TokenizingException(pos - 1, buffer, "Illegal unicode escape sequence: " + ESCAPE_CHAR + "u" - + hex); - } - - default: - if (buffer[pos] == endDelimiter) { - pos++; - return endDelimiter; - } - else { - // Not an actual escape. Do not increment pos, - // and return the \ we consumed at the very beginning - return ESCAPE_CHAR; - } - } - } - - /** - * Return the offset at which the last value seen started (NOT including any delimiter). - */ - public int getLastValueStartOffset() { - Assert.isTrue(lastValueStartOffset >= 0, "lastValueStartOffset has not been set yet"); - return lastValueStartOffset; - } - - /** - * Return the delimiter (space or quotes) that was (or is being) used for the last value. - */ - public char getLastValueDelimiter() { - Assert.isTrue(lastValueDelimiter != 0, "lastValueDelimiter has not been set yet"); - return lastValueDelimiter; - } - - /** - * Return whether the last value was meant to be enclosed in quotes, but the closing quote has not been typed yet. - */ - public boolean openingQuotesHaveNotBeenClosed() { - return openingQuotesHaveNotBeenClosed; - } - - /** - * Return true if we know for sure that the last value has been typed in full. - */ - public boolean lastValueIsComplete() { - // If using quotes as delim and they're not closed, we know for sure. - // Moreover if we're using space as the delimiter, we can't know. - return !openingQuotesHaveNotBeenClosed && lastValueDelimiter != ' '; - } - - /** - * Apply delimiter escaping to the given string, using the actual delimiter that was used for the last value. - */ - public String escape(String value) { - String result = value.replace("" + lastValueDelimiter, "" + ESCAPE_CHAR + lastValueDelimiter); - result = result.replace("\r", "\\r"); - result = result.replace("\n", "\\n"); - result = result.replace("\t", "\\t"); - result = result.replace("\f", "\\f"); - return result; - } - - /** - * Consume a full {@code --key value} pair *unless* - *

    - *
  • we're at the very end,
  • - *
  • or the next token starts with {@code --}
  • - *
- * in which case allow for just {@code --key}, using "" for the value. - */ - private void eatKeyEqualsValue() { - // We already consumed '--' - int offsetInCaseOfFailure = pos - 2; - String key = eatKey(); - eatWhiteSpace(); - String value; - // We're at the very end or it's a valueless option - // Make last* fields consistent - if (pos >= buffer.length || lookAhead('-', '-')) { - lastValueDelimiter = ' '; - lastValueStartOffset = pos; - value = ""; - } - else { - value = eatValue(false); - } - // Don't store the ""="" that would result from having a pending " --" at the end - if (key.equals("") && value.equals("")) { - return; - } - store(key, value, offsetInCaseOfFailure); - } - - private String eatKey() { - int start = pos; - while (pos < buffer.length && buffer[pos] != ' ') { - pos++; - } - return new String(buffer, start, pos - start); - } - - @Override - public String toString() { - StringBuilder result = new StringBuilder().append(buffer).append('\n'); - for (int i = 0; i < lastValueStartOffset; i++) { - result.append(' '); - } - result.append('^'); - return result.toString(); - } -} diff --git a/src/main/java/org/springframework/shell/core/TokenizingException.java b/src/main/java/org/springframework/shell/core/TokenizingException.java deleted file mode 100644 index 114dd1a9..00000000 --- a/src/main/java/org/springframework/shell/core/TokenizingException.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2014 the original author or authors. - * - * 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.springframework.shell.core; - -@SuppressWarnings("serial") -public class TokenizingException extends RuntimeException { - - private final int offendingOffset; - - private final char[] buffer; - - private final String reason; - - public TokenizingException(int offendingOffset, char[] buffer, String reason) { - super(); - this.offendingOffset = offendingOffset; - this.buffer = buffer; - this.reason = reason; - } - - public int getOffendingOffset() { - return offendingOffset; - } - - public String getBuffer() { - return new String(buffer); - } - - public String getReason() { - return reason; - } - -} diff --git a/src/main/java/org/springframework/shell/core/annotation/CliAvailabilityIndicator.java b/src/main/java/org/springframework/shell/core/annotation/CliAvailabilityIndicator.java deleted file mode 100644 index 6aebddf6..00000000 --- a/src/main/java/org/springframework/shell/core/annotation/CliAvailabilityIndicator.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * Annotates a method that can indicate whether a particular command is presently - * available or not. - * - *

- * This annotation must only be applied to a public no-argument method that returns primitive boolean. - * The method should be inexpensive to evaluate, as this method can be called very - * frequently. If expensive operations are necessary to compute command availability, - * it is suggested the method return a boolean field that is maintained using the observer - * pattern. - * - *

- * It is possible that a particular availability method might be able to represent the - * availability status of multiple commands. As such, an availability indicator annotation - * will indicate the commands that it applies to. If a specific command has multiple - * aliases (ie by using an array for {@link CliCommand#value()}), only one of the commands - * need to be specified in the {@link CliAvailabilityIndicator} annotation. - * - * @author Ben Alex - * @since 1.0 - */ -@Inherited -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface CliAvailabilityIndicator { - - /** - * @return the name of the command or commands that this availability indicator represents - */ - String[] value(); -} diff --git a/src/main/java/org/springframework/shell/core/annotation/CliCommand.java b/src/main/java/org/springframework/shell/core/annotation/CliCommand.java deleted file mode 100644 index f80aa564..00000000 --- a/src/main/java/org/springframework/shell/core/annotation/CliCommand.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * - * Annotates a method that provides a command to the shell. - * - * @author Ben Alex - * @since 1.0 - * - */ -@Inherited -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface CliCommand { - - /** - * @return one or more strings which must serve as the start of a particular command in order to match this method - * (these must be unique within the entire application; if not unique, behaviour is not specified) - */ - String[] value(); - - /** - * @return a help message for this command (the default is a blank String, which means there is no help) - */ - String help() default ""; -} diff --git a/src/main/java/org/springframework/shell/core/annotation/CliOption.java b/src/main/java/org/springframework/shell/core/annotation/CliOption.java deleted file mode 100644 index 480cb524..00000000 --- a/src/main/java/org/springframework/shell/core/annotation/CliOption.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.shell.core.Converter; - -/** - * Annotates the arguments of a command methods, allowing it to declare the argument value as mandatory or optional with a default value. - * - * @author Ben Alex - * @since 1.0 - * - */ -@Inherited -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.PARAMETER) -public @interface CliOption { - - /** - * @return if true, the user cannot specify this option and it is provided by the shell infrastructure - * (defaults to false) - */ - boolean systemProvided() default false; - - /** - * @return the name of the option, which must be unique within this {@link CliCommand} (an empty String may - * be given, which would denote this option is the default for the command) - */ - String[] key(); - - /** - * @return true if this option must be specified one way or the other by the user (defaults to false) - */ - boolean mandatory() default false; - - /** - * @return the default value to use if this option is unspecified by the user (defaults to __NULL__, which causes null to - * be presented to any non-primitive parameter) - */ - String unspecifiedDefaultValue() default "__NULL__"; - - /** - * @return the default value to use if this option is included by the user, but they didn't specify an - * actual value (most commonly used for flags; defaults to __NULL__, which causes null to - * be presented to any non-primitive parameter) - */ - String specifiedDefaultValue() default "__NULL__"; - - /** - * Returns a string providing context-specific information (e.g. a comma-delimited - * set of keywords) to the {@link Converter} that handles the annotated parameter's type. - *

- * For example, if a method parameter "thing" of type "Thing" is annotated as - * follows: - *

@CliOption(..., optionContext = "foo,bar", ...) Thing thing
- * ... then the {@link Converter} that converts the text entered by the user - * into an instance of Thing will be passed "foo,bar" as the value of the - * optionContext parameter in its public methods. This allows - * the behaviour of that Converter to be individually customised for each - * {@link CliOption} of each {@link CliCommand}. - * - * @return a non-null string (can be empty) - */ - String optionContext() default ""; - - /** - * @return a help message for this option (the default is a blank String, which means there is no help) - */ - String help() default ""; -} diff --git a/src/main/java/org/springframework/shell/event/AbstractShellStatusPublisher.java b/src/main/java/org/springframework/shell/event/AbstractShellStatusPublisher.java deleted file mode 100644 index 9773949f..00000000 --- a/src/main/java/org/springframework/shell/event/AbstractShellStatusPublisher.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.event; - -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; - -import org.springframework.shell.event.ShellStatus.Status; -import org.springframework.util.Assert; - -/** - * Provides a convenience superclass for those shells wishing to publish status messages. - * - * @author Ben Alex - * @since 1.0 - */ -public abstract class AbstractShellStatusPublisher implements ShellStatusProvider { - - // Fields - protected Set shellStatusListeners = new CopyOnWriteArraySet(); - protected ShellStatus shellStatus = new ShellStatus(Status.STARTING); - - public final void addShellStatusListener(final ShellStatusListener shellStatusListener) { - Assert.notNull(shellStatusListener, "Status listener required"); - synchronized (shellStatus) { - shellStatusListeners.add(shellStatusListener); - } - } - - public final void removeShellStatusListener(final ShellStatusListener shellStatusListener) { - Assert.notNull(shellStatusListener, "Status listener required"); - synchronized (shellStatus) { - shellStatusListeners.remove(shellStatusListener); - } - } - - public final ShellStatus getShellStatus() { - synchronized (shellStatus) { - return shellStatus; - } - } - - protected void setShellStatus(final Status shellStatus) { - setShellStatus(shellStatus, null, null); - } - - protected void setShellStatus(final Status shellStatus, final String msg, final ParseResult parseResult) { - Assert.notNull(shellStatus, "Shell status required"); - - synchronized (this.shellStatus) { - ShellStatus st; - if (msg == null || msg.length() == 0) { - st = new ShellStatus(shellStatus); - } else { - st = new ShellStatus(shellStatus, msg, parseResult); - } - - if (this.shellStatus.equals(st)) { - return; - } - - for (ShellStatusListener listener : shellStatusListeners) { - listener.onShellStatusChange(this.shellStatus, st); - } - this.shellStatus = st; - } - } -} diff --git a/src/main/java/org/springframework/shell/event/ParseResult.java b/src/main/java/org/springframework/shell/event/ParseResult.java deleted file mode 100644 index bb186e4f..00000000 --- a/src/main/java/org/springframework/shell/event/ParseResult.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.event; - -import java.lang.reflect.Method; -import java.util.Arrays; - -import org.springframework.core.style.ToStringCreator; -import org.springframework.shell.core.Converter; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Immutable representation of the outcome of parsing a given shell line. - * - *

- * Note that contained objects (the instance and the arguments) may be mutable, as the shell infrastructure - * has no way of restricting which methods can be the target of CLI commands and nor the arguments - * they will accept via the {@link Converter} infrastructure. - * - * @author Ben Alex - * @since 1.0 - */ -public class ParseResult { - - // Fields - private final Method method; - private final Object instance; - private final Object[] arguments; // May be null if no arguments needed - - public ParseResult(final Method method, final Object instance, final Object[] arguments) { - Assert.notNull(method, "Method required"); - Assert.notNull(instance, "Instance required"); - int length = arguments == null ? 0 : arguments.length; - Assert.isTrue(method.getParameterTypes().length == length, "Required " + method.getParameterTypes().length + " arguments, but received " + length); - this.method = method; - this.instance = instance; - this.arguments = arguments; - } - - public Method getMethod() { - return method; - } - - public Object getInstance() { - return instance; - } - - public Object[] getArguments() { - return arguments; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode(arguments); - result = prime * result + ((instance == null) ? 0 : instance.hashCode()); - result = prime * result + ((method == null) ? 0 : method.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ParseResult other = (ParseResult) obj; - if (!Arrays.equals(arguments, other.arguments)) - return false; - if (instance == null) { - if (other.instance != null) - return false; - } else if (!instance.equals(other.instance)) - return false; - if (method == null) { - if (other.method != null) - return false; - } else if (!method.equals(other.method)) - return false; - return true; - } - - @Override - public String toString() { - ToStringCreator tsc = new ToStringCreator(this); - tsc.append("method", method); - tsc.append("instance", instance); - tsc.append("arguments", StringUtils.arrayToCommaDelimitedString(arguments)); - return tsc.toString(); - } -} diff --git a/src/main/java/org/springframework/shell/event/ShellStatus.java b/src/main/java/org/springframework/shell/event/ShellStatus.java deleted file mode 100644 index 857e58fa..00000000 --- a/src/main/java/org/springframework/shell/event/ShellStatus.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.event; - - -/** - * Represents the different states that a shell can legally be in. - * - *

- * There is no "shut down" state because the shell would have been terminated by - * that stage and potentially garbage collected. There is no guarantee that a - * shell implementation will necessarily publish every state. - * - * @author Ben Alex - * @author Stefan Schmidt - * @since 1.0 - */ -public class ShellStatus { - - // Fields - private final Status status; - private String message = ""; - private ParseResult parseResult; - - public enum Status { - STARTING, - STARTED, - USER_INPUT, - PARSING, - EXECUTING, - EXECUTION_RESULT_PROCESSING, - EXECUTION_SUCCESS, - EXECUTION_FAILED, - SHUTTING_DOWN - } - - ShellStatus(final Status status) { - this.status = status; - } - - ShellStatus(final Status status, final String msg, final ParseResult parseResult) { - this.status = status; - this.message = msg; - this.parseResult = parseResult; - } - - public String getMessage() { - return message; - } - - public Status getStatus() { - return status; - } - - public final ParseResult getParseResult() { - return parseResult; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((message == null) ? 0 : message.hashCode()); - result = prime * result - + ((parseResult == null) ? 0 : parseResult.hashCode()); - result = prime * result + ((status == null) ? 0 : status.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ShellStatus other = (ShellStatus) obj; - if (message == null) { - if (other.message != null) - return false; - } else if (!message.equals(other.message)) - return false; - if (parseResult == null) { - if (other.parseResult != null) - return false; - } else if (!parseResult.equals(other.parseResult)) - return false; - if (status == null) { - if (other.status != null) - return false; - } else if (!status.equals(other.status)) - return false; - return true; - } -} diff --git a/src/main/java/org/springframework/shell/event/ShellStatusListener.java b/src/main/java/org/springframework/shell/event/ShellStatusListener.java deleted file mode 100644 index 4aaaf97c..00000000 --- a/src/main/java/org/springframework/shell/event/ShellStatusListener.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.event; - -/** - * Implemented by classes that wish to be notified of shell status changes. - * - * @author Ben Alex - * @since 1.0 - */ -public interface ShellStatusListener { - - /** - * Invoked by the shell to report a new status. - * - * @param oldStatus the old status - * @param newStatus the new status - */ - void onShellStatusChange(ShellStatus oldStatus, ShellStatus newStatus); -} diff --git a/src/main/java/org/springframework/shell/event/ShellStatusProvider.java b/src/main/java/org/springframework/shell/event/ShellStatusProvider.java deleted file mode 100644 index b3e70310..00000000 --- a/src/main/java/org/springframework/shell/event/ShellStatusProvider.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.event; - -/** - * Implemented by shells that support the publication of shell status changes. - * - *

- * Implementations are not required to provide any guarantees with respect to the order - * in which notifications are delivered to listeners. - * - *

- * Implementations must permit modification of the listener list, even while delivering - * event notifications to listeners. However, listeners do not receive any guarantee that - * their addition or removal from the listener list will be effective or not for any event - * notification that is currently proceeding. - * - *

- * Implementations must ensure that status notifications are only delivered when an actual - * change has taken place. - * - * @author Ben Alex - * @since 1.0 - */ -public interface ShellStatusProvider { - - /** - * Registers a new status listener. - * - * @param shellStatusListener to register (cannot be null) - */ - void addShellStatusListener(ShellStatusListener shellStatusListener); - - /** - * Removes an existing status listener. - * - *

- * If the presented status listener is not found, the method returns without exception. - * - * @param shellStatusListener to remove (cannot be null) - */ - void removeShellStatusListener(ShellStatusListener shellStatusListener); - - /** - * Returns the current shell status. - * - * @return the current status (never null) - */ - ShellStatus getShellStatus(); -} diff --git a/src/main/java/org/springframework/shell/plugin/BannerProvider.java b/src/main/java/org/springframework/shell/plugin/BannerProvider.java deleted file mode 100644 index 16f1150c..00000000 --- a/src/main/java/org/springframework/shell/plugin/BannerProvider.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.plugin; - - - -/** - * Banner provider. Plugins should implement this interface to replace the version banner. - * Use the @Order annotation to specify the priority of the banner to be display, higher - * values can be interpreted as lower priority - * - * @author Jarred Li - * @since 1.0 - * - */ -public interface BannerProvider extends NamedProvider { - - /** - * Returns the banner. - * - * @return - */ - String getBanner(); - - /** - * Returns the associated version. - * - * @return - */ - String getVersion(); - - /** - * Returns the welcome message. - * - * @return - */ - String getWelcomeMessage(); - -} diff --git a/src/main/java/org/springframework/shell/plugin/HistoryFileNameProvider.java b/src/main/java/org/springframework/shell/plugin/HistoryFileNameProvider.java deleted file mode 100644 index f26b41ca..00000000 --- a/src/main/java/org/springframework/shell/plugin/HistoryFileNameProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.plugin; - - -/** - * History file name provider. - * Plugin should implement this interface to customize history file. - * getOrder indicate the priority, higher values can be interpreted as lower priority - * - * @author Jarred Li - * @since 1.0 - * - */ -public interface HistoryFileNameProvider extends NamedProvider { - - /** - * get history file name - * - * @return history file name - */ - String getHistoryFileName(); - -} diff --git a/src/main/java/org/springframework/shell/plugin/NamedProvider.java b/src/main/java/org/springframework/shell/plugin/NamedProvider.java deleted file mode 100644 index 490f372b..00000000 --- a/src/main/java/org/springframework/shell/plugin/NamedProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.plugin; - -/** - * Returns the name of the provider. Providers customize features of the shell such as the banner and command line prompt. - * - * - * @author Jarred Li - * @author Mark Pollack - * @see BannerProvider - * @see PromptProvider - * @see HistoryFileNameProvider - */ -public interface NamedProvider { - - /** - * Return the name of the provider. - */ - String getProviderName(); -} diff --git a/src/main/java/org/springframework/shell/plugin/PluginUtils.java b/src/main/java/org/springframework/shell/plugin/PluginUtils.java deleted file mode 100644 index c1dbe4e7..00000000 --- a/src/main/java/org/springframework/shell/plugin/PluginUtils.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.plugin; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.context.ApplicationContext; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; - -/** - * Utilities dealing with shell plugins. - * - * @author Erwin Vervaet - */ -public final class PluginUtils { - - private PluginUtils() { - } - - /** - * Returns the highest priority {@link PluginProvider} of specified type defined in - * given application context. - * - * @since 1.0.1 - */ - public static T getHighestPriorityProvider(ApplicationContext applicationContext, Class t) { - Map providers = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, t); - List sortedProviders = new ArrayList(providers.values()); - Collections.sort(sortedProviders, new AnnotationAwareOrderComparator()); - T highestPriorityProvider = sortedProviders.get(0); - return highestPriorityProvider; - } -} diff --git a/src/main/java/org/springframework/shell/plugin/PromptProvider.java b/src/main/java/org/springframework/shell/plugin/PromptProvider.java deleted file mode 100644 index 70721e5c..00000000 --- a/src/main/java/org/springframework/shell/plugin/PromptProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.plugin; - - -/** - * Shell prompt provider. - * Plugins should implement this interface to customize prompt. - * getOrder indicate the priority, higher values can be interpreted as lower priority - * - * @author Jarred Li - * - */ -public interface PromptProvider extends NamedProvider { - - /** - * Returns the prompt text. - * - * @return prompt - */ - String getPrompt(); -} diff --git a/src/main/java/org/springframework/shell/plugin/support/DefaultBannerProvider.java b/src/main/java/org/springframework/shell/plugin/support/DefaultBannerProvider.java deleted file mode 100644 index 1904a6e4..00000000 --- a/src/main/java/org/springframework/shell/plugin/support/DefaultBannerProvider.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.plugin.support; - -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.shell.plugin.BannerProvider; -import org.springframework.shell.support.util.FileUtils; -import org.springframework.shell.support.util.OsUtils; -import org.springframework.shell.support.util.VersionUtils; -import org.springframework.stereotype.Component; - -/** - * Default Banner provider. - * - * @author Jarred Li - * @author Costin Leau - */ -@Component -@Order(Ordered.LOWEST_PRECEDENCE) -public class DefaultBannerProvider implements BannerProvider { - - public String getBanner() { - StringBuilder sb = new StringBuilder(); - sb.append(FileUtils.readBanner(DefaultBannerProvider.class, "banner.txt")); - sb.append(getVersion()).append(OsUtils.LINE_SEPARATOR); - sb.append(OsUtils.LINE_SEPARATOR); - - return sb.toString(); - } - - - public String getVersion() { - return VersionUtils.versionInfo(); - } - - public String getWelcomeMessage() { - return "Welcome to " + getProviderName() + "."; - } - - public String getProviderName() { - return "Spring Shell"; - } -} diff --git a/src/main/java/org/springframework/shell/plugin/support/DefaultHistoryFileNameProvider.java b/src/main/java/org/springframework/shell/plugin/support/DefaultHistoryFileNameProvider.java deleted file mode 100644 index 3518cba1..00000000 --- a/src/main/java/org/springframework/shell/plugin/support/DefaultHistoryFileNameProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.plugin.support; - -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.shell.plugin.HistoryFileNameProvider; -import org.springframework.stereotype.Component; - -/** - * Default history file provider. Default file is {@link org.springframework.shell.Constant.HISTORY_FILE_NAME} - * - * @author Jarred Li - * - */ -@Component -@Order(Ordered.LOWEST_PRECEDENCE) -public class DefaultHistoryFileNameProvider implements HistoryFileNameProvider { - - public String getHistoryFileName() { - return "spring-shell.log"; - } - - public String getProviderName() { - return "default history provider"; - } -} diff --git a/src/main/java/org/springframework/shell/plugin/support/DefaultPromptProvider.java b/src/main/java/org/springframework/shell/plugin/support/DefaultPromptProvider.java deleted file mode 100644 index 26451239..00000000 --- a/src/main/java/org/springframework/shell/plugin/support/DefaultPromptProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.plugin.support; - -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.shell.plugin.PromptProvider; -import org.springframework.stereotype.Component; - -/** - * Default prompt provider. The prompt text is {@link org.springframework.shell.Constant.COMMAND_LINE_PROMPT} - * - * @author Jarred Li - * - */ -@Component -@Order(Ordered.LOWEST_PRECEDENCE) -public class DefaultPromptProvider implements PromptProvider { - - public String getPrompt() { - return "spring-shell>"; - } - - public String getProviderName() { - return "default prompt provider"; - } -} diff --git a/src/main/java/org/springframework/shell/support/logging/DeferredLogHandler.java b/src/main/java/org/springframework/shell/support/logging/DeferredLogHandler.java deleted file mode 100644 index c77a120c..00000000 --- a/src/main/java/org/springframework/shell/support/logging/DeferredLogHandler.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.logging; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogRecord; - -import org.springframework.util.Assert; - -/** - * Defers the publication of JDK {@link LogRecord} instances until a target {@link Handler} is registered. - * - *

- * This class is useful if a target {@link Handler} cannot be instantiated before {@link LogRecord} instances are being - * published. This may be the case if the target {@link Handler} requires the establishment of complex publication - * infrastructure such as a GUI, message queue, IoC container and the establishment of that infrastructure may produce - * log messages that should ultimately be delivered to the target {@link Handler}. - * - *

- * In recognition that sometimes the target {@link Handler} may never be registered (perhaps due to failures configuring - * its supporting infrastructure), this class supports a fallback mode. When in fallback mode, a fallback {@link Handler} - * will receive all previous and future {@link LogRecord} instances. Fallback mode is automatically triggered if a - * {@link LogRecord} is published at the fallback {@link Level}. Fallback mode is also triggered if the {@link #flush()} - * or {@link #close()} method is involved and the target {@link Handler} has never been registered. - * - * @author Ben Alex - * @since 1.0 - */ -public class DeferredLogHandler extends Handler { - - // Fields - private final List logRecords = Collections.synchronizedList(new ArrayList()); - private final Handler fallbackHandler; - private final Level fallbackPushLevel; - private boolean fallbackMode = false; - private Handler targetHandler; - - /** - * Creates an instance that will publish all recorded {@link LogRecord} instances to the specified fallback - * {@link Handler} if an event of the specified {@link Level} is received. - * - * @param fallbackHandler to publish events to (mandatory) - * @param fallbackPushLevel the level which will trigger an event publication (mandatory) - */ - public DeferredLogHandler(final Handler fallbackHandler, final Level fallbackPushLevel) { - Assert.notNull(fallbackHandler, "Fallback handler required"); - Assert.notNull(fallbackPushLevel, "Fallback push level required"); - this.fallbackHandler = fallbackHandler; - this.fallbackPushLevel = fallbackPushLevel; - } - - @Override - public void close() throws SecurityException { - if (targetHandler == null) { - fallbackMode = true; - } - if (fallbackMode) { - publishLogRecordsTo(fallbackHandler); - fallbackHandler.close(); - return; - } - targetHandler.close(); - } - - @Override - public void flush() { - if (targetHandler == null) { - fallbackMode = true; - } - if (fallbackMode) { - publishLogRecordsTo(fallbackHandler); - fallbackHandler.flush(); - return; - } - targetHandler.flush(); - } - - /** - * Stores the log record internally. - */ - @Override - public void publish(final LogRecord record) { - if (!isLoggable(record)) { - return; - } - if (fallbackMode) { - fallbackHandler.publish(record); - return; - } - if (targetHandler != null) { - targetHandler.publish(record); - return; - } - synchronized (logRecords) { - logRecords.add(record); - } - if (!fallbackMode && record.getLevel().intValue() >= fallbackPushLevel.intValue()) { - fallbackMode = true; - publishLogRecordsTo(fallbackHandler); - } - } - - /** - * @return the target {@link Handler}, or null if there is no target {@link Handler} defined so far - */ - public Handler getTargetHandler() { - return targetHandler; - } - - public void setTargetHandler(final Handler targetHandler) { - Assert.notNull(targetHandler, "Must specify a target handler"); - this.targetHandler = targetHandler; - if (!fallbackMode) { - publishLogRecordsTo(this.targetHandler); - } - } - - private void publishLogRecordsTo(final Handler destination) { - synchronized (logRecords) { - for (LogRecord record : logRecords) { - destination.publish(record); - } - logRecords.clear(); - } - } -} diff --git a/src/main/java/org/springframework/shell/support/logging/HandlerUtils.java b/src/main/java/org/springframework/shell/support/logging/HandlerUtils.java deleted file mode 100644 index 103f9a9c..00000000 --- a/src/main/java/org/springframework/shell/support/logging/HandlerUtils.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.logging; - -import java.util.ArrayList; -import java.util.List; -import java.util.logging.ConsoleHandler; -import java.util.logging.Formatter; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; - -import org.springframework.shell.support.util.OsUtils; -import org.springframework.util.Assert; - -/** - * Utility methods for dealing with {@link Handler} objects. - * - * @author Ben Alex - * @since 1.0 - * - */ -public abstract class HandlerUtils { - - /** - * Obtains a {@link Logger} that guarantees to set the {@link Level} - * to {@link Level#FINE} if it is part of org.springframework.roo. - * Unfortunately this is needed due to a regression in JDK 1.6.0_18 - * as per issue ROO-539. - * - * @param clazz to retrieve the logger for (required) - * @return the logger, which will at least of {@link Level#FINE} if no level was specified - */ - public static Logger getLogger(final Class clazz) { - Assert.notNull(clazz, "Class required"); - String name = clazz.getName(); - Logger logger = Logger.getLogger(name); - if (logger.getLevel() == null && name.startsWith("org.springframework.shell")) { - logger.setLevel(Level.FINE); - } - return logger; - } - - /** - * Replaces each {@link Handler} defined against the presented {@link Logger} with {@link DeferredLogHandler}. - * - *

- * This is useful for ensuring any {@link Handler} defaults defined by the user are preserved and treated as the - * {@link DeferredLogHandler} "fallback" {@link Handler} if the indicated severity {@link Level} is encountered. - * - *

- * This method will create a {@link ConsoleHandler} if the presented {@link Logger} has no current {@link Handler}. - * - * @param logger to introspect and replace the {@link Handler}s for (required) - * @param fallbackSeverity to trigger fallback mode (required) - * @return the number of {@link DeferredLogHandler}s now registered against the {@link Logger} (guaranteed to be 1 or above) - */ - public static int wrapWithDeferredLogHandler(final Logger logger, final Level fallbackSeverity) { - Assert.notNull(logger, "Logger is required"); - Assert.notNull(fallbackSeverity, "Fallback severity is required"); - - List newHandlers = new ArrayList(); - - // Create DeferredLogHandlers for each Handler in presented Logger - Handler[] handlers = logger.getHandlers(); - if (handlers != null && handlers.length > 0) { - for (Handler h : handlers) { - logger.removeHandler(h); - newHandlers.add(new DeferredLogHandler(h, fallbackSeverity)); - } - } - - // Create a default DeferredLogHandler if no Handler was defined in the presented Logger - if (newHandlers.isEmpty()) { - ConsoleHandler consoleHandler = new ConsoleHandler(); - consoleHandler.setFormatter(new Formatter() { - @Override - public String format(final LogRecord record) { - return record.getMessage() + OsUtils.LINE_SEPARATOR; - } - }); - newHandlers.add(new DeferredLogHandler(consoleHandler, fallbackSeverity)); - } - - // Add the new DeferredLogHandlers to the presented Logger - for (DeferredLogHandler h : newHandlers) { - logger.addHandler(h); - } - - return newHandlers.size(); - } - - /** - * Registers the presented target {@link Handler} against any {@link DeferredLogHandler} encountered in the presented - * {@link Logger}. - * - *

- * Generally this method is used on {@link Logger} instances that have previously been presented to the - * {@link #wrapWithDeferredLogHandler(Logger, Level)} method. - * - *

- * The method will return a count of how many {@link DeferredLogHandler} instances it detected. Note that no - * attempt is made to distinguish between instances already possessing the intended target {@link Handler} - * or those already possessing any target {@link Handler} at all. This method always overwrites the target - * {@link Handler} and the returned count represents how many overwrites took place. - * - * @param logger to introspect for {@link DeferredLogHandler} instances (required) - * @param target to set as the target {@link Handler} - * @return number of {@link DeferredLogHandler} instances detected and updated (may be 0 if none found) - */ - public static int registerTargetHandler(final Logger logger, final Handler target) { - Assert.notNull(logger, "Logger is required"); - Assert.notNull(target, "Target handler is required"); - - int replaced = 0; - Handler[] handlers = logger.getHandlers(); - if (handlers != null && handlers.length > 0) { - for (Handler h : handlers) { - if (h instanceof DeferredLogHandler) { - replaced++; - DeferredLogHandler defLogger = (DeferredLogHandler) h; - defLogger.setTargetHandler(target); - } - } - } - - return replaced; - } - - /** - * Forces all {@link Handler} instances registered in the presented {@link Logger} to be flushed. - * - * @param logger to flush (required) - * @return the number of {@link Handler}s flushed (may be 0 or above) - */ - public static int flushAllHandlers(final Logger logger) { - Assert.notNull(logger, "Logger is required"); - - int flushed = 0; - Handler[] handlers = logger.getHandlers(); - if (handlers != null && handlers.length > 0) { - for (Handler h : handlers) { - flushed++; - h.flush(); - } - } - - return flushed; - } -} diff --git a/src/main/java/org/springframework/shell/support/logging/LoggingOutputStream.java b/src/main/java/org/springframework/shell/support/logging/LoggingOutputStream.java deleted file mode 100644 index a303739d..00000000 --- a/src/main/java/org/springframework/shell/support/logging/LoggingOutputStream.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.logging; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; - -import org.springframework.shell.support.util.IOUtils; -import org.springframework.util.Assert; - -/** - * Wraps an {@link OutputStream} and automatically passes each line to the {@link Logger} - * when {@link OutputStream#flush()} or {@link OutputStream#close()} is called. - * - * @author Ben Alex - * @since 1.1 - */ -public class LoggingOutputStream extends OutputStream { - - // Constants - protected static final Logger LOGGER = HandlerUtils.getLogger(LoggingOutputStream.class); - - // Fields - private final Level level; - private String sourceClassName = LoggingOutputStream.class.getName(); - private int count; - private ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - /** - * Constructor - * - * @param level the level at which to log (required) - */ - public LoggingOutputStream(final Level level) { - Assert.notNull(level, "A logging level is required"); - this.level = level; - } - - @Override - public void write(final int b) throws IOException { - baos.write(b); - count++; - } - - @Override - public void flush() throws IOException { - if (count > 0) { - String msg = new String(baos.toByteArray()); - LogRecord record = new LogRecord(level, msg); - record.setSourceClassName(sourceClassName); - try { - LOGGER.log(record); - } finally { - count = 0; - IOUtils.closeQuietly(baos); - baos = new ByteArrayOutputStream(); - } - } - } - - @Override - public void close() throws IOException { - flush(); - } - - public String getSourceClassName() { - return sourceClassName; - } - - public void setSourceClassName(final String sourceClassName) { - this.sourceClassName = sourceClassName; - } -} diff --git a/src/main/java/org/springframework/shell/support/logging/MessageDisplayUtils.java b/src/main/java/org/springframework/shell/support/logging/MessageDisplayUtils.java deleted file mode 100644 index 37005927..00000000 --- a/src/main/java/org/springframework/shell/support/logging/MessageDisplayUtils.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.logging; - -import java.io.BufferedInputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.springframework.shell.support.util.IOUtils; -import org.springframework.util.FileCopyUtils; - -/** - * Retrieves text files from the classloader and displays them on-screen. - * - *

- * Respects normal Roo conventions such as all resources should appear under the same - * package as the bundle itself etc. - * - * @author Ben Alex - * @since 1.1.1 - */ -public abstract class MessageDisplayUtils { - - // Constants - private static Logger LOGGER = HandlerUtils.getLogger(MessageDisplayUtils.class); - - /** - * Displays the requested file via the LOGGER API. - * - *

- * Each file must available from the classloader of the "owner". It must also be in the same - * package as the class of the "owner". So if the owner is com.foo.Bar, and the file is called - * "hello.txt", the file must appear in the same bundle as com.foo.Bar and be available from - * the resource path "/com/foo/Hello.txt". - * - * @param fileName the simple filename (required) - * @param owner the class which owns the file (required) - * @param important if true, it will display with a higher importance color where possible - */ - public static void displayFile(final String fileName, final Class owner, final boolean important) { - Level level = important ? Level.SEVERE : Level.FINE; - String owningPackage = owner.getPackage().getName().replace('.', '/'); - String fullResourceName = "/" + owningPackage + "/" + fileName; - InputStream inputStream = owner.getClassLoader().getResourceAsStream(fullResourceName); - if (inputStream == null) { - throw new IllegalStateException("Could not locate '" + fileName + "'"); - } - try { - String message = FileCopyUtils.copyToString(new InputStreamReader(new BufferedInputStream(inputStream))); - LOGGER.log(level, message); - } catch (Exception e) { - throw new IllegalStateException(e); - } finally { - IOUtils.closeQuietly(inputStream); - } - } - - /** - * Same as {@link #displayFile(String, Class, boolean)} except it passes false as the - * final argument. - * - * @param fileName the simple filename (required) - * @param owner the class which owns the file (required) - */ - public static void displayFile(final String fileName, final Class owner) { - displayFile(fileName, owner, false); - } -} diff --git a/src/main/java/org/springframework/shell/support/table/Table.java b/src/main/java/org/springframework/shell/support/table/Table.java deleted file mode 100644 index 84ed09cf..00000000 --- a/src/main/java/org/springframework/shell/support/table/Table.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2009-2013 the original author or authors. - * - * 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.springframework.shell.support.table; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -/** - * Provide a basic concept of a table structure containing a map of column - * headers and a collection of rows. Used to render text-based tables (console - * output). - * - * @see TableRenderer - * - * @author Gunnar Hillert - * @deprecated In favor of {@link org.springframework.shell.table.TableBuilder} - */ -public class Table { - - private final Map headers = new TreeMap(); - - private volatile List rows = new ArrayList(0); - - public List getRows() { - return rows; - } - - public Map getHeaders() { - return headers; - } - - public Table addHeader(Integer columnIndex, TableHeader tableHeader) { - this.headers.put(columnIndex, tableHeader); - return this; - } - - /** - * Add a new empty row to the table. - * - * @return the newly created row, which can be then be populated - */ - public TableRow newRow() { - TableRow row = new TableRow(); - rows.add(row); - return row; - } - - public Table addRow(String... values) { - - final TableRow row = new TableRow(); - - int column = 1; - - for (String value : values) { - row.addValue(column, value); - column++; - } - - rows.add(row); - - return this; - } - - public void calculateColumnWidths() { - for (java.util.Map.Entry headerEntry : headers - .entrySet()) { - final Integer headerEntryKey = headerEntry.getKey(); - for (TableRow tableRow : rows) { - headerEntry.getValue().updateWidth( - tableRow.getValue(headerEntryKey).length()); - } - } - } - - @Override - public String toString() { - return TableRenderer.renderTextTable(this); - } - - @Override - public int hashCode() { - calculateColumnWidths(); - final int prime = 31; - int result = 1; - result = prime * result + ((headers == null) ? 0 : headers.hashCode()); - result = prime * result + ((rows == null) ? 0 : rows.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - - Table other = (Table) obj; - this.calculateColumnWidths(); - other.calculateColumnWidths(); - if (headers == null) { - if (other.headers != null) - return false; - } else if (!headers.equals(other.headers)) - return false; - if (rows == null) { - if (other.rows != null) - return false; - } else if (!rows.equals(other.rows)) - return false; - return true; - } -} diff --git a/src/main/java/org/springframework/shell/support/table/TableHeader.java b/src/main/java/org/springframework/shell/support/table/TableHeader.java deleted file mode 100644 index 359e5a99..00000000 --- a/src/main/java/org/springframework/shell/support/table/TableHeader.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2009-2013 the original author or authors. - * - * 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.springframework.shell.support.table; - -/** - * Defines table column headers used by {@link Table}. - * - * @see TableRenderer - * - * @author Gunnar Hillert - * @deprecated In favor of {@link org.springframework.shell.table.TableBuilder} - * - */ -public class TableHeader { - - private int maxWidth = -1; - - private int width = 0; - - private String name; - - /** - * Constructor that initializes the table header with the provided header - * name and the with of the table header. - * - * @param name - * @param width - */ - public TableHeader(String name, int width) { - - super(); - this.width = width; - this.name = name; - - } - - /** - * Constructor that initializes the table header with the provided header - * name. The with of the table header is calculated and assigned based on - * the provided header name. - * - * @param name - */ - public TableHeader(String name) { - super(); - this.name = name; - - if (name == null) { - this.width = 0; - } else { - this.width = name.length(); - } - - } - - public int getWidth() { - return width; - } - - public void setWidth(int width) { - this.width = width; - } - - /** - * Updated the width for this particular column, but only if the value of - * the passed-in width is higher than the value of the pre-existing width. - * - * @param width - */ - public void updateWidth(int width) { - if (this.width < width) { - if (this.maxWidth > 0 && this.maxWidth < width) { - this.width = this.maxWidth; - } else { - this.width = width; - } - } - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getMaxWidth() { - return maxWidth; - } - - /** - * Defaults to -1 indicating to ignore the property. - * - * @param maxWidth - * If negative or zero this property will be ignored. - */ - public void setMaxWidth(int maxWidth) { - this.maxWidth = maxWidth; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + maxWidth; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + width; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - TableHeader other = (TableHeader) obj; - if (maxWidth != other.maxWidth) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (width != other.width) - return false; - return true; - } - -} diff --git a/src/main/java/org/springframework/shell/support/table/TableRenderer.java b/src/main/java/org/springframework/shell/support/table/TableRenderer.java deleted file mode 100644 index 188d67f5..00000000 --- a/src/main/java/org/springframework/shell/support/table/TableRenderer.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright 2009-2013 the original author or authors. - * - * 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.springframework.shell.support.table; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.springframework.shell.support.util.StringUtils; - -/** - * Contains utility methods for rendering data to a formatted console output. - * E.g. it provides helper methods for rendering ASCII-based data tables. - * - * @author Gunnar Hillert - * @author Thomas Risberg - * @deprecated In favor of {@link org.springframework.shell.table.TableBuilder} - * - */ -public final class TableRenderer { - - public static final String HORIZONTAL_LINE = "-------------------------------------------------------------------------------\n"; - - public static final int COLUMN_1 = 1; - - public static final int COLUMN_2 = 2; - - public static final int COLUMN_3 = 3; - - public static final int COLUMN_4 = 4; - - public static final int COLUMN_5 = 5; - - public static final int COLUMN_6 = 6; - - /** - * Prevent instantiation. - * - */ - private TableRenderer() { - throw new AssertionError(); - } - - /** - * Renders a textual representation of the list of provided Map data - * - * @param columns - * List of Maps - * @return The rendered table representation as String - * - */ - public static String renderMapDataAsTable(List> data, - List columns) { - - Table table = new Table(); - - int col = 0; - for (String colName : columns) { - col++; - table.getHeaders().put(col, new TableHeader(colName)); - if (col >= 6) { - break; - } - } - - for (Map dataRow : data) { - - TableRow tableRow = new TableRow(); - - for (int i = 0; i < col; i++) { - String value = dataRow.get(columns.get(i)).toString(); - table.getHeaders().get(i + 1).updateWidth(value.length()); - tableRow.addValue(i + 1, value); - } - - table.getRows().add(tableRow); - } - - return renderTextTable(table); - } - - public static String renderParameterInfoDataAsTable( - Map parameters, boolean withHeader, - int lastColumnMaxWidth) { - final Table table = new Table(); - - table.getHeaders().put(COLUMN_1, new TableHeader("Parameter")); - - final TableHeader tableHeader2 = new TableHeader( - "Value (Configured or Default)"); - tableHeader2.setMaxWidth(lastColumnMaxWidth); - table.getHeaders().put(COLUMN_2, tableHeader2); - - for (Entry entry : parameters.entrySet()) { - - final TableRow tableRow = new TableRow(); - - table.getHeaders().get(COLUMN_1) - .updateWidth(entry.getKey().length()); - tableRow.addValue(COLUMN_1, entry.getKey()); - - int width = entry.getValue() != null ? entry.getValue().length() - : 0; - - table.getHeaders().get(COLUMN_2).updateWidth(width); - tableRow.addValue(COLUMN_2, entry.getValue()); - - table.getRows().add(tableRow); - } - - return renderTextTable(table, withHeader); - } - - /** - * Renders a textual representation of provided parameter map. - * - * @param parameters - * Map of parameters (key, value) - * @return The rendered table representation as String - * - */ - public static String renderParameterInfoDataAsTable( - Map parameters) { - return renderParameterInfoDataAsTable(parameters, true, -1); - } - - public static String renderTextTable(Table table) { - return renderTextTable(table, true); - } - - /** - * Renders a textual representation of the provided {@link Table} - * - * @param table - * Table data {@link Table} - * @return The rendered table representation as String - */ - public static String renderTextTable(Table table, boolean withHeader) { - - table.calculateColumnWidths(); - - final String padding = " "; - final String headerBorder = getHeaderBorder(table.getHeaders()); - final StringBuilder textTable = new StringBuilder(); - - if (withHeader) { - final StringBuilder headerline = new StringBuilder(); - for (TableHeader header : table.getHeaders().values()) { - - if (header.getName().length() > header.getWidth()) { - Iterable chunks = split(header.getName(), header.getWidth()); - int length = headerline.length(); - boolean first = true; - for (String chunk : chunks) { - final String lineToAppend; - if (first) { - lineToAppend = padding - + StringUtils.padRight(chunk, - header.getWidth()); - } else { - lineToAppend = StringUtils.padLeft("", length) - + padding - + StringUtils.padRight(chunk, - header.getWidth()); - } - first = false; - headerline.append(lineToAppend); - headerline.append("\n"); - } - headerline.deleteCharAt(headerline.lastIndexOf("\n")); - } else { - String lineToAppend = padding - + StringUtils.padRight(header.getName(), - header.getWidth()); - headerline.append(lineToAppend); - } - } - textTable.append(org.springframework.util.StringUtils - .trimTrailingWhitespace(headerline.toString())); - textTable.append("\n"); - } - - textTable.append(headerBorder); - - for (TableRow row : table.getRows()) { - StringBuilder rowLine = new StringBuilder(); - for (Entry entry : table.getHeaders() - .entrySet()) { - String value = row.getValue(entry.getKey()); - if (value.length() > entry.getValue().getWidth()) { - Iterable chunks = split(value, entry.getValue().getWidth()); - int length = rowLine.length(); - boolean first = true; - for (String chunk : chunks) { - final String lineToAppend; - if (first) { - lineToAppend = padding - + StringUtils.padRight(chunk, entry - .getValue().getWidth()); - } else { - lineToAppend = StringUtils.padLeft("", length) - + padding - + StringUtils.padRight(chunk, entry - .getValue().getWidth()); - } - first = false; - rowLine.append(lineToAppend); - rowLine.append("\n"); - } - rowLine.deleteCharAt(rowLine.lastIndexOf("\n")); - } else { - String lineToAppend = padding - + StringUtils.padRight(value, entry.getValue() - .getWidth()); - rowLine.append(lineToAppend); - } - } - textTable.append(org.springframework.util.StringUtils - .trimTrailingWhitespace(rowLine.toString())); - textTable.append("\n"); - } - - if (!withHeader) { - textTable.append(headerBorder); - } - - return textTable.toString(); - } - - /** - * Renders the Table header border, based on the map of provided headers. - * - * @param headers - * Map of headers containing meta information e.g. name+width of - * header - * @return Returns the rendered header border as String - */ - public static String getHeaderBorder(Map headers) { - - final StringBuilder headerBorder = new StringBuilder(); - - for (TableHeader header : headers.values()) { - headerBorder.append(StringUtils.padRight(" ", - header.getWidth() + 2, '-')); - } - headerBorder.append("\n"); - - return headerBorder.toString(); - } - - private static List split(String in, int length) { - List result = new ArrayList(in.length() / length); - for (int i = 0; i < in.length(); i += length) { - result.add(in.substring(i, Math.min(in.length(), i + length))); - } - return result; - } - -} diff --git a/src/main/java/org/springframework/shell/support/table/TableRow.java b/src/main/java/org/springframework/shell/support/table/TableRow.java deleted file mode 100644 index 98d9ff13..00000000 --- a/src/main/java/org/springframework/shell/support/table/TableRow.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2009-2013 the original author or authors. - * - * 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.springframework.shell.support.table; - -import java.util.HashMap; -import java.util.Map; - -/** - * Holds the table rows used by {@link Table}. - * - * @see TableRenderer - * - * @author Gunnar Hillert - * @author Ilayaperumal Gopinathan - * @deprecated In favor of {@link org.springframework.shell.table.TableBuilder} - * - */ -public class TableRow { - - /** Holds the data for the column */ - private Map data = new HashMap(); - - public void setData(Map data) { - this.data = data; - } - - /** - * Return a value from this row. - * - * @param key - * Column for which to return the value for - * @return Value of the specified column within this row - * - */ - public String getValue(Integer key) { - return data.get(key); - } - - /** - * Add a value to the to the specified column within this row. - * - * @param column - * @param value - */ - public TableRow addValue(Integer column, String value) { - this.data.put(column, value); - return this; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((data == null) ? 0 : data.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - TableRow other = (TableRow) obj; - if (data == null) { - if (other.data != null) - return false; - } else if (!data.equals(other.data)) - return false; - return true; - } - -} diff --git a/src/main/java/org/springframework/shell/support/util/AnsiEscapeCode.java b/src/main/java/org/springframework/shell/support/util/AnsiEscapeCode.java deleted file mode 100644 index 5dc35dee..00000000 --- a/src/main/java/org/springframework/shell/support/util/AnsiEscapeCode.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - -/** - * ANSI escape codes supported by JLine - * - * @author Andrew Swan - * @since 1.2.0 - */ -public enum AnsiEscapeCode { - - // These int literals are non-public constants in ANSIBuffer.ANSICodes - BLINK(5), - BOLD(1), - CONCEALED(8), - FG_BLACK(30), - FG_BLUE(34), - FG_CYAN(36), - FG_GREEN(32), - FG_MAGENTA(35), - FG_RED(31), - FG_YELLOW(33), - FG_WHITE(37), - OFF(0), - REVERSE(7), - UNDERSCORE(4); - - // Constant for the escape character - private static final boolean ANSI_SUPPORTED = Boolean.getBoolean("roo.console.ansi"); - private static final char ESC = 27; - - /** - * Decorates the given text with the given escape codes (turning them off - * afterwards) - * - * @param text the text to decorate; can be null - * @param codes - * @return null if null is passed - */ - public static String decorate(final String text, final AnsiEscapeCode... codes) { - if (text == null || "".equals(text)) { - return text; - } - - final StringBuilder sb = new StringBuilder(); - if (ANSI_SUPPORTED) { - for (final AnsiEscapeCode code : codes) { - sb.append(code.code); - } - } - sb.append(text); - if (codes != null && codes.length > 0 && ANSI_SUPPORTED) { - sb.append(OFF.code); - } - return sb.toString(); - } - - // Fields - final String code; - - /** - * Constructor - * - * @param code the numeric ANSI escape code - */ - private AnsiEscapeCode(final int code) { - // Copied from the method ANSIBuffer.ANSICodes#attrib(int) - this.code = ESC + "[" + code + "m"; - } -} diff --git a/src/main/java/org/springframework/shell/support/util/ExceptionUtils.java b/src/main/java/org/springframework/shell/support/util/ExceptionUtils.java deleted file mode 100644 index 065b0e9b..00000000 --- a/src/main/java/org/springframework/shell/support/util/ExceptionUtils.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - -import org.springframework.util.Assert; - -/** - * Methods for working with exceptions. - * - * @author Ben Alex - * @since 1.0 - */ -public abstract class ExceptionUtils { - - /** - * Obtains the root cause of an exception, if available. - * - * @param ex to extract the root cause from (required) - * @return the root cause, or original exception is unavailable (guaranteed to never be null) - */ - public final static Throwable extractRootCause(final Throwable ex) { - Assert.notNull(ex, "An exception is required"); - Throwable root = ex; - if (ex.getCause() != null) { - root = ex.getCause(); - } - return root; - } -} diff --git a/src/main/java/org/springframework/shell/support/util/FileUtils.java b/src/main/java/org/springframework/shell/support/util/FileUtils.java deleted file mode 100644 index fb6a0919..00000000 --- a/src/main/java/org/springframework/shell/support/util/FileUtils.java +++ /dev/null @@ -1,406 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Arrays; -import java.util.Collection; -import java.util.regex.Pattern; - -import org.springframework.util.AntPathMatcher; -import org.springframework.util.Assert; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.PathMatcher; -import org.springframework.util.StringUtils; - - -/** - * Utilities for handling {@link File} instances. - * - * @author Ben Alex - * @since 1.0 - */ -public final class FileUtils { - - // Constants - private static final String BACKSLASH = "\\"; - private static final String ESCAPED_BACKSLASH = "\\\\"; - - /** - * The relative file path to the current directory. Should be valid on all - * platforms that Roo supports. - */ - public static final String CURRENT_DIRECTORY = "."; - - private static final String WINDOWS_DRIVE_PREFIX = "^[A-Za-z]:"; - - // Doesn't check for backslash after the colon, since Java has no issues with paths like c:/Windows - private static final Pattern WINDOWS_DRIVE_PATH = Pattern.compile(WINDOWS_DRIVE_PREFIX + ".*"); - - private static final PathMatcher PATH_MATCHER; - - static { - PATH_MATCHER = new AntPathMatcher(); - ((AntPathMatcher) PATH_MATCHER).setPathSeparator(File.separator); - } - - /** - * Deletes the specified {@link File}. - * - *

- * If the {@link File} refers to a directory, any contents of that directory (including other directories) - * are also deleted. - * - *

- * If the {@link File} does not already exist, this method immediately returns true. - * - * @param file to delete (required; the file may or may not exist) - * @return true if the file is fully deleted, or false if there was a failure when deleting - */ - public static boolean deleteRecursively(final File file) { - Assert.notNull(file, "File to delete required"); - if (!file.exists()) { - return true; - } - if (file.isDirectory()) { - for (File f : file.listFiles()) { - if (!deleteRecursively(f)) { - return false; - } - } - } - file.delete(); - return true; - } - - /** - * Copies the specified source directory to the destination. - * - *

- * Both the source must exist. If the destination does not already exist, it will be created. If the destination - * does exist, it must be a directory (not a file). - * - * @param source the already-existing source directory (required) - * @param destination the destination directory (required) - * @param deleteDestinationOnExit indicates whether to mark any created destinations for deletion on exit - * @return true if the copy was successful - */ - public static boolean copyRecursively(final File source, final File destination, final boolean deleteDestinationOnExit) { - Assert.notNull(source, "Source directory required"); - Assert.notNull(destination, "Destination directory required"); - Assert.isTrue(source.exists(), "Source directory '" + source + "' must exist"); - Assert.isTrue(source.isDirectory(), "Source directory '" + source + "' must be a directory"); - if (destination.exists()) { - Assert.isTrue(destination.isDirectory(), "Destination directory '" + destination + "' must be a directory"); - } - else { - destination.mkdirs(); - if (deleteDestinationOnExit) { - destination.deleteOnExit(); - } - } - for (File s : source.listFiles()) { - File d = new File(destination, s.getName()); - if (deleteDestinationOnExit) { - d.deleteOnExit(); - } - if (s.isFile()) { - try { - FileCopyUtils.copy(s, d); - } catch (IOException ioe) { - return false; - } - } - else { - // It's a sub-directory, so copy it - d.mkdir(); - if (!copyRecursively(s, d, deleteDestinationOnExit)) { - return false; - } - } - } - return true; - } - - /** - * Checks if the provided fileName denotes an absolute path on the file system. - * On Windows, this includes both paths with and without drive letters, where the latter have to start with '\'. - * No check is performed to see if the file actually exists! - * - * @param fileName name of a file, which could be an absolute path - * @return true if the fileName looks like an absolute path for the current OS - */ - public static boolean denotesAbsolutePath(final String fileName) { - if (OsUtils.isWindows()) { - // first check for drive letter - if (WINDOWS_DRIVE_PATH.matcher(fileName).matches()) { - return true; - } - } - return fileName.startsWith(File.separator); - } - - /** - * Returns the part of the given path that represents a directory, in other - * words the given path if it's already a directory, or the parent directory - * if it's a file. - * - * @param fileIdentifier the path to parse (required) - * @return see above - * @since 1.2.0 - */ - public static String getFirstDirectory(String fileIdentifier) { - fileIdentifier = removeTrailingSeparator(fileIdentifier); - if (new File(fileIdentifier).isDirectory()) { - return fileIdentifier; - } - return backOneDirectory(fileIdentifier); - } - - /** - * Returns the given file system path minus its last element - * - * @param fileIdentifier - * @return - * @since 1.2.0 - */ - public static String backOneDirectory(String fileIdentifier) { - fileIdentifier = removeTrailingSeparator(fileIdentifier); - fileIdentifier = fileIdentifier.substring(0, fileIdentifier.lastIndexOf(File.separator)); - return removeTrailingSeparator(fileIdentifier); - } - - /** - * Removes any trailing {@link File#separator}s from the given path - * - * @param path the path to modify (can be null) - * @return the modified path - * @since 1.2.0 - */ - public static String removeTrailingSeparator(String path) { - while (path != null && path.endsWith(File.separator)) { - path = path.substring(0, path.length() - File.separator.length()); - } - return path; - } - - /** - * Indicates whether the given canonical path matches the given Ant-style pattern - * - * @param antPattern the pattern to check against (can't be blank) - * @param canonicalPath the path to check (can't be blank) - * @return see above - * @since 1.2.0 - */ - public static boolean matchesAntPath(final String antPattern, final String canonicalPath) { - Assert.hasText(antPattern, "Ant pattern required"); - Assert.hasText(canonicalPath, "Canonical path required"); - return PATH_MATCHER.match(antPattern, canonicalPath); - } - - /** - * Removes any leading or trailing {@link File#separator}s from the given path. - * - * @param path the path to modify (can be null) - * @return the path, modified as above, or null if null was given - * @since 1.2.0 - */ - public static String removeLeadingAndTrailingSeparators(String path) { - if (!StringUtils.hasText(path)) { - return path; - } - while (path.endsWith(File.separator)) { - path = path.substring(0, path.length() - File.separator.length()); - } - while (path.startsWith(File.separator)) { - path = path.substring(File.separator.length()); - } - return path; - } - - /** - * Ensures that the given path has exactly one trailing {@link File#separator} - * - * @param path the path to modify (can't be null) - * @return the normalised path - * @since 1.2.0 - */ - public static String ensureTrailingSeparator(final String path) { - Assert.notNull(path); - return removeTrailingSeparator(path) + File.separatorChar; - } - - /** - * Returns an operating-system-dependent path consisting of the given - * elements, separated by {@link File#separator}. - * - * @param pathElements the path elements from uppermost downwards (can't be empty) - * @return a non-blank string - * @since 1.2.0 - */ - public static String getSystemDependentPath(final String... pathElements) { - return getSystemDependentPath(Arrays.asList(pathElements)); - } - - /** - * Returns an operating-system-dependent path consisting of the given - * elements, separated by {@link File#separator}. - * - * @param pathElements the path elements from uppermost downwards (can't be empty) - * @return a non-blank string - * @since 1.2.0 - */ - public static String getSystemDependentPath(final Collection pathElements) { - Assert.notEmpty(pathElements); - return StringUtils.collectionToDelimitedString(pathElements, File.separator); - } - - /** - * Returns the canonical path of the given {@link File}. - * - * @param file the file for which to find the canonical path (can be null) - * @return the canonical path, or null if a null file is given - * @since 1.2.0 - */ - public static String getCanonicalPath(final File file) { - if (file == null) { - return null; - } - try { - return file.getCanonicalPath(); - } catch (final IOException ioe) { - throw new IllegalStateException("Cannot determine canonical path for '" + file + "'", ioe); - } - } - - /** - * Returns the platform-specific file separator as a regular expression. - * - * @return a non-blank regex - * @since 1.2.0 - */ - public static String getFileSeparatorAsRegex() { - final String fileSeparator = File.separator; - if (fileSeparator.contains(BACKSLASH)) { - // Escape the backslashes - return fileSeparator.replace(BACKSLASH, ESCAPED_BACKSLASH); - } - return fileSeparator; - } - - /** - * Determines the path to the requested file, relative to the given class. - * - * @param loadingClass the class to whose package the given file is relative (required) - * @param relativeFilename the name of the file relative to that package (required) - * @return the full classloader-specific path to the file (never null) - * @since 1.2.0 - */ - public static String getPath(final Class loadingClass, final String relativeFilename) { - Assert.notNull(loadingClass, "Loading class required"); - Assert.hasText(relativeFilename, "Filename required"); - Assert.isTrue(!relativeFilename.startsWith("/"), "Filename shouldn't start with a slash"); - // Slashes instead of File.separatorChar is correct here, as these are classloader paths (not file system paths) - return "/" + loadingClass.getPackage().getName().replace('.', '/') + "/" + relativeFilename; - } - - /** - * Loads the given file from the classpath. - * - * @param loadingClass the class from whose package to load the file (required) - * @param filename the name of the file to load, relative to that package (required) - * @return the file's input stream (never null) - * @throws IllegalArgumentException if the given file cannot be found - */ - public static File getFile(final Class loadingClass, final String filename) { - final URL url = loadingClass.getResource(filename); - Assert.notNull(url, "Could not locate '" + filename + "' in classpath of " + loadingClass.getName()); - try { - return new File(url.toURI()); - } catch (URISyntaxException e) { - throw new IllegalArgumentException(e); - } - } - - /** - * Loads the given file from the classpath. - * - * @param loadingClass the class from whose package to load the file (required) - * @param filename the name of the file to load, relative to that package (required) - * @return the file's input stream (never null) - * @throws IllegalArgumentException if the given file cannot be found - */ - public static InputStream getInputStream(final Class loadingClass, final String filename) { - final InputStream inputStream = loadingClass.getResourceAsStream(filename); - Assert.notNull(inputStream, "Could not locate '" + filename + "' in classpath of " + loadingClass.getName()); - return inputStream; - } - - /** - * Reads a banner from the given resource. Performs conversion of any line separator contained by the source to that of the running platform. - * - * @return platform-compatible banner as a String - */ - public static String readBanner(Reader reader) { - try { - String content = FileCopyUtils.copyToString(new BufferedReader(reader)); - return content.replaceAll("(\\r|\\n)+", OsUtils.LINE_SEPARATOR); - } catch (Exception ex) { - throw new IllegalStateException("Cannot read stream", ex); - } - } - - /** - * Reads a banner from the given resource. Performs conversion of any line separator contained by the source to that of the running platform. - * - * @return platform-compatible banner as a String - */ - public static String readBanner(final Class loadingClass, String resourceName) { - return readBanner(new InputStreamReader(getInputStream(loadingClass, resourceName))); - } - - /** - * Returns the contents of the given File as a String. - * - * @param file the file to read from (must be an existing file) - * @return the contents - * @throws IllegalStateException in case of I/O errors - * @since 1.2.0 - */ - public static String read(final File file) { - try { - return FileCopyUtils.copyToString(new FileReader(file)); - } catch (final IOException e) { - throw new IllegalStateException(e); - } - } - - /** - * Constructor is private to prevent instantiation - * - * @since 1.2.0 - */ - private FileUtils() { - } -} diff --git a/src/main/java/org/springframework/shell/support/util/IOUtils.java b/src/main/java/org/springframework/shell/support/util/IOUtils.java deleted file mode 100644 index 7220634d..00000000 --- a/src/main/java/org/springframework/shell/support/util/IOUtils.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - -import java.io.Closeable; -import java.io.IOException; -import java.util.zip.ZipFile; - -/** - * Static helper methods relating to I/O. Inspired by the eponymous class in - * Apache Commons I/O. - * - * @author Andrew Swan - * @since 1.2.0 - */ -public final class IOUtils { - - /** - * Quietly closes each of the given {@link Closeable}s, i.e. eats any - * {@link IOException}s arising. - * - * @param closeables the closeables to close (any of which can be - * null or already closed) - */ - public static void closeQuietly(final Closeable... closeables) { - for (final Closeable closeable : closeables) { - if (closeable != null) { - try { - closeable.close(); - } catch (IOException e) { - // Ignore - } - } - } - } - - /** - * Quietly closes each of the given {@link ZipFile}s, i.e. eats any - * {@link IOException}s arising. - * - * @param zipFiles the zipFiles to close (any of which can be - * null or already closed) - */ - public static void closeQuietly(final ZipFile... zipFiles) { - for (final ZipFile zipFile : zipFiles) { - if (zipFile != null) { - try { - zipFile.close(); - } catch (IOException e) { - // Ignore - } - } - } - } - - /** - * Constructor is private to prevent instantiation - */ - private IOUtils() {} -} diff --git a/src/main/java/org/springframework/shell/support/util/MathUtils.java b/src/main/java/org/springframework/shell/support/util/MathUtils.java deleted file mode 100644 index 68a41bc8..00000000 --- a/src/main/java/org/springframework/shell/support/util/MathUtils.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - -/** - * A class which contains a number of number manipulation operations - * - * @author James Tyrrell - * @since 1.2.0 - */ -public class MathUtils { - - public static double round(final double valueToRound, final int numberOfDecimalPlaces) { - double multiplicationFactor = Math.pow(10, numberOfDecimalPlaces); - double interestedInZeroDPs = valueToRound * multiplicationFactor; - return Math.round(interestedInZeroDPs) / multiplicationFactor; - } -} diff --git a/src/main/java/org/springframework/shell/support/util/NaturalOrderComparator.java b/src/main/java/org/springframework/shell/support/util/NaturalOrderComparator.java deleted file mode 100644 index d54a7a18..00000000 --- a/src/main/java/org/springframework/shell/support/util/NaturalOrderComparator.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - -import java.util.Comparator; - -/** - * NaturalOrderComparator.java -- Perform natural order comparisons of strings in Java. - * Copyright (C) 2003 by Pierre-Luc Paour - * Based on the C version by Martin Pool, of which this is more or less a straight conversion. - * Copyright (C) 2000 by Martin Pool - * - * This software is provided as-is, without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgement in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - */ -public class NaturalOrderComparator implements Comparator { - - /** - * Returns the character at the given position of the given string; - * equivalent to {@link String#charAt(int)}, but handles overly large - * indices. - * - * @param s the string to read (can't be null) - * @param i the index at which to read (zero-based) - * @return 0 if the given index is beyond the end of the string - */ - static char charAt(final String s, final int i) { - if (i >= s.length()) { - return 0; - } - return s.charAt(i); - } - - /** - * Indicates whether the given character is whitespace - * - * @param c the character to check - * @return see above - */ - public static boolean isSpace(final char c) { - switch (c) { - case ' ': - return true; - case '\n': - return true; - case '\t': - return true; - case '\f': - return true; - case '\r': - return true; - default: - return false; - } - } - - int compareRight(final String a, final String b) { - int bias = 0; - int ia = 0; - int ib = 0; - - // The longest run of digits wins. That aside, the greatest - // value wins, but we can't know that it will until we've scanned - // both numbers to know that they have the same magnitude, so we - // remember it in BIAS. - for (; ; ia++, ib++) { - char ca = charAt(a, ia); - char cb = charAt(b, ib); - - if (!Character.isDigit(ca) && !Character.isDigit(cb)) { - return bias; - } else if (!Character.isDigit(ca)) { - return -1; - } else if (!Character.isDigit(cb)) { - return +1; - } else if (ca < cb) { - if (bias == 0) { - bias = -1; - } - } else if (ca > cb) { - if (bias == 0) - bias = +1; - } else if (ca == 0 && cb == 0) { - return bias; - } - } - } - - protected String stringify(final E object) { - return object.toString(); - } - - public int compare(final E o1, final E o2) { - if (o1 == null && o2 == null) { - return 1; - } - - if (o1 == null) { - return 1; - } - - if (o2 == null) { - return -1; - } - - String a = stringify(o1); - String b = stringify(o2); - - int ia = 0, ib = 0; - int nza = 0, nzb = 0; - char ca, cb; - int result; - - while (true) { - // Only count the number of zeroes leading the last number compared - nza = nzb = 0; - - ca = charAt(a, ia); - cb = charAt(b, ib); - - // Skip over leading spaces or zeros - while (isSpace(ca) || ca == '0') { - if (ca == '0') { - nza++; - } else { - // Only count consecutive zeroes - nza = 0; - } - - ca = charAt(a, ++ia); - } - - while (isSpace(cb) || cb == '0') { - if (cb == '0') { - nzb++; - } else { - // Only count consecutive zeroes - nzb = 0; - } - - cb = charAt(b, ++ib); - } - - // Process run of digits - if (Character.isDigit(ca) && Character.isDigit(cb)) { - if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0) { - return result; - } - } - - if (ca == 0 && cb == 0) { - // The strings compare the same. Perhaps the caller - // will want to call strcmp to break the tie. - return nza - nzb; - } - - if (ca < cb) { - return -1; - } else if (ca > cb) { - return +1; - } - - ++ia; - ++ib; - } - } -} diff --git a/src/main/java/org/springframework/shell/support/util/OsUtils.java b/src/main/java/org/springframework/shell/support/util/OsUtils.java deleted file mode 100644 index f374f5d3..00000000 --- a/src/main/java/org/springframework/shell/support/util/OsUtils.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - -/** - * Utilities for handling OS-specific behavior. - * - * @author Joris Kuipers - * @since 1.1.1 - */ -public class OsUtils { - - public static final String LINE_SEPARATOR = System.getProperty("line.separator"); - - private static final boolean WINDOWS_OS = System.getProperty("os.name").toLowerCase().contains("windows"); - - public static boolean isWindows() { - return WINDOWS_OS; - } -} diff --git a/src/main/java/org/springframework/shell/support/util/StringUtils.java b/src/main/java/org/springframework/shell/support/util/StringUtils.java deleted file mode 100644 index 74fddf94..00000000 --- a/src/main/java/org/springframework/shell/support/util/StringUtils.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright 2009-2013 the original author or authors. - * - * 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.springframework.shell.support.util; - - -/** - * Utility methods for Strings focused on the use in formatting of tables. padLeft methods taken from - * Commons Lang 2.6 to avoid an extra compile time dependency. - * - * @author Gunnar Hillert - * @author Mark Pollack - * - */ -public class StringUtils { - - /** - *

- * The maximum size to which the padding constant(s) can expand. - *

- */ - private static final int PAD_LIMIT = 8192; - - /** - *

- * Left pad a String with spaces (' '). - *

- * - *

- * The String is padded to the size of size. - *

- * - *
-	 * StringUtils.leftPad(null, *) = null
-	 * StringUtils.leftPad("", 3) = " "
-	 * StringUtils.leftPad("bat", 3) = "bat"
-	 * StringUtils.leftPad("bat", 5) = " bat"
-	 * StringUtils.leftPad("bat", 1) = "bat"
-	 * StringUtils.leftPad("bat", -1) = "bat"
-	 * 
- * - * @param str - * the String to pad out, may be null - * @param size - * the size to pad to - * @return left padded String or original String if no padding is necessary, - * null if null String input - */ - public static String padLeft(String str, int size) { - return padLeft(str, size, ' '); - } - - /** - *

- * Left pad a String with a specified character. - *

- * - *

- * Pad to a size of size. - *

- * - *
-	 * StringUtils.leftPad(null, *, *) = null
-	 * StringUtils.leftPad("", 3, 'z') = "zzz"
-	 * StringUtils.leftPad("bat", 3, 'z') = "bat"
-	 * StringUtils.leftPad("bat", 5, 'z') = "zzbat"
-	 * StringUtils.leftPad("bat", 1, 'z') = "bat"
-	 * StringUtils.leftPad("bat", -1, 'z') = "bat"
-	 * 
- * - * @param str - * the String to pad out, may be null - * @param size - * the size to pad to - * @param padChar - * the character to pad with - * @return left padded String or original String if no padding is necessary, - * null if null String input - * @since 2.0 - */ - public static String padLeft(String str, int size, char padChar) { - if (str == null) { - return null; - } - int pads = size - str.length(); - if (pads <= 0) { - return str; // returns original String when possible - } - if (pads > PAD_LIMIT) { - return padLeft(str, size, String.valueOf(padChar)); - } - return padding(pads, padChar).concat(str); - } - - /** - *

- * Left pad a String with a specified String. - *

- * - *

- * Pad to a size of size. - *

- * - *
-	 * StringUtils.leftPad(null, *, *) = null
-	 * StringUtils.leftPad("", 3, "z") = "zzz"
-	 * StringUtils.leftPad("bat", 3, "yz") = "bat"
-	 * StringUtils.leftPad("bat", 5, "yz") = "yzbat"
-	 * StringUtils.leftPad("bat", 8, "yz") = "yzyzybat"
-	 * StringUtils.leftPad("bat", 1, "yz") = "bat"
-	 * StringUtils.leftPad("bat", -1, "yz") = "bat"
-	 * StringUtils.leftPad("bat", 5, null) = " bat"
-	 * StringUtils.leftPad("bat", 5, "") = " bat"
-	 * 
- * - * @param str - * the String to pad out, may be null - * @param size - * the size to pad to - * @param padStr - * the String to pad with, null or empty treated as single space - * @return left padded String or original String if no padding is necessary, - * null if null String input - */ - public static String padLeft(String str, int size, String padStr) { - if (str == null) { - return null; - } - if (isEmpty(padStr)) { - padStr = " "; - } - int padLen = padStr.length(); - int strLen = str.length(); - int pads = size - strLen; - if (pads <= 0) { - return str; // returns original String when possible - } - if (padLen == 1 && pads <= PAD_LIMIT) { - return padLeft(str, size, padStr.charAt(0)); - } - - if (pads == padLen) { - return padStr.concat(str); - } else if (pads < padLen) { - return padStr.substring(0, pads).concat(str); - } else { - char[] padding = new char[pads]; - char[] padChars = padStr.toCharArray(); - for (int i = 0; i < pads; i++) { - padding[i] = padChars[i % padLen]; - } - return new String(padding).concat(str); - } - } - - /** - *

- * Checks if a String is empty ("") or null. - *

- * - *
-	 * StringUtils.isEmpty(null) = true
-	 * StringUtils.isEmpty("") = true
-	 * StringUtils.isEmpty(" ") = false
-	 * StringUtils.isEmpty("bob") = false
-	 * StringUtils.isEmpty(" bob ") = false
-	 * 
- * - *

- * NOTE: This method changed in Lang version 2.0. It no longer trims the - * String. That functionality is available in isBlank(). - *

- * - * @param str - * the String to check, may be null - * @return true if the String is empty or null - */ - public static boolean isEmpty(String str) { - return str == null || str.length() == 0; - } - - /** - *

- * Returns padding using the specified delimiter repeated to a given length. - *

- * - *
-	 * StringUtils.padding(0, 'e') = ""
-	 * StringUtils.padding(3, 'e') = "eee"
-	 * StringUtils.padding(-2, 'e') = IndexOutOfBoundsException
-	 * 
- * - *

- * Note: this method doesn't not support padding with Unicode - * Supplementary Characters as they require a pair of chars - * to be represented. If you are needing to support full I18N of your - * applications consider using {@link #repeat(String, int)} instead. - *

- * - * @param repeat - * number of times to repeat delim - * @param padChar - * character to repeat - * @return String with repeated character - * @throws IndexOutOfBoundsException - * if repeat < 0 - * @see #repeat(String, int) - */ - private static String padding(int repeat, char padChar) - throws IndexOutOfBoundsException { - if (repeat < 0) { - throw new IndexOutOfBoundsException( - "Cannot pad a negative amount: " + repeat); - } - final char[] buf = new char[repeat]; - for (int i = 0; i < buf.length; i++) { - buf[i] = padChar; - } - return new String(buf); - } - - /** - * Right-pad a String with a configurable padding character. - * - * @param inputString - * The String to pad. A {@code null} String will be treated like - * an empty String. - * @param size - * Pad String by the number of characters. - * @param paddingChar - * The character to pad the String with. - * @return The padded String. If the provided String is null, an empty - * String is returned. - */ - public static String padRight(String inputString, int size, char paddingChar) { - - final String stringToPad; - - if (inputString == null) { - stringToPad = ""; - } else { - stringToPad = inputString; - } - - StringBuilder padded = new StringBuilder(stringToPad); - while (padded.length() < size) { - padded.append(paddingChar); - } - return padded.toString(); - } - - /** - * Right-pad the provided String with empty spaces. - * - * @param string - * The String to pad - * @param size - * Pad String by the number of characters. - * @return The padded String. If the provided String is null, an empty - * String is returned. - */ - public static String padRight(String string, int size) { - return padRight(string, size, ' '); - } - -} diff --git a/src/main/java/org/springframework/shell/support/util/VersionUtils.java b/src/main/java/org/springframework/shell/support/util/VersionUtils.java deleted file mode 100644 index b2154fd4..00000000 --- a/src/main/java/org/springframework/shell/support/util/VersionUtils.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - - -/** - * @author Jarred Li - */ -public class VersionUtils { - - /** - * Returns the full version string of the present Spring Shell codebase, - * or null if it cannot be determined. - * @see java.lang.Package#getImplementationVersion() - */ - public static String versionInfo() { - Package pkg = VersionUtils.class.getPackage(); - String version = null; - if (pkg != null) { - version = pkg.getImplementationVersion(); - } - return (version != null ? version : "Unknown Version"); - } -} diff --git a/src/main/java/org/springframework/shell/table/AbsoluteWidthSizeConstraints.java b/src/main/java/org/springframework/shell/table/AbsoluteWidthSizeConstraints.java deleted file mode 100644 index a32e7721..00000000 --- a/src/main/java/org/springframework/shell/table/AbsoluteWidthSizeConstraints.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * A cell sizing strategy that forces a fixed width, expressed in number of characters. - * - * @author Eric Bottard - */ -public class AbsoluteWidthSizeConstraints implements SizeConstraints { - - private final int width; - - public AbsoluteWidthSizeConstraints(int width) { - this.width = width; - } - - - @Override - public Extent width(String[] raw, int previous, int tableWidth) { - return new Extent(width, width); - } -} diff --git a/src/main/java/org/springframework/shell/table/Aligner.java b/src/main/java/org/springframework/shell/table/Aligner.java deleted file mode 100644 index 23ac5ce0..00000000 --- a/src/main/java/org/springframework/shell/table/Aligner.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * A strategy interface for performing text alignment. - * - * @author Eric Bottard - */ -public interface Aligner { - - /** - * Perform text alignment, returning a String array that MUST contain - * {@code cellHeight} lines, each of which MUST be {@code cellWidth} chars in length. - * - *

Input array is guaranteed to contain lines that have length equal to {@cellWidth}. There - * is no guarantee on the input number of lines though.

- */ - String[] align(String[] text, int cellWidth, int cellHeight); -} diff --git a/src/main/java/org/springframework/shell/table/ArrayTableModel.java b/src/main/java/org/springframework/shell/table/ArrayTableModel.java deleted file mode 100644 index 1b7baf81..00000000 --- a/src/main/java/org/springframework/shell/table/ArrayTableModel.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import org.springframework.util.Assert; - -/** - * A TableModel backed by a row-first array. - * - * @author Eric Bottard - */ -public class ArrayTableModel extends TableModel { - - private Object[][] data; - - public ArrayTableModel(Object[][] data) { - this.data = data; - int width = data.length > 0 ? data[0].length : 0; - for (int row = 0; row < data.length; row++) { - Assert.isTrue(width == data[row].length, "All rows of array data must be of same length"); - } - } - - public int getRowCount() { - return data.length; - } - - public int getColumnCount() { - return data.length > 0 ? data[0].length : 0; - } - - public Object getValue(int row, int column) { - return data[row][column]; - } -} diff --git a/src/main/java/org/springframework/shell/table/AutoSizeConstraints.java b/src/main/java/org/springframework/shell/table/AutoSizeConstraints.java deleted file mode 100644 index 7789427f..00000000 --- a/src/main/java/org/springframework/shell/table/AutoSizeConstraints.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * A SizeConstraints implementation that splits lines at space boundaries - * and returns an extent with minimal and maximal width requirements. - * - * @author Eric Bottard - */ -public class AutoSizeConstraints implements SizeConstraints { - - @Override - public Extent width(String[] raw, int tableWidth, int nbColumns) { - int max = 0; - int min = 0; - for (String line : raw) { - String[] words = line.split(" "); - for (String word : words) { - min = Math.max(min, word.length()); - } - max = Math.max(max, line.length()); - } - return new Extent(min, max); - } -} diff --git a/src/main/java/org/springframework/shell/table/BeanListTableModel.java b/src/main/java/org/springframework/shell/table/BeanListTableModel.java deleted file mode 100644 index 958a831e..00000000 --- a/src/main/java/org/springframework/shell/table/BeanListTableModel.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import java.beans.PropertyDescriptor; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; - -import org.springframework.beans.BeanUtils; -import org.springframework.beans.BeanWrapper; -import org.springframework.beans.BeanWrapperImpl; - -/** - * A table model that is backed by a list of beans. - * - *

One can control which properties are exposed (and their order). There is also - * a convenience constructor for adding a special header row.

- * - * @author Eric Bottard - */ -public class BeanListTableModel extends TableModel { - - private final List data; - - private final List propertyNames; - - private final List headerRow; - - public BeanListTableModel(Class clazz, Iterable list) { - this.data = new ArrayList(); - for (T bean : list) { - this.data.add(new BeanWrapperImpl(bean)); - } - this.headerRow = null; - propertyNames = new ArrayList(); - for (PropertyDescriptor propertyName : BeanUtils.getPropertyDescriptors(clazz)) { - if ("class".equals(propertyName.getName())) { - continue; - } - propertyNames.add(propertyName.getName()); - } - } - - public BeanListTableModel(Iterable list, String... propertyNames) { - this.data = new ArrayList(); - for (T bean : list) { - this.data.add(new BeanWrapperImpl(bean)); - } - this.headerRow = null; - this.propertyNames = Arrays.asList(propertyNames); - } - - public BeanListTableModel(Iterable list, LinkedHashMap header) { - this.data = new ArrayList(); - for (T bean : list) { - this.data.add(new BeanWrapperImpl(bean)); - } - this.headerRow = new ArrayList(header.values()); - propertyNames = new ArrayList(header.keySet()); - } - - @Override - public int getRowCount() { - return headerRow == null ? data.size() : 1 + data.size(); - } - - @Override - public int getColumnCount() { - return propertyNames.size(); - } - - @Override - public Object getValue(int row, int column) { - if (headerRow != null && row == 0) { - return headerRow.get(column); - } - else { - int rowToUse = headerRow == null ? row : row - 1; - String propertyName = propertyNames.get(column); - return data.get(rowToUse).getPropertyValue(propertyName); - } - } -} diff --git a/src/main/java/org/springframework/shell/table/BorderSpecification.java b/src/main/java/org/springframework/shell/table/BorderSpecification.java deleted file mode 100644 index f7227efc..00000000 --- a/src/main/java/org/springframework/shell/table/BorderSpecification.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -/** - * This represents a directive to set some borders on cells of a table. - * Multiple specifications can be combined on a single table. - * - * @author Eric Bottard - */ -public class BorderSpecification { - - public static final int NONE = 0; - - public static final int TOP = 1; - - public static final int BOTTOM = 2; - - public static final int LEFT = 4; - - public static final int RIGHT = 8; - - public static final int INNER_VERTICAL = 16; - - public static final int INNER_HORIZONTAL = 32; - - public static final int OUTLINE = TOP | BOTTOM | LEFT | RIGHT; - - public static final int FULL = OUTLINE | INNER_HORIZONTAL | INNER_VERTICAL; - - public static final int INNER = INNER_HORIZONTAL | INNER_VERTICAL; - - private final int row1, row2, column1, column2; - - private final int match; - - private final BorderStyle style; - - /** - * Specifications are created by {@link Table#addBorder(int, int, int, int, int, BorderStyle)}. - */ - /*default*/ BorderSpecification(int row1, int column1, int row2, int column2, int match, BorderStyle style) { - this.row1 = row1; - this.row2 = row2; - this.column1 = column1; - this.column2 = column2; - this.match = match; - this.style = style; - } - - /** - * Does this specification result in the need to paint a vertical bar at row,column? - */ - /*default*/ char verticals(int row, int column) { - boolean result = (match & LEFT) == LEFT && column == column1; - result |= (match & INNER_VERTICAL) == INNER_VERTICAL && column > column1 && column < column2; - result |= (match & RIGHT) == RIGHT && column == column2; - - result &= row >= row1; - result &= row < row2; - return result ? style.verticalGlyph() : BorderStyle.NONE; - } - - /** - * Does this specification result in the need to paint an horizontal bar at row,column? - */ - /*default*/ char horizontals(int row, int column) { - boolean result = (match & TOP) == TOP && row == row1; - result |= (match & INNER_HORIZONTAL) == INNER_HORIZONTAL && row > row1 && row < row2; - result |= (match & BOTTOM) == BOTTOM && row == row2; - - result &= column >= column1; - result &= column < column2; - return result ? style.horizontalGlyph() : BorderStyle.NONE; - } - - @Override - public String toString() { - return String.format("%s[(%d, %d)->(%d, %d), %s, %s]", getClass().getSimpleName(), row1, column1, row2, column2, style, matchConstants()); - } - - private String matchConstants() { - try { - for (String field : new String[] {"NONE", "INNER", "FULL", "OUTLINE"}) { - int value = ReflectionUtils.findField(getClass(), field).getInt(null); - if (match == value) { - return field; - } - } - List constants = new ArrayList(); - for (String field : new String[] {"TOP", "BOTTOM", "LEFT", "RIGHT", "INNER_HORIZONTAL", "INNER_VERTICAL"}) { - int value = ReflectionUtils.findField(getClass(), field).getInt(null); - if ((match & value) == value) { - constants.add(field); - } - } - return StringUtils.collectionToDelimitedString(constants, "|"); - } - catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/shell/table/BorderStyle.java b/src/main/java/org/springframework/shell/table/BorderStyle.java deleted file mode 100644 index b6b69ea7..00000000 --- a/src/main/java/org/springframework/shell/table/BorderStyle.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import java.util.HashMap; -import java.util.Map; - -/** - * Provides support for different styles of borders, using simple or fancy ascii art. - * - * @see https://en.wikipedia.org/wiki/Box-drawing_character - * - * @author Eric Bottard - */ -public enum BorderStyle { - - /** - * A simplistic style, using characters that ought to always be available in all systems (pipe and minus). - */ - oldschool('|', '-'), - - /** - * A border style that uses dedicated light box drawing characters from the unicode set. - */ - fancy_light('│', '─'), - - /** - * A border style that uses dedicated fat box drawing characters from the unicode set. - */ - fancy_heavy('┃', '━'), - - /** - * A border style that uses dedicated double-light box drawing characters from the unicode set. - */ - fancy_double('║', '═'), - - /** - * A border style that uses space characters, giving some space between columns. - */ - air(' ', ' '), - - /** - * A border style that uses dedicated double dash light box drawing characters from the unicode set. - */ - fancy_light_double_dash('╎', '╌'), - - /** - * A border style that uses dedicated double dash light box drawing characters from the unicode set. - */ - fancy_light_triple_dash('┆', '┄'), - - /** - * A border style that uses dedicated double dash light box drawing characters from the unicode set. - */ - fancy_light_quadruple_dash('┊', '┈'), - - /** - * A border style that uses dedicated double dash heavy box drawing characters from the unicode set. - */ - fancy_heavy_double_dash('╏', '╍'), - - /** - * A border style that uses dedicated double dash heavy box drawing characters from the unicode set. - */ - fancy_heavy_triple_dash('┇', '┅'), - - /** - * A border style that uses dedicated double dash heavy box drawing characters from the unicode set. - */ - fancy_heavy_quadruple_dash('┋', '┉'), - - ; - - private char vertical; - - private char horizontal; - - public static final char NONE = '\u0000'; - - private static Map CORNERS = new HashMap(); - - private static Map EQUIVALENTS = new HashMap(); - - public char verticalGlyph() { - return vertical; - } - - public char horizontalGlyph() { - return horizontal; - } - - static { - registerCorners("─│┌┐└┘├┤┬┴┼"); - registerCorners("━┃┏┓┗┛┣┫┳┻╋"); - - // double dashes - registerCorners("╌╎┌┐└┘├┤┬┴┼"); - registerCorners("╍╏┏┓┗┛┣┫┳┻╋"); - - // triple dashes - registerCorners("┈┆┌┐└┘├┤┬┴┼"); - registerCorners("┅┇┏┓┗┛┣┫┳┻╋"); - - // quad dashes - registerCorners("┈┊┌┐└┘├┤┬┴┼"); - registerCorners("┉┋┏┓┗┛┣┫┳┻╋"); - - // double lines - registerCorners("═║╔╗╚╝╠╣╦╩╬"); - // oldschool - registerCorners("-|+++++++++"); - // air style - registerCorners(" "); - - // Register some mixed-style combinations - // light + heavy - registerCorner('│', '│', '━', NONE, '┥'); - registerCorner('│', '│', NONE, '━', '┝'); - registerCorner('┃', NONE, '─', '─', '┸'); - registerCorner(NONE, '┃', '─', '─', '┰'); - // heavy + light - registerCorner('┃', '┃', '─', NONE, '┨'); - registerCorner('┃', '┃', NONE, '─', '┠'); - registerCorner('│', NONE, '━', '━', '┷'); - registerCorner(NONE, '│', '━', '━', '┯'); - // double + single - registerCorner('║', '║', '─', NONE, '╢'); - registerCorner('║', '║', NONE, '─', '╟'); - registerCorner('│', NONE, '═', '═', '╧'); - registerCorner(NONE, '│', '═', '═', '╤'); - // single + double - registerCorner('│', '│', '═', NONE, '╡'); - registerCorner('│', '│', NONE, '═', '╞'); - registerCorner('║', NONE, '─', '─', '╨'); - registerCorner(NONE, '║', '─', '─', '╥'); - // heavy + light, 90° - registerCorner('┃', '│', '━', '─', '╃'); - registerCorner('│', '┃', '─', '━', '╆'); - registerCorner('┃', '│', '─', '━', '╄'); - registerCorner('│', '┃', '━', '─', '╅'); - // light crossing (heavy or double) - registerCorner('│', '│', '━', '━', '┿'); - registerCorner('│', '│', '═', '═', '╪'); - registerCorner('┃', '┃', '─', '─', '╂'); - registerCorner('║', '║', '─', '─', '╫'); - - // Dashed variants crossing others behave like regular corners - registerSameCorners(fancy_light_double_dash, fancy_light); - registerSameCorners(fancy_light_triple_dash, fancy_light); - registerSameCorners(fancy_light_quadruple_dash, fancy_light); - registerSameCorners(fancy_heavy_double_dash, fancy_heavy); - registerSameCorners(fancy_heavy_triple_dash, fancy_heavy); - registerSameCorners(fancy_heavy_quadruple_dash, fancy_heavy); - - - // Air-style glyphs are easy to combine with others. Register some combinations - registerMixedWithAirCombinations(oldschool.vertical, oldschool.horizontal); - registerMixedWithAirCombinations(fancy_light.vertical, fancy_light.horizontal); - registerMixedWithAirCombinations(fancy_double.vertical, fancy_double.horizontal); - registerMixedWithAirCombinations(fancy_heavy.vertical, fancy_heavy.horizontal); - - registerMixedWithAirCombinations(fancy_light_double_dash.vertical, fancy_light_double_dash.horizontal); - registerMixedWithAirCombinations(fancy_light_triple_dash.vertical, fancy_light_triple_dash.horizontal); - registerMixedWithAirCombinations(fancy_light_quadruple_dash.vertical, fancy_light_quadruple_dash.horizontal); - registerMixedWithAirCombinations(fancy_heavy_double_dash.vertical, fancy_heavy_double_dash.horizontal); - registerMixedWithAirCombinations(fancy_heavy_triple_dash.vertical, fancy_heavy_triple_dash.horizontal); - registerMixedWithAirCombinations(fancy_heavy_quadruple_dash.vertical, fancy_heavy_quadruple_dash.horizontal); - } - - /** - * Register the fact that for corner purposes, style1 behaves like style2. - */ - private static void registerSameCorners(BorderStyle style1, BorderStyle style2) { - EQUIVALENTS.put(style1.horizontal, style2.horizontal); - EQUIVALENTS.put(style1.vertical, style2.vertical); - } - - private static void registerMixedWithAirCombinations(char vertical, char horizontal) { - registerCorner(vertical, vertical, ' ', NONE, vertical); - registerCorner(vertical, vertical, NONE, ' ', vertical); - registerCorner(vertical, vertical, ' ', ' ', vertical); - registerCorner(' ', NONE, horizontal, horizontal, horizontal); - registerCorner(NONE, ' ', horizontal, horizontal, horizontal); - registerCorner(' ', ' ', horizontal, horizontal, horizontal); - - } - - /** - * Register corner glyphs for a given set, not taking care of mixed style intersections. - */ - private static void registerCorners(String list) { - char horizontal = list.charAt(0); - char vertical = list.charAt(1); - registerCorner(NONE, vertical, NONE, horizontal, list.charAt(2)); - registerCorner(NONE, vertical, horizontal, NONE, list.charAt(3)); - registerCorner(vertical, NONE, NONE, horizontal, list.charAt(4)); - registerCorner(vertical, NONE, horizontal, NONE, list.charAt(5)); - registerCorner(vertical, vertical, NONE, horizontal, list.charAt(6)); - registerCorner(vertical, vertical, horizontal, NONE, list.charAt(7)); - registerCorner(NONE, vertical, horizontal, horizontal, list.charAt(8)); - registerCorner(vertical, NONE, horizontal, horizontal, list.charAt(9)); - registerCorner(vertical, vertical, horizontal, horizontal, list.charAt(10)); - - } - - private static void registerCorner(char above, char below, char left, char right, char corner) { - long key = key(above, below, left, right); - CORNERS.put(key, corner); - } - - public static char intersection(char above, char below, char left, char right) { - above = EQUIVALENTS.get(above) != null ? EQUIVALENTS.get(above) : above; - below = EQUIVALENTS.get(below) != null ? EQUIVALENTS.get(below) : below; - left = EQUIVALENTS.get(left) != null ? EQUIVALENTS.get(left) : left; - right = EQUIVALENTS.get(right) != null ? EQUIVALENTS.get(right) : right; - Character character = CORNERS.get(key(above, below, left, right)); - return character != null ? character : NONE; - } - - private static long key(char above, char below, char left, char right) { - return (long) above << 48 | (long) below << 32 | (long) left << 16 | (long) right; - } - - BorderStyle(char vertical, char horizontal) { - this.vertical = vertical; - this.horizontal = horizontal; - } - -} diff --git a/src/main/java/org/springframework/shell/table/CellMatcher.java b/src/main/java/org/springframework/shell/table/CellMatcher.java deleted file mode 100644 index dda53f14..00000000 --- a/src/main/java/org/springframework/shell/table/CellMatcher.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * This is used to specify where some components of a Table may be applied. - * - *

Some commonly used matchers can be created via {@link CellMatchers}.

- * - * @author Eric Bottard - */ -public interface CellMatcher { - - /** - * Return whether a given cell of the table should match. - */ - public boolean matches(int row, int column, TableModel model); -} diff --git a/src/main/java/org/springframework/shell/table/CellMatchers.java b/src/main/java/org/springframework/shell/table/CellMatchers.java deleted file mode 100644 index f9fdfff3..00000000 --- a/src/main/java/org/springframework/shell/table/CellMatchers.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * Contains factory methods for commonly used {@link CellMatcher}s. - * - * @author Eric Bottard - */ -public class CellMatchers { - - /** - * Return a matcher that applies to every cell of the table. - */ - public static CellMatcher table() { - return new CellMatcher() { - public boolean matches(int row, int column, TableModel model) { - return true; - } - }; - } - - /** - * Return a matcher that applies to every cell of some column of the table. - */ - public static CellMatcher column(final int col) { - return new CellMatcher() { - public boolean matches(int row, int column, TableModel model) { - return col == column; - } - }; - } - - /** - * Return a matcher that applies to every cell of some row of the table. - */ - public static CellMatcher row(final int theRow) { - return new CellMatcher() { - public boolean matches(int row, int column, TableModel model) { - return theRow == row; - } - }; - } - - public static CellMatcher ofType(final Class clazz) { - return new CellMatcher() { - @Override - public boolean matches(int row, int column, TableModel model) { - Object value = model.getValue(row, column); - if (value == null) { - return false; - } - else { - return clazz.isAssignableFrom(value.getClass()); - } - } - }; - } -} diff --git a/src/main/java/org/springframework/shell/table/DebugAligner.java b/src/main/java/org/springframework/shell/table/DebugAligner.java deleted file mode 100644 index b1a9bd74..00000000 --- a/src/main/java/org/springframework/shell/table/DebugAligner.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import java.util.Arrays; - -import org.springframework.util.Assert; - -/** - * A decorator Aligner that checks the Aligner invariants contract, useful for debugging. - * - * @author Eric Bottard - */ -public class DebugAligner implements Aligner { - - private final Aligner delegate; - - public DebugAligner(Aligner delegate) { - this.delegate = delegate; - } - - @Override - public String[] align(String[] text, int cellWidth, int cellHeight) { - String[] result = delegate.align(text, cellWidth, cellHeight); - Assert.isTrue(result.length == cellHeight, String.format("%s had the wrong number of lines (%d), expected %d", - Arrays.asList(result), result.length, cellHeight)); - for (String s : result) { - Assert.isTrue(s.length() == cellWidth, String.format("'%s' had wrong length (%d), expected %d", s, s.length(), - cellWidth)); - } - return result; - } -} diff --git a/src/main/java/org/springframework/shell/table/DebugTextWrapper.java b/src/main/java/org/springframework/shell/table/DebugTextWrapper.java deleted file mode 100644 index 1e105172..00000000 --- a/src/main/java/org/springframework/shell/table/DebugTextWrapper.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import org.springframework.util.Assert; - -/** - * A TextWrapper that delegates to another but makes sure that the contract is not violated. - * - * @author Eric Bottard - */ -public class DebugTextWrapper implements TextWrapper { - - private final TextWrapper delegate; - - public DebugTextWrapper(TextWrapper delegate) { - this.delegate = delegate; - } - - @Override - public String[] wrap(String[] original, int columnWidth) { - String[] result = delegate.wrap(original, columnWidth); - for (String s : result) { - Assert.isTrue(s.length() == columnWidth, String.format("'%s' has the wrong length (%d), expected %d", s, s.length(), columnWidth)); - } - return result; - } -} diff --git a/src/main/java/org/springframework/shell/table/DefaultFormatter.java b/src/main/java/org/springframework/shell/table/DefaultFormatter.java deleted file mode 100644 index c11c711b..00000000 --- a/src/main/java/org/springframework/shell/table/DefaultFormatter.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * A very simple formatter that uses {@link Object#toString()} and splits on newlines. - * - * @author Eric Bottard - */ -public class DefaultFormatter implements Formatter { - - public String[] format(Object value) { - return value == null ? new String[] {""} : value.toString().split("\n"); - } - -} diff --git a/src/main/java/org/springframework/shell/table/DelimiterTextWrapper.java b/src/main/java/org/springframework/shell/table/DelimiterTextWrapper.java deleted file mode 100644 index b4a3422b..00000000 --- a/src/main/java/org/springframework/shell/table/DelimiterTextWrapper.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import java.util.ArrayList; -import java.util.List; - -/** - * A Text wrapper that wraps at "word" boundaries. The default delimiter is the space character. - * - * @author Eric Bottard - */ -public class DelimiterTextWrapper implements TextWrapper { - - private final char delimiter; - - public DelimiterTextWrapper() { - this(' '); - } - - public DelimiterTextWrapper(char delimiter) { - this.delimiter = delimiter; - } - - @Override - public String[] wrap(String[] original, int columnWidth) { - List result = new ArrayList(original.length); - for (String line : original) { - while (line.length() > columnWidth) { - int split = line.lastIndexOf(delimiter, columnWidth); - String toAdd = split == -1 ? line.substring(0, columnWidth) : line.substring(0, split); - result.add(String.format("%-" + columnWidth + "s", toAdd)); - line = line.substring(split == -1 ? columnWidth : split + 1); - } - if (columnWidth > 0) { - result.add(String.format("%-" + columnWidth + "s", line)); // right pad if necessary - } - } - return result.toArray(new String[result.size()]); - } -} diff --git a/src/main/java/org/springframework/shell/table/Formatter.java b/src/main/java/org/springframework/shell/table/Formatter.java deleted file mode 100644 index 36f1573a..00000000 --- a/src/main/java/org/springframework/shell/table/Formatter.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * A Formatter is responsible for the initial rendering of a value to lines of text. - * - *

Note that this representation is likely to be altered later in the pipeline, for the - * purpose of text wrapping and aligning. The role of a formatter is merely to give the - * raw text representation (e.g. format numbers).

- * - * @author Eric Bottard - */ -public interface Formatter { - - public String[] format(Object value); -} diff --git a/src/main/java/org/springframework/shell/table/KeyValueHorizontalAligner.java b/src/main/java/org/springframework/shell/table/KeyValueHorizontalAligner.java deleted file mode 100644 index 30fde797..00000000 --- a/src/main/java/org/springframework/shell/table/KeyValueHorizontalAligner.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * A text alignment strategy that aligns text horizontally so that all instances of some special character(s) - * line up perfectly in a column. - * - *

Typically used to render numbers which may or may not have a decimal point, or series of key-value pairs

- * - * @author Eric Bottard - */ -public class KeyValueHorizontalAligner implements Aligner { - - private final String delimiter; - - public KeyValueHorizontalAligner(String delimiter) { - this.delimiter = delimiter; - } - - @Override - public String[] align(String[] text, int cellWidth, int cellHeight) { - - String[] result = new String[cellHeight]; - int alignOffset = 0; - for (String line : text) { - alignOffset = Math.max(alignOffset, line.trim().indexOf(delimiter)); - } - int i = 0; - for (String line : text) { - String trimmed = line.trim(); - int offset = trimmed.indexOf(delimiter); - if (offset >= 0) { - // It is possible that aligning would trigger overflow - // Make sure not to - int offsetToUse = Math.min(alignOffset - offset, cellWidth - trimmed.length()); - result[i++] = pad(offsetToUse, cellWidth - trimmed.length() - offsetToUse, trimmed); - } - else { - result[i++] = pad(0, cellWidth - line.length(), line); - } - - } - return result; - } - - private String pad(int left, int right, String original) { - StringBuilder sb = new StringBuilder(left + original.length() + right); - for (int i = 0; i < left; i++) { - sb.append(' '); - } - sb.append(original); - for (int i = 0; i < right; i++) { - sb.append(' '); - } - return sb.toString(); - } -} diff --git a/src/main/java/org/springframework/shell/table/KeyValueSizeConstraints.java b/src/main/java/org/springframework/shell/table/KeyValueSizeConstraints.java deleted file mode 100644 index 84550f85..00000000 --- a/src/main/java/org/springframework/shell/table/KeyValueSizeConstraints.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * A SizeConstraints implementation that is tailored to rendering a series - * of {@literal key = value} pairs. Computes extents so that equal signs (or any other - * configurable delimiter) line up vertically. - * - * @author Eric Bottard - */ -public class KeyValueSizeConstraints implements SizeConstraints { - - private final String delimiter; - - public KeyValueSizeConstraints(String delimiter) { - this.delimiter = delimiter; - } - - private static String leftTrim(String raw) { - int start = 0; - int length = raw.length(); - while (start < length && raw.charAt(start) == ' ') { - start++; - } - return raw.substring(start); - } - - private static String rightTrim(String raw) { - int end = raw.length(); - while (end > 0 && raw.charAt(end - 1) == ' ') { - end--; - } - return raw.substring(0, end); - } - - @Override - public Extent width(String[] raw, int tableWidth, int nbColumns) { - - // We need to make sure we take care of the case where we have - // k = long-value - // long-key = v - // as the real maximal extent is size(long-key) + size( = ) + size(long-value) - - // The minimal extent in the example above is size(long-value) - - int maxLeft = 0; - int maxRight = 0; - int min = 0; - for (String line : raw) { - String lineToConsider = line.trim(); - int offset = lineToConsider.indexOf(delimiter); - - if (offset != -1) { - // Compute minimal case (line can be split, decide where to put the delimiter) - String minimalLeftPart = lineToConsider.substring(0, offset).trim(); - String minimalRightPart = lineToConsider.substring(offset + delimiter.length()).trim(); - int left = minimalLeftPart.length(); - int right = minimalRightPart.length(); - int case1 = Math.max(left, right + leftTrim(delimiter).length()); - int case2 = Math.max(left + rightTrim(delimiter).length(), right); - int bestMin = Math.min(case1, case2); - min = Math.max(min, bestMin); - - // Compute maximal case (sum of worst case on left and right) - maxLeft = Math.max(maxLeft, offset); - int after = lineToConsider.length() - offset - delimiter.length(); - maxRight = Math.max(maxRight, after); - } - else { - min = Math.max(min, lineToConsider.length()); - } - - } - - return new Extent(min, maxLeft + delimiter.length() + maxRight); - } -} diff --git a/src/main/java/org/springframework/shell/table/KeyValueTextWrapper.java b/src/main/java/org/springframework/shell/table/KeyValueTextWrapper.java deleted file mode 100644 index 18bcf65c..00000000 --- a/src/main/java/org/springframework/shell/table/KeyValueTextWrapper.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import java.util.ArrayList; -import java.util.List; - -/** - * A TextWrapper implementation tailored for key-value rendering (working in concert - * with {@link KeyValueSizeConstraints}, {@link KeyValueHorizontalAligner}), that tries its - * best to vertically align some delimiter character (default '='). - */ -public class KeyValueTextWrapper implements TextWrapper { - - private final String delimiter; - - public KeyValueTextWrapper() { - this("="); - } - - public KeyValueTextWrapper(String delimiter) { - this.delimiter = delimiter; - } - - @Override - public String[] wrap(String[] original, int columnWidth) { - List result = new ArrayList(); - for (String line : original) { - line = line.trim(); - while (line.length() > columnWidth) { - int cut = line.lastIndexOf(delimiter, columnWidth); - if (cut == -1) { - cut = columnWidth; - } - else if (cut + delimiter.length() <= columnWidth) { - cut = cut + delimiter.length(); - } - result.add(rightPad(line.substring(0, cut), columnWidth)); - line = line.substring(cut).trim(); - } - if (line.length() > 0) { - result.add(rightPad(line, columnWidth)); - } - } - return result.toArray(new String[result.size()]); - } - - private String rightPad(String raw, int width) { - StringBuilder result = new StringBuilder(raw); - for (int i = raw.length(); i < width; i++) { - result.append(' '); - } - return result.toString(); - } -} diff --git a/src/main/java/org/springframework/shell/table/MapFormatter.java b/src/main/java/org/springframework/shell/table/MapFormatter.java deleted file mode 100644 index 7ea3b3dc..00000000 --- a/src/main/java/org/springframework/shell/table/MapFormatter.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import java.util.Map; - -/** - * A formatter suited for key-value pairs, that renders each mapping on a new line. - * - * @author Eric Bottard - */ -public class MapFormatter implements Formatter { - - private final String separator; - - public MapFormatter(String separator) { - this.separator = separator; - } - - @Override - public String[] format(Object value) { - Map map = (Map) value; - String[] result = new String[map.size()]; - int i = 0; - for (Map.Entry kv : map.entrySet()) { - result[i++] = kv.getKey() + separator + kv.getValue(); - } - return result; - } -} diff --git a/src/main/java/org/springframework/shell/table/NoWrapSizeConstraints.java b/src/main/java/org/springframework/shell/table/NoWrapSizeConstraints.java deleted file mode 100644 index 8e7a0d0b..00000000 --- a/src/main/java/org/springframework/shell/table/NoWrapSizeConstraints.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * A sizing strategy that will impose the longest line width on cells. - * - * @author Eric Bottard - */ -public class NoWrapSizeConstraints implements SizeConstraints { - - @Override - public Extent width(String[] raw, int tableWidth, int nbColumns) { - int max = 0; - for (String line : raw) { - max = Math.max(max, line.length()); - } - return new Extent(max, max); - } -} diff --git a/src/main/java/org/springframework/shell/table/SimpleHorizontalAligner.java b/src/main/java/org/springframework/shell/table/SimpleHorizontalAligner.java deleted file mode 100644 index bdd6749f..00000000 --- a/src/main/java/org/springframework/shell/table/SimpleHorizontalAligner.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * An horizontal alignment strategy that allows alignment to the left, center or right. - * - * @author Eric Bottard - */ -public enum SimpleHorizontalAligner implements Aligner { - - left, center, right; - - @Override - public String[] align(String[] text, int cellWidth, int cellHeight) { - String[] result = new String[cellHeight]; - for (int i = 0; i < cellHeight; i++) { - String line = (i < text.length && text[i] != null) ? text[i].trim() : ""; - - int paddingToDistribute = cellWidth - line.length(); - - int padLeft; - int padRight; - - switch (this) { - case center: { - int carry = paddingToDistribute % 2; - paddingToDistribute = paddingToDistribute - carry; - padLeft = padRight = paddingToDistribute / 2; - padRight += carry; - break; - } - case right: { - padLeft = paddingToDistribute; - padRight = 0; - break; - } - case left: { - padLeft = 0; - padRight = paddingToDistribute; - break; - } - default: - throw new AssertionError(); - } - StringBuilder sb = new StringBuilder(cellWidth); - for (int j = 0; j < padLeft; j++) { - sb.append(' '); - } - sb.append(line); - for (int j = 0; j < padRight; j++) { - sb.append(' '); - } - - result[i] = sb.toString(); - } - return result; - } - -} diff --git a/src/main/java/org/springframework/shell/table/SimpleVerticalAligner.java b/src/main/java/org/springframework/shell/table/SimpleVerticalAligner.java deleted file mode 100644 index f3e230c5..00000000 --- a/src/main/java/org/springframework/shell/table/SimpleVerticalAligner.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import java.util.Arrays; - -/** - * Alignment strategy that allows simple vertical alignment to top, middle or bottom. - * - * @author Eric Bottard - */ -public enum SimpleVerticalAligner implements Aligner { - - top, middle, bottom; - - @Override - public String[] align(String[] text, int cellWidth, int cellHeight) { - String[] result = new String[cellHeight]; - int blanksBefore = 0; - int blanksAfter = 0; - boolean atLeastOneNonEmptyRow = false; - for (int row = 0; row < text.length; row++) { - if (text[row] == null || text[row].trim().equals("")) { - blanksBefore++; - } - else { - atLeastOneNonEmptyRow = true; - break; - } - } - // In case of full blank, don't count blank rows twice - if (atLeastOneNonEmptyRow) { - for (int row = text.length - 1; row >= 0; row--) { - if (text[row] == null || text[row].trim().equals("")) { - blanksAfter++; - } - else { - break; - } - } - } - String filler = spaces(cellWidth); - - int padBefore; - int padAfter; - int nonBlankLines = text.length - blanksAfter - blanksBefore; - int paddingToDistribute = cellHeight - nonBlankLines; - - switch (this) { - case middle: { - int carry = paddingToDistribute % 2; - paddingToDistribute = paddingToDistribute - carry; - padBefore = padAfter = paddingToDistribute / 2; - padAfter += carry; - break; - } - case bottom: { - padBefore = paddingToDistribute; - padAfter = 0; - break; - } - case top: { - padBefore = 0; - padAfter = paddingToDistribute; - break; - } - default: - throw new AssertionError(); - } - - Arrays.fill(result, 0, padBefore, filler); - System.arraycopy(text, blanksBefore, result, padBefore, nonBlankLines); - Arrays.fill(result, result.length - padAfter, result.length, filler); - - return result; - } - - private String spaces(int width) { - char[] data = new char[width]; - Arrays.fill(data, ' '); - return new String(data); - } - -} diff --git a/src/main/java/org/springframework/shell/table/SizeConstraints.java b/src/main/java/org/springframework/shell/table/SizeConstraints.java deleted file mode 100644 index f81b842b..00000000 --- a/src/main/java/org/springframework/shell/table/SizeConstraints.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import org.springframework.util.Assert; - -/** - * Strategy for computing the dimensions of a table cell. - * - * @author Eric Bottard - */ -public interface SizeConstraints { - - /** - * Return the minimum and maximum width of the cell, given its raw content. - * @param raw the raw String representation of the cell contents (may be reformatted later, eg wrapped) - * @param tableWidth the whole available width for the table - * @param nbColumns the number of columns in the table - */ - Extent width(String[] raw, int tableWidth, int nbColumns); - - /** - * Holds both a minimum and maximum width. - * - * @author Eric Bottard - */ - class Extent { - - public final int min; - - public final int max; - - public Extent(int min, int max) { - Assert.isTrue(min <= max, "min must be less than max"); - Assert.isTrue(0 <= min, "min and max must be positive"); - this.min = min; - this.max = max; - } - } -} diff --git a/src/main/java/org/springframework/shell/table/Table.java b/src/main/java/org/springframework/shell/table/Table.java deleted file mode 100644 index 337f72da..00000000 --- a/src/main/java/org/springframework/shell/table/Table.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import static org.springframework.shell.table.BorderSpecification.NONE; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.shell.TerminalSizeAware; - -/** - * This is the central API for table rendering. A Table object is constructed with a given - * TableModel, which holds raw table contents. Its rendering logic is then altered by applying - * various customizations, in a fashion very similar to what is used e.g. in a spreadsheet - * program:
    - *
  1. {@link #format(CellMatcher, Formatter) formatters} know how to derive character data out of raw data. For - * example, numbers are - * formatted according to a Locale, or Maps are emitted as a series of {@literal key=value} lines
  2. - *
  3. {@link #size(CellMatcher, SizeConstraints) size constraints} are then applied, which decide how - * much column real estate to allocate to cells
  4. - *
  5. {@link #wrap(CellMatcher, TextWrapper) text wrapping policies} are applied once the column sizes - * are known
  6. - *
  7. finally, {@link #align(CellMatcher, Aligner) alignment} strategies actually render - * text as a series of space-padded strings that draw nicely on screen.
  8. - *
- * All those customizations are applied selectively on the Table cells thanks to a {@link CellMatcher}: One can - * decide to right pad column number 3, or to format in a certain way all instances of {@literal java.util.Map}. - * - *

Of course, all of those customizations often work hand in hand, and not all combinations make sense: - * one needs to anticipate the fact that text will be split using the ' ' (space) character to properly - * calculate column sizes.

- * @author Eric Bottard - */ -public class Table implements TerminalSizeAware { - - private final int rows; - - private final int columns; - - private TableModel model; - - private Map formatters = new LinkedHashMap(); - - private Map sizeConstraints = new LinkedHashMap(); - - private Map wrappers = new LinkedHashMap(); - - private Map aligners = new LinkedHashMap(); - - private List borderSpecifications = new ArrayList(); - - /** - * Construct a new Table with the given model and customizers. - * The passed in LinkedHashMap should be in reverse-insertion order (i.e. the first CellMatcher - * found in iteration order will "win"). - * - * @see TableBuilder#build() - */ - /*package*/ Table(TableModel model, - LinkedHashMap formatters, - LinkedHashMap sizeConstraints, - LinkedHashMap wrappers, - LinkedHashMap aligners, - List borderSpecifications) { - this.model = model; - this.formatters = formatters; - this.sizeConstraints = sizeConstraints; - this.wrappers = wrappers; - this.aligners = aligners; - this.borderSpecifications = borderSpecifications; - rows = model.getRowCount(); - columns = model.getColumnCount(); - - } - - public TableModel getModel() { - return model; - } - - public String render(int totalAvailableWidth) { - StringBuilder result = new StringBuilder(); - - int[] cellHeights = new int[rows]; - int[] cellWidths; - int[] minCellWidths = new int[columns]; - int[] maxCellWidths = new int[columns]; - - String[][][] subLines = new String[rows][columns][]; - - Borders borders = new Borders(); - int widthAvailableForContents = totalAvailableWidth - borders.getNumberOfVerticalBorders(); - - // First, compute desired column widths - for (int row = 0; row < rows; row++) { - for (int column = 0; column < columns; column++) { - Object value = model.getValue(row, column); - String[] lines = getFormatter(row, column).format(value); - subLines[row][column] = lines; - - SizeConstraints.Extent extent = getSizeConstraints(row, column).width(lines, widthAvailableForContents, columns); - - minCellWidths[column] = Math.max(minCellWidths[column], extent.min); - maxCellWidths[column] = Math.max(maxCellWidths[column], extent.max); - - } - } - - - cellWidths = computeColumnWidths(widthAvailableForContents, minCellWidths, maxCellWidths); - // Now that widths are known, apply wrapping & render - for (int row = 0; row < rows; row++) { - for (int column = 0; column < columns; column++) { - subLines[row][column] = getWrapper(row, column).wrap(subLines[row][column], cellWidths[column]); - cellHeights[row] = Math.max(cellHeights[row], subLines[row][column].length); - } - for (int column = 0; column < columns; column++) { - for (Map.Entry kv : aligners.entrySet()) { - if (kv.getKey().matches(row, column, model)) { - subLines[row][column] = kv.getValue().align(subLines[row][column], cellWidths[column], cellHeights[row]); - } - } - } - } - - - for (int row = 0; row < rows; row++) { - - // TOP CELL BORDER - int before = result.length(); - for (int column = 0; column < columns; column++) { - borders.paintCorner(row, column, result); - borders.paintHorizontal(row, column, cellWidths[column], result); - } - borders.paintCorner(row, columns, result); - if (result.length() > before) { - result.append('\n'); - } - - for (int subRow = 0; subRow < cellHeights[row]; subRow++) { - for (int column = 0; column < columns; column++) { - // LEFT CELL BORDER - borders.paintVertical(row, column, result); - String[] lines = subLines[row][column]; - result.append(lines[subRow]); - } - // TABLE RIGHT BORDER - borders.paintVertical(row, columns, result); - result.append("\n"); - } - } - - // TABLE BOTTOM BORDER - int before = result.length(); - for (int column = 0; column < columns; column++) { - borders.paintCorner(rows, column, result); - borders.paintHorizontal(rows, column, cellWidths[column], result); - } - - // TABLE BOTTOM RIGHT CORNER - borders.paintCorner(rows, columns, result); - if (result.length() > before) { - result.append('\n'); - } - return result.toString(); - } - - private int[] computeColumnWidths(int availableWidth, int[] minCellWidths, int[] maxCellWidths) { - - int[] cellWidths; - int minTableWidth = 0, maxTableWidth = 0; - for (int column = 0; column < columns; column++) { - minTableWidth += minCellWidths[column]; - maxTableWidth += maxCellWidths[column]; - } - - // Can use max desired width - if (maxTableWidth <= availableWidth) { - cellWidths = maxCellWidths; - } // will overflow - else if (minTableWidth >= availableWidth) { - cellWidths = minCellWidths; - } // Redistribute nicely - else { - int W = availableWidth - minTableWidth; - int D = maxTableWidth - minTableWidth; - cellWidths = new int[columns]; - for (int column = 0; column < columns; column++) { - cellWidths[column] = minCellWidths[column] + W * (maxCellWidths[column] - minCellWidths[column]) / D; - } - } - return cellWidths; - } - - private TextWrapper getWrapper(int row, int column) { - for (Map.Entry kv : wrappers.entrySet()) { - if (kv.getKey().matches(row, column, model)) { - return kv.getValue(); - } - } - throw new AssertionError("Can't be reached thanks to the whole-table default"); - } - - private SizeConstraints getSizeConstraints(int row, int column) { - for (Map.Entry kv : sizeConstraints.entrySet()) { - if (kv.getKey().matches(row, column, model)) { - return kv.getValue(); - } - } - throw new AssertionError("Can't be reached thanks to the whole-table default"); - } - - private Formatter getFormatter(int row, int column) { - for (Map.Entry kv : formatters.entrySet()) { - if (kv.getKey().matches(row, column, model)) { - return kv.getValue(); - } - } - throw new AssertionError("Can't be reached thanks to the whole-table default"); - } - - /** - * An instance of this class knows where to paint border glyphs. - * - *

In all instance arrays, 'row' and 'column' are actually indices in-between - * table rows and columns. Hence, sizes are larger by one.

- * @author Eric Bottard - */ - private class Borders { - - /** - * Glyph to paint a vertical line at row,col. - */ - private char[][] verticals; - - /** - * Glyph to paint a horizontal line at row,col. - */ - private char[][] horizontals; - - /** - * The type of corner, if any, to paint at row,col. - */ - private char[][] corners; - - /** - * True if at least one vertical bar exists in that col. - */ - private boolean[] vFillers; - - /** - * True if at least one horizontal bar exists in that row. - */ - private boolean[] hFillers; - - public Borders() { - verticals = new char[rows][columns + 1]; - horizontals = new char[rows + 1][columns]; - corners = new char[rows + 1][columns + 1]; - vFillers = new boolean[columns + 1]; - hFillers = new boolean[rows + 1]; - init(); - } - - private void init() { - - for (int row = 0; row <= rows; row++) { - for (int column = 0; column <= columns; column++) { - for (BorderSpecification bs : borderSpecifications) { - if (row < rows) { - char verticalThere = bs.verticals(row, column); - if (verticalThere != BorderStyle.NONE) { - this.verticals[row][column] = verticalThere; - vFillers[column] |= true; - } - } - if (column < columns) { - char horizontalThere = bs.horizontals(row, column); - if (horizontalThere != BorderStyle.NONE) { - this.horizontals[row][column] = horizontalThere; - hFillers[row] |= true; - } - } - } - } - } - - // Compute corners when horizontals & verticals intersect - for (int row = 0; row <= rows; row++) { - for (int column = 0; column <= columns; column++) { - char left = (column - 1 >= 0) ? horizontals[row][column - 1] : NONE; - char right = (column < columns) ? horizontals[row][column] : NONE; - char above = (row - 1 >= 0) ? verticals[row - 1][column] : NONE; - char below = (row < rows) ? verticals[row][column] : NONE; - corners[row][column] = BorderStyle.intersection(above, below, left, right); - } - } - } - - private void paintCorner(int row, int column, StringBuilder stringBuilder) { - if (corners[row][column] != NONE) { - stringBuilder.append(corners[row][column]); - } // If there is a border in same row|column, paint filler - else if (vFillers[column] && hFillers[row]) { - stringBuilder.append(' '); - } - } - - private void paintVertical(int row, int column, StringBuilder stringBuilder) { - if (verticals[row][column] != NONE) { - stringBuilder.append(verticals[row][column]); - } - else if (vFillers[column]) { - stringBuilder.append(' '); - } - } - - private void paintHorizontal(int row, int column, int width, StringBuilder stringBuilder) { - if (horizontals[row][column] != NONE) { - for (int i = 0; i < width; i++) { - stringBuilder.append(horizontals[row][column]); - } - } - else if (hFillers[row]) { - for (int i = 0; i < width; i++) { - stringBuilder.append(' '); - } - } - } - - /** - * Return the number of vertical borders, and hence the space consumed by those. - */ - public int getNumberOfVerticalBorders() { - int result = 0; - for (boolean b : vFillers) { - if (b) { - result++; - } - } - return result; - } - } - -} diff --git a/src/main/java/org/springframework/shell/table/TableBuilder.java b/src/main/java/org/springframework/shell/table/TableBuilder.java deleted file mode 100644 index 8c69fcbe..00000000 --- a/src/main/java/org/springframework/shell/table/TableBuilder.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import static org.springframework.shell.table.BorderSpecification.FULL; -import static org.springframework.shell.table.BorderSpecification.INNER; -import static org.springframework.shell.table.BorderSpecification.INNER_VERTICAL; -import static org.springframework.shell.table.BorderSpecification.OUTLINE; -import static org.springframework.shell.table.SimpleHorizontalAligner.left; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.util.Assert; - -/** - * A builder class to incrementally configure a Table. - * @author Eric Bottard - */ -public class TableBuilder { - - private final TableModel model; - - private final Map formatters = new LinkedHashMap(); - - private final Map sizeConstraints = new LinkedHashMap(); - - private final Map wrappers = new LinkedHashMap(); - - private final LinkedHashMap aligners = new LinkedHashMap(); - - private final List borderSpecifications = new ArrayList(); - - private final int rows; - - private final int columns; - - /** - * Construct a table with the given model. The table will use the following - * strategies for all cells, unless overridden:
    - *
  • {@link DefaultFormatter default formatting} using {@literal toString()}
  • - *
  • {@link AutoSizeConstraints sizing strategy} trying to use the maximum space, resorting to splitting lines on - * spaces
  • - *
  • {@link DelimiterTextWrapper wrapping text} on space characters
  • - *
  • {@link SimpleHorizontalAligner left aligning} text.
  • - *
- */ - - public TableBuilder(TableModel model) { - this.model = model; - rows = model.getRowCount(); - columns = model.getColumnCount(); - - formatters.put(CellMatchers.table(), new DefaultFormatter()); - sizeConstraints.put(CellMatchers.table(), new AutoSizeConstraints()); - wrappers.put(CellMatchers.table(), new DelimiterTextWrapper()); - aligners.put(CellMatchers.table(), left); - - } - - private TableBuilder addBorder(int top, int left, int bottom, int right, int match, BorderStyle style) { - Assert.isTrue(top >= 0 && top < rows, "top row must be positive and less than total number of rows"); - Assert.isTrue(left >= 0 && left < columns, "left column must be positive and less than total number of columns"); - Assert.isTrue(bottom > top && bottom <= rows, "bottom row must be greater than top and less than total number of rows"); - Assert.isTrue(right >= left && right <= columns, "right column must be greater than left and less than total number of columns"); - Assert.notNull(style, "style cannot be null"); - borderSpecifications.add(new BorderSpecification(top, left, bottom, right, match, style)); - return this; - } - - public TableModel getModel() { - return model; - } - - public CellMatcherStub on(CellMatcher matcher) { - return new CellMatcherStub(matcher); - } - - public Table build() { - return new Table(model, - reverse(formatters), - reverse(sizeConstraints), - reverse(wrappers), - aligners, - borderSpecifications); - } - - public BorderStub paintBorder(BorderStyle style, int match) { - return new BorderStub(style, match); - } - - // Convenience methods for borders - - /** - * Set a border on the outline of the whole table. - */ - public TableBuilder addOutlineBorder(BorderStyle style) { - this.addBorder(0, 0, model.getRowCount(), model.getColumnCount(), OUTLINE, style); - return this; - } - - /** - * Set a border on the outline of the whole table, as well as around the first row. - */ - public TableBuilder addHeaderBorder(BorderStyle style) { - this.addBorder(0, 0, 1, model.getColumnCount(), OUTLINE, style); - return addOutlineBorder(style); - } - - /** - * Set a border around each and every cell of the table. - */ - public TableBuilder addFullBorder(BorderStyle style) { - this.addBorder(0, 0, model.getRowCount(), model.getColumnCount(), FULL, style); - return this; - } - - /** - * Set a border on the outline of the whole table, around the first row and draw vertical lines - * around each column. - */ - public TableBuilder addHeaderAndVerticalsBorders(BorderStyle style) { - this.addBorder(0, 0, 1, model.getColumnCount(), OUTLINE, style); - this.addBorder(0, 0, model.getRowCount(), model.getColumnCount(), OUTLINE | INNER_VERTICAL, style); - return this; - } - - /** - * Set a border on the inner verticals and horizontals of the table, but not on the outline. - */ - public TableBuilder addInnerBorder(BorderStyle style) { - this.addBorder(0, 0, model.getRowCount(), model.getColumnCount(), INNER, style); - return this; - } - - private LinkedHashMap reverse(Map original) { - LinkedHashMap result = new LinkedHashMap(original.size()); - List> entries = new ArrayList>(original.entrySet()); - for (int i = entries.size() - 1; i >= 0; i--) { - Map.Entry entry = entries.get(i); - result.put(entry.getKey(), entry.getValue()); - } - return result; - } - - public class CellMatcherStub { - - private final CellMatcher cellMatcher; - - private CellMatcherStub(CellMatcher cellMatcher) { - this.cellMatcher = cellMatcher; - } - - public CellMatcherStub addFormatter(Formatter formatter) { - formatters.put(this.cellMatcher, formatter); - return this; - } - - public CellMatcherStub addSizer(SizeConstraints sizer) { - sizeConstraints.put(this.cellMatcher, sizer); - return this; - } - - public CellMatcherStub addWrapper(TextWrapper textWrapper) { - wrappers.put(this.cellMatcher, textWrapper); - return this; - } - - public CellMatcherStub addAligner(Aligner aligner) { - aligners.put(this.cellMatcher, aligner); - return this; - } - - public CellMatcherStub on(CellMatcher other) { - return TableBuilder.this.on(other); - } - - public TableBuilder and() { - return TableBuilder.this; - } - - public Table build() { - return TableBuilder.this.build(); - } - } - - public class BorderStub { - - private final BorderStyle style; - - private final int match; - - private BorderStub(BorderStyle style, int match) { - this.style = style; - this.match = match; - } - - public TopLeft fromRowColumn(int row, int column) { - return new TopLeft(row, column); - } - - public TopLeft fromTopLeft() { - return new TopLeft(0, 0); - } - - public class TopLeft { - private final int row; - - private final int column; - - private TopLeft(int row, int column) { - this.row = row; - this.column = column; - } - - public TableBuilder toRowColumn(int row, int column) { - TableBuilder.this.addBorder(TopLeft.this.row, TopLeft.this.column, row, column, BorderStub.this.match, BorderStub.this.style); - return TableBuilder.this; - } - - public TableBuilder toBottomRight() { - return toRowColumn(model.getRowCount(), model.getColumnCount()); - } - } - } -} diff --git a/src/main/java/org/springframework/shell/table/TableModel.java b/src/main/java/org/springframework/shell/table/TableModel.java deleted file mode 100644 index 355ca8d0..00000000 --- a/src/main/java/org/springframework/shell/table/TableModel.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * Abstracts away the contract a {@link Table} will use to retrieve tabular data. - * - * @author Eric Bottard - */ -public abstract class TableModel { - - /** - * Return the number of rows that can be queried. - * Values between 0 and {@code rowCount-1} inclusive are valid values. - */ - public abstract int getRowCount(); - - /** - * Return the number of columns that can be queried. - * Values between 0 and {@code columnCount-1} inclusive are valid values. - */ - public abstract int getColumnCount(); - - /** - * Return the data value to be displayed at a given row and column, which may be null. - */ - public abstract Object getValue(int row, int column); - - /** - * Return a transposed view of this model, where rows become columns and vice-versa. - */ - public TableModel transpose() { - return new TableModel() { - @Override - public int getRowCount() { - return TableModel.this.getColumnCount(); - } - - @Override - public int getColumnCount() { - return TableModel.this.getRowCount(); - } - - @Override - public Object getValue(int row, int column) { - return TableModel.this.getValue(column, row); - } - }; - } -} diff --git a/src/main/java/org/springframework/shell/table/TableModelBuilder.java b/src/main/java/org/springframework/shell/table/TableModelBuilder.java deleted file mode 100644 index 12c76acc..00000000 --- a/src/main/java/org/springframework/shell/table/TableModelBuilder.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.util.Assert; - -/** - * Helper class to build a TableModel incrementally. - * - * @author Eric Bottard - */ -public class TableModelBuilder { - - public static final int DEFAULT_ROW_CAPACITY = 3; - - private List> rows = new ArrayList>(); - - private int previousRowSize = -1; - - private boolean frozen; - - public TableModelBuilder addRow() { - Assert.isTrue(!frozen, "TableModel has already been built, builder can't be altered anymore"); - int nbRows = rows.size(); - if (previousRowSize != -1) { - int currentRowSize = rows.get(nbRows - 1).size(); - Assert.isTrue(currentRowSize == previousRowSize, - "Can't switch to next row, as the current one does not have as many elements as the previous one"); - } - if (rows.size() > 0) { - previousRowSize = rows.get(0).size(); - } - rows.add(new ArrayList(previousRowSize == -1 ? DEFAULT_ROW_CAPACITY : previousRowSize)); - return this; - } - - public TableModelBuilder addValue(T value) { - Assert.isTrue(!frozen, "TableModel has already been built, builder can't be altered anymore"); - if (previousRowSize != -1 && rows.get(rows.size() - 1).size() == previousRowSize) { - throw new IllegalArgumentException("Can't add another value to current row"); - } - rows.get(rows.size() - 1).add(value); - return this; - } - - public TableModel build() { - frozen = true; - return new TableModel() { - @Override - public int getRowCount() { - return rows.size(); - } - - @Override - public int getColumnCount() { - return rows.isEmpty() ? 0 : rows.get(0).size(); - } - - @Override - public Object getValue(int row, int column) { - return rows.get(row).get(column); - } - }; - - } -} diff --git a/src/main/java/org/springframework/shell/table/Tables.java b/src/main/java/org/springframework/shell/table/Tables.java deleted file mode 100644 index 51e5e1db..00000000 --- a/src/main/java/org/springframework/shell/table/Tables.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import java.util.Map; - -/** - * Utility class used to create and configure typical Tables. - * - * @author Eric Bottard - */ -public class Tables { - - /** - * Install all the necessary formatters, aligners, etc for key-value rendering of Maps. - */ - public static TableBuilder configureKeyValueRendering(TableBuilder builder, String delimiter) { - return builder.on(CellMatchers.ofType(Map.class)) - .addFormatter(new MapFormatter(delimiter)) - .addAligner(new KeyValueHorizontalAligner(delimiter.trim())) - .addSizer(new KeyValueSizeConstraints(delimiter)) - .addWrapper(new KeyValueTextWrapper(delimiter)).and(); - } -} diff --git a/src/main/java/org/springframework/shell/table/TextWrapper.java b/src/main/java/org/springframework/shell/table/TextWrapper.java deleted file mode 100644 index df89ae1f..00000000 --- a/src/main/java/org/springframework/shell/table/TextWrapper.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -/** - * A strategy for applying text wrapping/cropping given a cell width. - */ -public interface TextWrapper { - - /** - * Return a list of lines where each line length MUST be equal to {@code columnWidth} (padding with spaces if - * appropriate). There is no constraint on the number of lines returned however (typically, will be greater than - * the input number if wrapping occurred). - */ - String[] wrap(String[] original, int columnWidth); -} diff --git a/src/main/resources/org/springframework/shell/plugin/support/banner.txt b/src/main/resources/org/springframework/shell/plugin/support/banner.txt deleted file mode 100644 index 9a5df68a..00000000 --- a/src/main/resources/org/springframework/shell/plugin/support/banner.txt +++ /dev/null @@ -1,9 +0,0 @@ - _____ _ _____ _ _ _ -/ ___| (_) / ___| | | | | -\ `--. _ __ _ __ _ _ __ __ _ \ `--.| |__ ___| | | - `--. \ '_ \| '__| | '_ \ / _` | `--. \ '_ \ / _ \ | | -/\__/ / |_) | | | | | | | (_| | /\__/ / | | | __/ | | -\____/| .__/|_| |_|_| |_|\__, | \____/|_| |_|\___|_|_| - | | __/ | - |_| |___/ - diff --git a/src/test/java/org/springframework/shell/BootstrapTest.java b/src/test/java/org/springframework/shell/BootstrapTest.java deleted file mode 100644 index 8d96a634..00000000 --- a/src/test/java/org/springframework/shell/BootstrapTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.springframework.shell; - -import java.io.IOException; -import java.util.logging.Logger; - -import org.junit.Assert; - -import org.junit.Test; -import org.springframework.shell.core.JLineShellComponent; -import org.springframework.shell.support.logging.HandlerUtils; - -public class BootstrapTest { - - @Test - public void test() throws IOException { - try { - Bootstrap bootstrap = new Bootstrap(null); - JLineShellComponent shell = bootstrap.getJLineShellComponent(); - - //This is a brittle assertion - as additiona 'test' commands are added to the suite, this number will increase. - Assert.assertEquals("Number of CommandMarkers is incorrect", 10, shell.getSimpleParser().getCommandMarkers().size()); - Assert.assertEquals("Number of Converters is incorrect", 17, shell.getSimpleParser().getConverters().size()); - } catch (RuntimeException t) { - throw t; - } finally { - HandlerUtils.flushAllHandlers(Logger.getLogger("")); - } - - } - -} diff --git a/src/test/java/org/springframework/shell/commands/AbstractShellIntegrationTest.java b/src/test/java/org/springframework/shell/commands/AbstractShellIntegrationTest.java deleted file mode 100644 index 7cfaccda..00000000 --- a/src/test/java/org/springframework/shell/commands/AbstractShellIntegrationTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013 the original author or authors. - * - * 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.springframework.shell.commands; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.springframework.shell.Bootstrap; -import org.springframework.shell.core.JLineShellComponent; - -/** - * Superclass for performing integration tests of shell commands. - * - * JUnit's BeforeClass and AfterClass annotations are used to start and stop the shell. - * in local mode with the default store configured to use in-memory storage. - * - * @author Mark Pollack - * - */ -public abstract class AbstractShellIntegrationTest { - - private static JLineShellComponent shell; - - @BeforeClass - public static void startUp() throws InterruptedException { - Bootstrap bootstrap = new Bootstrap(); - shell = bootstrap.getJLineShellComponent(); - } - - @AfterClass - public static void shutdown() { - shell.stop(); - } - - public static JLineShellComponent getShell() { - return shell; - } - -} diff --git a/src/test/java/org/springframework/shell/commands/test/OptionsInjectedDummyCommand.java b/src/test/java/org/springframework/shell/commands/test/OptionsInjectedDummyCommand.java deleted file mode 100644 index 828b03eb..00000000 --- a/src/test/java/org/springframework/shell/commands/test/OptionsInjectedDummyCommand.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.springframework.shell.commands.test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.shell.CommandLine; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.stereotype.Component; - -@Component -public class OptionsInjectedDummyCommand implements CommandMarker { - - @Autowired - private CommandLine commandLine; - - @CliCommand("do nothing") - public String simple() { - return "foo"; - } - - public CommandLine getCommandLine() { - return commandLine; - } - -} diff --git a/src/test/java/org/springframework/shell/converters/ArrayConverterTest.java b/src/test/java/org/springframework/shell/converters/ArrayConverterTest.java deleted file mode 100644 index 5dce3587..00000000 --- a/src/test/java/org/springframework/shell/converters/ArrayConverterTest.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.springframework.shell.converters; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.hamcrest.Description; -import org.hamcrest.DiagnosingMatcher; -import org.hamcrest.Matcher; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.shell.core.Completion; -import org.springframework.shell.core.Converter; - -/** - * Tests for ArrayConverter. - * - * @author Eric Bottard - */ -public class ArrayConverterTest { - - private ArrayConverter arrayConverter; - - @Before - public void setUp() throws Exception { - FileConverter fileConverter = new FileConverter() { - - @Override - protected File getWorkingDirectory() { - return new File("."); - } - }; - arrayConverter = new ArrayConverter(); - Set> allConverters = new HashSet>(); - allConverters.add(fileConverter); - allConverters.add(arrayConverter); - allConverters.add(new IntegerConverter()); - arrayConverter.setConverters(allConverters); - } - - @Test - public void testInferredFileSeparator() throws IOException { - - String raw = "src/main" + File.pathSeparator + "src/main/java"; - File main = new File("src/main").getCanonicalFile(); - File src = new File("src/main/java").getCanonicalFile(); - - - assertThat(arrayConverter.supports(File[].class, ""), equalTo(true)); - File[] result = (File[]) arrayConverter.convertFromText(raw, File[].class, ""); - assertThat(result, arrayContaining(main, src)); - - } - - @Test - public void testDefaultDelimiter() { - assertThat(arrayConverter.supports(Integer[].class, ""), equalTo(true)); - Integer[] result = (Integer[]) arrayConverter.convertFromText("1,2,3,4,5", Integer[].class, ""); - assertThat(result, arrayContaining(1, 2, 3, 4, 5)); - } - - @Test - public void testOverriddenDelimiter() { - assertThat(arrayConverter.supports(Integer[].class, "splittingRegex=;"), equalTo(true)); - Integer[] result = (Integer[]) arrayConverter.convertFromText("1;2;3;4;5", Integer[].class, "splittingRegex=;"); - assertThat(result, arrayContaining(1, 2, 3, 4, 5)); - } - - @Test - public void testUnsupportedType() { - assertThat(arrayConverter.supports(Integer.class, ""), equalTo(false)); - assertThat(arrayConverter.supports(Float[].class, ""), equalTo(false)); - } - - @Test - public void testOptOut() { - assertThat(arrayConverter.supports(Integer[].class, "disable-array-converter"), equalTo(false)); - } - - @Test - @SuppressWarnings("unchecked") - public void testCompletions() throws IOException { - String raw = ("src/test/java/" + File.pathSeparator + "src/main/").replace('/', File.separatorChar); - String match1 = ("src/test/java/" + File.pathSeparator + "src/main/java/").replace('/', File.separatorChar); - String match2 = ("src/test/java/" + File.pathSeparator + "src/main/resources/").replace('/', File.separatorChar); - - List completions = new ArrayList(); - arrayConverter.getAllPossibleValues(completions, File[].class, raw, "", null); - assertThat(completions, containsInAnyOrder( - completionWhoseValue(equalTo(match1)), - completionWhoseValue(equalTo(match2)))); - } - - private Matcher completionWhoseValue(final Matcher matcher) { - return new DiagnosingMatcher() { - - @Override - public void describeTo(Description description) { - description.appendText("a completion that ").appendDescriptionOf(matcher); - } - - @Override - protected boolean matches(Object item, Description mismatchDescription) { - Completion completion = (Completion) item; - boolean match = matcher.matches(completion.getValue()); - matcher.describeMismatch(completion.getValue(), mismatchDescription); - return match; - } - }; - } - -} \ No newline at end of file diff --git a/src/test/java/org/springframework/shell/core/CommandLineInjectedTest.java b/src/test/java/org/springframework/shell/core/CommandLineInjectedTest.java deleted file mode 100644 index 62b91bf4..00000000 --- a/src/test/java/org/springframework/shell/core/CommandLineInjectedTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - - -import java.io.IOException; -import java.util.logging.Logger; - -import junit.framework.Assert; - -import org.junit.Test; -import org.springframework.context.ApplicationContext; -import org.springframework.shell.Bootstrap; -import org.springframework.shell.commands.test.OptionsInjectedDummyCommand; -import org.springframework.shell.support.logging.HandlerUtils; - -public class CommandLineInjectedTest { - - @Test - public void commandLineInjected() throws IOException { - try { - Bootstrap bootstrap = new Bootstrap(null); - ApplicationContext ctx = bootstrap.getApplicationContext(); - OptionsInjectedDummyCommand dummyCommand = ctx.getBean(OptionsInjectedDummyCommand.class); - Assert.assertNotNull("commandLine was not injected into a command", dummyCommand.getCommandLine()); - } catch (RuntimeException t) { - throw t; - } finally { - HandlerUtils.flushAllHandlers(Logger.getLogger("")); - } - } -} diff --git a/src/test/java/org/springframework/shell/core/MethodTargetTest.java b/src/test/java/org/springframework/shell/core/MethodTargetTest.java deleted file mode 100644 index 3516b38f..00000000 --- a/src/test/java/org/springframework/shell/core/MethodTargetTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import java.lang.reflect.Method; - -import org.junit.Test; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.MethodTarget; - -/** - * Unit test of {@link MethodTarget} - * - * @author Andrew Swan - * @since 1.2.0 - */ -public class MethodTargetTest { - - // Constants - private static final Object TARGET_1 = new CommandMarker() {}; - private static final Object TARGET_2 = new CommandMarker() {}; - private static final Method METHOD_1 = TARGET_1.getClass().getMethods()[0]; // unmockable - private static final Method METHOD_2 = TARGET_2.getClass().getMethods()[1]; // unmockable - - @Test - public void testInstanceEqualsItself() { - final MethodTarget instance = new MethodTarget(METHOD_1, TARGET_1); - assertEquals(instance, instance); - } - - @Test - public void testInstanceDoesNotEqualNull() { - assertFalse(new MethodTarget(METHOD_1, TARGET_1).equals(null)); - } - - @Test - public void testInstancesWithSameMethodAndTargetAreEqualAndHaveSameHashCode() { - final MethodTarget instance1 = new MethodTarget(METHOD_1, TARGET_1, "the-buff", "the-key"); - final MethodTarget instance2 = new MethodTarget(METHOD_1, TARGET_1); - assertEquals(instance1, instance2); - assertEquals(instance1.hashCode(), instance2.hashCode()); - } - - @Test - public void testInstancesWithDifferentMethodAreNotEqual() { - assertFalse(new MethodTarget(METHOD_1, TARGET_1).equals(new MethodTarget(METHOD_2, TARGET_1))); - } - - @Test - public void testInstancesWithDifferentTargetAreNotEqual() { - assertFalse(new MethodTarget(METHOD_1, TARGET_1).equals(new MethodTarget(METHOD_1, TARGET_2))); - } -} diff --git a/src/test/java/org/springframework/shell/core/SimpleExecutionStrategyTest.java b/src/test/java/org/springframework/shell/core/SimpleExecutionStrategyTest.java deleted file mode 100644 index 9b3c0ce0..00000000 --- a/src/test/java/org/springframework/shell/core/SimpleExecutionStrategyTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.core; - -import java.lang.reflect.Method; - -import org.junit.Test; -import org.springframework.shell.core.ExecutionProcessor; -import org.springframework.shell.core.SimpleExecutionStrategy; -import org.springframework.shell.event.ParseResult; -import org.springframework.util.ReflectionUtils; - -import static org.junit.Assert.*; - -/** - * @author Costin Leau - * @author Oliver Gierke - */ -public class SimpleExecutionStrategyTest { - - public static class Target implements ExecutionProcessor { - Object before = null; - Object after = null; - ParseResult beforeReturn = null; - - public String one() { - return "one"; - } - - public String two() { - return "two"; - } - - public ParseResult beforeInvocation(ParseResult invocationContext) { - before = invocationContext; - return (beforeReturn == null ? invocationContext : beforeReturn); - } - - public void afterReturningInvocation(ParseResult invocationContext, Object result) { - after = invocationContext; - } - - public void afterThrowingInvocation(ParseResult invocationContext, Throwable thrown) { - // - } - } - - static class PackageProtectedTarget { - - void someMethod() {} - } - - private SimpleExecutionStrategy execution = new SimpleExecutionStrategy(); - - @Test - public void testSimpleCommandProcessor() throws Exception { - Target target = new Target(); - Method one = ReflectionUtils.findMethod(target.getClass(), "one"); - ParseResult result = new ParseResult(one, target, null); - - assertEquals("one", execution.execute(result)); - assertSame(result, target.before); - assertSame(result, target.after); - } - - @Test - public void testRedirectCommandProcessor() throws Exception { - Target target = new Target(); - Method one = ReflectionUtils.findMethod(target.getClass(), "one"); - Method two = ReflectionUtils.findMethod(target.getClass(), "two"); - ParseResult given = new ParseResult(one, target, null); - ParseResult redirect = new ParseResult(two, target, null); - target.beforeReturn = redirect; - - assertEquals("two", execution.execute(given)); - assertSame(given, target.before); - assertSame(redirect, target.after); - } - - /** - * @see SHL-189 - */ - @Test - public void invokesMethodsOnPackageProtectedTypes() { - - Method method = ReflectionUtils.findMethod(PackageProtectedTarget.class, "someMethod"); - ParseResult result = new ParseResult(method, new PackageProtectedTarget(), new Object[] {}); - - execution.execute(result); - } -} diff --git a/src/test/java/org/springframework/shell/core/SimpleParserTests.java b/src/test/java/org/springframework/shell/core/SimpleParserTests.java deleted file mode 100644 index a400b701..00000000 --- a/src/test/java/org/springframework/shell/core/SimpleParserTests.java +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Copyright 2013 the original author or authors. - * - * 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.springframework.shell.core; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.assertThat; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Pattern; - -import org.hamcrest.Description; -import org.hamcrest.DiagnosingMatcher; -import org.hamcrest.Matcher; -import org.junit.Assert; -import org.junit.Test; - -import org.springframework.shell.converters.StringConverter; -import org.springframework.shell.core.annotation.CliAvailabilityIndicator; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; -import org.springframework.shell.event.ParseResult; - -/** - * Tests for parsing and completion logic. - * - * @author Eric Bottard - */ -public class SimpleParserTests { - - private SimpleParser parser = new SimpleParser(); - - private int offset; - - private String buffer; - - private ArrayList candidates = new ArrayList(); - - @Test - public void testSHL170_ValueMadeOfSpacesOK() { - parser.add(new MyCommands()); - parser.add(new StringConverter()); - - // A value made of space(s) is ok - ParseResult result = parser.parse("bar --option1 ' '"); - assertThat(result.getMethod().getName(), equalTo("bar")); - assertThat(result.getArguments(), arrayContaining((Object) " ")); - - // Ok too with a literal TAB - result = parser.parse("bar --option1 '\t'"); - assertThat(result.getMethod().getName(), equalTo("bar")); - assertThat(result.getArguments(), arrayContaining((Object)"\t")); - - // Also Ok when Shell itself does the escaping - result = parser.parse("bar --option1 '\\t'"); - assertThat(result.getMethod().getName(), equalTo("bar")); - assertThat(result.getArguments(), arrayContaining((Object)"\t")); - - } - - @Test - public void testSimpleCommandNameCompletion() { - parser.add(new MyCommands()); - - buffer = "f"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("foo "))))); - } - - @Test - public void testSimpleArgumentNameCompletion() { - parser.add(new MyCommands()); - - buffer = "bar --op"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 "))))); - } - - @Test - public void testSimpleArgumentValueCompletion() { - parser.add(new MyCommands()); - parser.add(new StringCompletions(Arrays.asList("abc", "def", "ghi"))); - - buffer = "bar --option1 a"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 abc"))))); - } - - @Test - public void testArgumentValueCompletionWhenQuoted() { - parser.add(new MyCommands()); - parser.add(new StringCompletions(Arrays.asList("abc", "def", "ghi"))); - - buffer = "bar --option1 \"a"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"abc"))))); - } - - @Test - public void testCompletionInMiddleOfBuffer() { - parser.add(new MyCommands()); - - buffer = "bar --optimum"; - offset = parser.completeAdvanced(buffer, "bar --opti".length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 "))))); - - } - - @Test - public void testArgumentValueCompletionWhenAmbiguity() { - parser.add(new MyCommands()); - parser.add(new StringCompletions(Arrays.asList("abc", "def", "abd"))); - - buffer = "bar --option1 a"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(startsWith("bar --option1 ab")))); - } - - @Test - public void testArgumentValueCompletionWhenAmbiguityUsingQuotes() { - parser.add(new MyCommands()); - parser.add(new StringCompletions(Arrays.asList("abc", "def", "abd"))); - - buffer = "bar --option1 \"a"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"abc"))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"abd"))))); - } - - @Test - public void testArgumentValueCompletionUnderstandsEndQuote() { - parser.add(new MyCommands()); - parser.add(new StringCompletions(Arrays.asList("abc", "def", "abd"))); - - buffer = "bar --option1 \"ab\""; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, is(empty())); - } - - @Test - public void testArgumentValueCompletionAlreadyGiven() { - parser.add(new MyCommands()); - parser.add(new StringCompletions(Arrays.asList("abc", "def", "ghi"))); - - buffer = "bar --option1 def"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, is(empty())); - } - - @Test - public void testDashDashIntoOption() { - parser.add(new MyCommands()); - - buffer = "bar --"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 "))))); - } - - @Test - public void testArgumentValueWithEscapedQuotes() { - parser.add(new MyCommands()); - parser.add(new StringCompletions(Arrays.asList("he said \"hello\" to me"))); - - buffer = "bar --option1 \"he said \\\"he"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"he said \\\"hello\\\" to me"))))); - - } - - @Test - public void testNoCompletionsFound() { - parser.add(new MyCommands()); - - buffer = "notthere"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, empty()); - - } - - @Test - public void testCommandAmbiguity() { - parser.add(new MyCommands()); - - buffer = "b"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar "))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("bing "))))); - - } - - @Test - public void testUnfinishedCommandThatHasParams() { - parser.add(new MyCommands()); - - buffer = "ba"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar "))))); - - } - - @Test - public void testDontMisinterpretDashDashInArgumentValue() { - parser.add(new MyCommands()); - - buffer = "bar --option1 \"I end with --"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, empty()); - - } - - @Test - public void testWithDefaultKey() { - parser.add(new MyCommands()); - - buffer = "testDefaultKey thevalue --optio"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("testDefaultKey thevalue --option2 "))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("testDefaultKey thevalue --option3 "))))); - assertThat(candidates, not(hasItem(completionThat(containsString("option1"))))); - - // Let's do it again with default key in the middle - candidates.clear(); - buffer = "testDefaultKey --option3 foo thevalue --optio"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("testDefaultKey --option3 foo thevalue --option2 "))))); - assertThat(candidates, not(hasItem(completionThat(endsWith("option3 "))))); - - } - - @Test - public void testStopAtFirstWhenMandatory() { - parser.add(new MyCommands()); - - buffer = "testMandatory --"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("testMandatory --option1 "))))); - assertThat(candidates, not(hasItem(completionThat(is(equalTo("testMandatory --option2 ")))))); - assertThat(candidates, not(hasItem(completionThat(is(equalTo("testMandatory --option3 ")))))); - - } - - @Test - public void testDontStopAtFirstWhenNotMandatory() { - parser.add(new MyCommands()); - - buffer = "testNotMandatory --"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("testNotMandatory --option1 "))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("testNotMandatory --option2 "))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("testNotMandatory --option3 "))))); - - } - - @Test - public void testAtEndOfKeyOption() { - parser.add(new MyCommands()); - parser.add(new StringCompletions(Arrays.asList("abd", "def"))); - - buffer = "fileMore"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("fileMore --option "))))); - - // Do it again with a trailing space - buffer = "fileMore "; - candidates.clear(); - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("fileMore --option "))))); - - } - - @Test - public void testAtEndOfKeyOptionWithEvenLongerKeyOption() { - parser.add(new MyCommands()); - parser.add(new StringCompletions(Arrays.asList("abd", "def"))); - - buffer = "file"; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("file "))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("fileMore "))))); - - // Do it again with a trailing space - buffer = "file "; - candidates.clear(); - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("file --option "))))); - assertThat(candidates, not(hasItem(completionThat(startsWith("fileMore"))))); - } - - @Test - public void testPrefixMatching() { - assertThat(SimpleParser.isMatch("hello", "hello", true), is(equalTo(""))); - assertThat(SimpleParser.isMatch("hello there", "hello", true), is(equalTo("there"))); - assertThat(SimpleParser.isMatch("hello there", "hello there", true), is(equalTo(""))); - assertThat(SimpleParser.isMatch("hell", "hello", true), is(equalTo(""))); - - assertThat(SimpleParser.isMatch("hello", "hello there", true), is(nullValue())); - assertThat(SimpleParser.isMatch("hello", "hello there", false), is(equalTo(""))); - - assertThat(SimpleParser.isMatch("hi", "hello", true), is(nullValue())); - - assertThat(SimpleParser.isMatch("hello", "hellothere", false), is(equalTo(""))); - assertThat(SimpleParser.isMatch("hello", "hellothere", true), is(equalTo(""))); - // TODO - // assertThat(SimpleParser.isMatch("hello ", "hellothere", true), is(nullValue())); - } - - @Test - public void testValueCompletionsThatCanContinue() { - - parser.add(new MyCommands()); - parser.add(new StringCompletions(Arrays.asList("abd", "def"), false)); - - // With space as delimiter - buffer = "bar --option1 "; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 abd"))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 def"))))); - - // With quotes as delimiter - buffer = "bar --option1 \""; - candidates.clear(); - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"abd"))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"def"))))); - } - - @Test - public void testValueCompletionsThatCannotContinue() { - - parser.add(new MyCommands()); - parser.add(new StringCompletions(Arrays.asList("abd", "def"), true)); - - // With space as delimiter - buffer = "bar --option1 "; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 abd "))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 def "))))); - - // With quotes as delimiter - buffer = "bar --option1 \""; - candidates.clear(); - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"abd\" "))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"def\" "))))); - } - - @Test - public void testSuccessiveInvocationsOfCompletion() { - - parser.add(new MyCommands()); - parser.add(new ExpertCompletions()); - - buffer = "bar --option1 "; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 one "))))); - assertThat(candidates, not(hasItem(completionThat(is(equalTo("bar --option1 two ")))))); - assertThat(candidates, not(hasItem(completionThat(is(equalTo("bar --option1 three ")))))); - - candidates.clear(); - // Simulate twice - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 one "))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 two "))))); - assertThat(candidates, not(hasItem(completionThat(is(equalTo("bar --option1 three ")))))); - - candidates.clear(); - // Simulate three times - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 one "))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 two "))))); - assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 three "))))); - - // And now for something completely different - buffer = "testMandatory --option2 "; - candidates.clear(); - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, hasItem(completionThat(is(equalTo("testMandatory --option2 one "))))); - assertThat(candidates, not(hasItem(completionThat(is(equalTo("testMandatory --option2 two ")))))); - assertThat(candidates, not(hasItem(completionThat(is(equalTo("testMandatory --option2 three ")))))); - - } - - /** - * @see https://jira.spring.io/browse/SHL-113 - */ - @Test - public void testFalseAmbiguity() { - parser.add(new SamePrefixCommands()); - ParseResult result = parser.parse("foo"); - assertThat(result.getMethod().getName(), equalTo("foo")); - } - - @Test - public void testRealAmbiguity() { - parser.add(new SamePrefixCommands()); - ParseResult result = parser.parse("fo"); - assertThat(result, nullValue(ParseResult.class)); - } - - @Test - public void testCommandPrefixCollisionFalseAmbiguity() { - parser.add(new SamePrefixCommands()); - buffer = "foo "; - offset = parser.completeAdvanced(buffer, buffer.length(), candidates); - - assertThat(candidates, not(hasItem(completionThat(startsWith("fooBar "))))); - } - - @Test - public void testMixedCaseOptions_SHL_98() { - parser.add(new MixedCaseOptions()); - parser.add(new StringConverter()); - ParseResult result = parser.parse("foo --upPer bar"); - assertThat(result.getMethod().getName(), equalTo("foo")); - - result = parser.parse("foo --upper fizz"); - assertThat(result, nullValue()); - } - - @Test - public void testAvailabilityIndicator() { - MyCommands commands = new MyCommands(); - parser.add(commands); - ParseResult result = parser.parse("foo"); - assertThat(result, notNullValue()); - - commands.fooIsAvailable = false; - result = parser.parse("foo"); - assertThat(result, nullValue()); - - } - - /** - * Return a matcher that asserts that a completion, when added to {@link #buffer} at the given {@link #offset}, - * indeed matches the provided matcher. - */ - private Matcher completionThat(final Matcher matcher) { - return new DiagnosingMatcher() { - - @Override - public void describeTo(Description description) { - description.appendText("a completion that ").appendDescriptionOf(matcher); - } - - @Override - protected boolean matches(Object item, Description mismatchDescription) { - Completion completion = (Completion) item; - StringBuilder sb = new StringBuilder(buffer); - sb.setLength(offset); - sb.append(completion.getValue()); - boolean match = matcher.matches(sb.toString()); - mismatchDescription.appendText("result was ") - .appendValue(sb.insert(offset, '[').append(']').toString()); - return match; - } - }; - } - - public static class MyCommands implements CommandMarker { - - boolean fooIsAvailable = true; - - @CliAvailabilityIndicator("foo") - /*package private. see gh-122*/boolean isFooAvailable() { - System.out.println("Returning " + fooIsAvailable); - return fooIsAvailable; - } - - @CliCommand("foo") - public void foo() { - - } - - @CliCommand("bar") - public void bar(@CliOption(key = "option1") - String option1) { - - } - - @CliCommand("bing") - public void bang() { - - } - - @CliCommand("testMandatory") - public void testMandatory(@CliOption(key = "option1", mandatory = true) - String option1, @CliOption(key = "option2", mandatory = true) - String option2, @CliOption(key = "option3") - String option3) { - - } - - @CliCommand("testNotMandatory") - public void testNotMandatory(@CliOption(key = "option1") - String option1, @CliOption(key = "option2") - String option2, @CliOption(key = "option3") - String option3) { - - } - - @CliCommand("testDefaultKey") - public void testDefaultKey(@CliOption(key = "") - String option1, @CliOption(key = "option2") - String option2, @CliOption(key = "option3") - String option3) { - - } - - @CliCommand("file") - public void file(@CliOption(key = "option", mandatory = true) - String option) { - - } - - @CliCommand("fileMore") - public void fileMore(@CliOption(key = "option", mandatory = true) - String option) { - - } - } - - public static class SamePrefixCommands implements CommandMarker { - @CliCommand(value = "foo") - public String foo(@CliOption(key = "") - String arg) { - return "foo " + arg; - } - - @CliCommand(value = "fooBar") - public String fooBar(@CliOption(key = "") - String arg) { - return "fooBar " + arg; - } - } - - public static class MixedCaseOptions implements CommandMarker { - @CliCommand(value = "foo") - public String foo(@CliOption(key = "upPer") - String arg) { - return "foo " + arg; - } - - - } - - - - public static class StringCompletions implements Converter { - - private final List completions; - - private final boolean canContinue; - - public StringCompletions(List completions) { - this(completions, false); - } - - public StringCompletions(List completions, boolean canContinue) { - this.completions = completions; - this.canContinue = canContinue; - } - - @Override - public boolean supports(Class type, String optionContext) { - return type == String.class; - } - - @Override - public String convertFromText(String value, Class targetType, String optionContext) { - return value; - } - - @Override - public boolean getAllPossibleValues(List completions, Class targetType, String existingData, - String optionContext, MethodTarget target) { - for (String s : this.completions) { - completions.add(new Completion(s)); - } - return canContinue; - } - - } - - public static class ExpertCompletions implements Converter { - - private static final Pattern NUMBER_OF_COMPLETIONS_CAPTURE = Pattern.compile(".*completion-count-(\\d+).*"); - - private static final String[] results = new String[] { "one", "two", "three" }; - - @Override - public boolean supports(Class type, String optionContext) { - return true; - } - - @Override - public String convertFromText(String value, Class targetType, String optionContext) { - return value; - } - - @Override - public boolean getAllPossibleValues(List completions, Class targetType, String existingData, - String optionContext, MethodTarget target) { - java.util.regex.Matcher m = NUMBER_OF_COMPLETIONS_CAPTURE.matcher(optionContext); - Assert.assertTrue(m.matches()); - int invocations = Integer.parseInt(m.group(1)); - for (int i = 0; i < invocations; i++) { - completions.add(new Completion(results[i])); - } - return true; - } - - } - -} diff --git a/src/test/java/org/springframework/shell/core/TokenizerTests.java b/src/test/java/org/springframework/shell/core/TokenizerTests.java deleted file mode 100644 index 7c493138..00000000 --- a/src/test/java/org/springframework/shell/core/TokenizerTests.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2013 the original author or authors. - * - * 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.springframework.shell.core; - -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasSize; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Test; - -/** - * Tests for Tokenizer. - * - * @author Eric Bottard - */ -public class TokenizerTests { - - @Test - public void testEmpty() { - Map result = tokenize(""); - assertEquals(emptyMap(), result); - } - - @Test - public void testBlank() { - Map result = tokenize(" "); - assertEquals(emptyMap(), result); - } - - @Test - public void testDefaultKey() { - Map result = tokenize("foo"); - assertEquals(singletonMap("", "foo"), result); - } - - @Test - public void testOneOption() { - Map result = tokenize("--foo bar"); - assertEquals(singletonMap("foo", "bar"), result); - } - - @Test - public void testTwoOptions() { - Map result = tokenize("--foo bar --fizz buzz"); - Map expected = new HashMap(); - expected.put("foo", "bar"); - expected.put("fizz", "buzz"); - assertEquals(expected, result); - } - - @Test - public void testTwoOptionsOneWithDefault() { - Map result = tokenize("bar --fizz buzz"); - Map expected = new HashMap(); - expected.put("", "bar"); - expected.put("fizz", "buzz"); - assertEquals(expected, result); - } - - @Test(expected = TokenizingException.class) - public void testTwoOptionsSameKey() { - tokenize("--foo bar --foo buzz"); - } - - @Test - public void testAllowTwoOptionsSameEmptyKeyIfNextToEachOther() { - Map result = tokenize("bar buzz"); - assertThat(result.keySet(), hasSize(1)); - assertThat(result.get(""), equalTo("bar buzz")); - - result = tokenize("--foo wizz bar buzz --woot cool"); - assertThat(result.keySet(), hasSize(3)); - assertThat(result.get(""), equalTo("bar buzz")); - assertThat(result.get("foo"), equalTo("wizz")); - assertThat(result.get("woot"), equalTo("cool")); - } - - @Test(expected = TokenizingException.class) - public void testDisallowTwoOptionsSameEmptyKeyIfNotNextToEachOther() { - tokenize("bar --foo wizz buzz"); - } - - @Test - public void testValueQuotation() { - Map result = tokenize("--foo \"bar fizz\""); - assertEquals(singletonMap("foo", "bar fizz"), result); - } - - @Test - public void testExtraSpaces() { - Map result = tokenize(" --foo \"bar fizz\" --bozz bizzz \"the default\""); - Map expected = new HashMap(); - expected.put("", "the default"); - expected.put("foo", "bar fizz"); - expected.put("bozz", "bizzz"); - assertEquals(expected, result); - } - - @Test(expected = TokenizingException.class) - public void testValueQuotationUnbalanced() { - Map result = tokenize("--foo \"bar fizz"); - assertEquals(singletonMap("foo", "bar fizz"), result); - } - - @Test - public void testValueQuotationEscaped() { - Map result = tokenize("--foo \"bar \\\"fizz\""); - assertEquals(singletonMap("foo", "bar \"fizz"), result); - } - - @Test - public void testAllowKeyOnlyIfAtTheEnd() { - Map result = tokenize("--foo bar fizz --bozz "); - Map expected = new HashMap(); - expected.put("", "fizz"); - expected.put("foo", "bar"); - expected.put("bozz", ""); - assertEquals(expected, result); - - } - - @Test - public void testValueQuotationAllowUnfinished() { - Tokenizer tokenizer = new Tokenizer("--foo \"bar bazz\" --bizz \"unfinished bizness ", true); - Map result = tokenizer.getTokens(); - Map expected = new HashMap(); - expected.put("foo", "bar bazz"); - expected.put("bizz", "unfinished bizness "); - assertEquals(expected, result); - assertTrue(tokenizer.openingQuotesHaveNotBeenClosed()); - } - - @Test - public void testValueQuotationAllowUnfinishedEvenWithEmptyContent() { - Tokenizer tokenizer = new Tokenizer("--foo \"bar bazz\" --bizz \"", true); - Map result = tokenizer.getTokens(); - Map expected = new HashMap(); - expected.put("foo", "bar bazz"); - expected.put("bizz", ""); - assertEquals(expected, result); - assertTrue(tokenizer.openingQuotesHaveNotBeenClosed()); - } - - @Test - public void testPendingDashDash() { - Map result = tokenize("--foo bar --"); - assertEquals(singletonMap("foo", "bar"), result); - } - - @Test - public void testKeyWithDefaultValueAtEnd() { - Map result = tokenize("--foo bar --recursive"); - Map expected = new HashMap(); - expected.put("foo", "bar"); - expected.put("recursive", ""); - assertEquals(expected, result); - } - - @Test - public void testKeyWithDefaultValueNotAtEnd() { - Map result = tokenize("--foo bar --recursive --wizz blow"); - Map expected = new HashMap(); - expected.put("foo", "bar"); - expected.put("recursive", ""); - expected.put("wizz", "blow"); - assertEquals(expected, result); - } - - @Test - public void testValueThatStartsWithDashDashStillSupportedIfQuoted() { - Map result = tokenize("--foo bar --recursive \"--wizz\" blow"); - Map expected = new HashMap(); - expected.put("foo", "bar"); - expected.put("recursive", "--wizz"); - expected.put("", "blow"); - assertEquals(expected, result); - - } - - @Test - public void testEscapeSequences() { - Map result = tokenize("--foo \\t\\n\\r\\f"); - assertEquals(Collections.singletonMap("foo", "\t\n\r\f"), result); - - // Unicode and space-escape - result = tokenize("--foo \\u65e5\\ \\u672c"); - assertEquals(Collections.singletonMap("foo", "\u65e5 \u672c"), result); - - // backslash escape - result = tokenize("--foo \\\\u\\g"); - assertEquals(Collections.singletonMap("foo", "\\u\\g"), result); - } - - public void testSingleAndDoubleQuotingBehavior() { - Map result = tokenize("--foo 'i have a double \" in me'"); - assertEquals(Collections.singletonMap("foo", "i have a double \" in me"), result); - - result = tokenize("--foo \"i have a double \\\" in me\""); - assertEquals(Collections.singletonMap("foo", "i have a double \" in me"), result); - - result = tokenize("--foo \"i have a single ' in me\""); - assertEquals(Collections.singletonMap("foo", "i have a single ' in me"), result); - - result = tokenize("--foo 'i have a single \\' in me'"); - assertEquals(Collections.singletonMap("foo", "i have a single ' in me"), result); - - } - - private Map tokenize(String what) { - return new Tokenizer(what).getTokens(); - } -} diff --git a/src/test/java/org/springframework/shell/plugin/support/DefaultBannerProviderTest.java b/src/test/java/org/springframework/shell/plugin/support/DefaultBannerProviderTest.java deleted file mode 100644 index bfd3dba6..00000000 --- a/src/test/java/org/springframework/shell/plugin/support/DefaultBannerProviderTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.plugin.support; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * @author Jarred Li - * - */ -public class DefaultBannerProviderTest { - - private DefaultBannerProvider banner = new DefaultBannerProvider(); - - /** - * Test method for {@link org.springframework.shell.plugin.support.DefaultBannerProvider#getBanner()}. - */ - @Test - public void testGetBanner() { - String bnr = banner.getBanner(); - System.out.println(bnr); - assertNotNull(bnr); - } - -} diff --git a/src/test/java/org/springframework/shell/plugin/support/DefaultHistoryFileProviderTest.java b/src/test/java/org/springframework/shell/plugin/support/DefaultHistoryFileProviderTest.java deleted file mode 100644 index fe8a9778..00000000 --- a/src/test/java/org/springframework/shell/plugin/support/DefaultHistoryFileProviderTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.plugin.support; - -import org.junit.Test; -import org.springframework.shell.plugin.HistoryFileNameProvider; - -import static org.junit.Assert.*; - -/** - * @author Jarred Li - * - */ -public class DefaultHistoryFileProviderTest { - - private HistoryFileNameProvider historyFile = new DefaultHistoryFileNameProvider(); - - /** - * Test method for {@link org.springframework.shell.plugin.support.DefaultHistoryFileNameProvider#getHistoryFileName()}. - */ - @Test - public void testGetHistoryFileName() { - assertNotNull(historyFile.getHistoryFileName()); - assertEquals("spring-shell.log", historyFile.getHistoryFileName()); - } - -} diff --git a/src/test/java/org/springframework/shell/plugin/support/DefaultPromptProviderTest.java b/src/test/java/org/springframework/shell/plugin/support/DefaultPromptProviderTest.java deleted file mode 100644 index b1c70e40..00000000 --- a/src/test/java/org/springframework/shell/plugin/support/DefaultPromptProviderTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.plugin.support; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.shell.plugin.PromptProvider; - -import static org.junit.Assert.*; - -/** - * @author Jarred Li - * - */ -public class DefaultPromptProviderTest { - - private static PromptProvider prompt; - - /** - * @throws java.lang.Exception - */ - @BeforeClass - public static void setUpBeforeClass() throws Exception { - prompt = new DefaultPromptProvider(); - } - - /** - * @throws java.lang.Exception - */ - @AfterClass - public static void tearDownAfterClass() throws Exception { - prompt = null; - } - - - /** - * Test method for {@link org.springframework.shell.plugin.support.DefaultPromptProvider#getPrompt()}. - */ - @Test - public void testGetPromptText() { - assertTrue(prompt.getPrompt().startsWith("spring-shell>")); - } -} diff --git a/src/test/java/org/springframework/shell/support/table/TableRendererTest.java b/src/test/java/org/springframework/shell/support/table/TableRendererTest.java deleted file mode 100644 index 87754914..00000000 --- a/src/test/java/org/springframework/shell/support/table/TableRendererTest.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2009-2013 the original author or authors. - * - * 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.springframework.shell.support.table; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Map; -import java.util.TreeMap; - -import org.junit.Test; - -import org.springframework.util.FileCopyUtils; - -/** - * @author Gunnar Hillert - * - */ -public class TableRendererTest { - - @Test - public void testRenderTextTable() { - - final Table table = new Table(); - table.addHeader(1, new TableHeader("Tap Name")) - .addHeader(2, new TableHeader("Stream Name")) - .addHeader(3, new TableHeader("Tap Definition")); - - for (int i = 1; i <= 3; i++) { - final TableRow row = new TableRow(); - row.addValue(1, "tap" + i) - .addValue(2, "ticktock") - .addValue(3, "tap@ticktock|log"); - table.getRows().add(row); - } - - String expectedTableAsString = null; - - final InputStream inputStream = getClass() - .getClassLoader() - .getResourceAsStream("testRenderTextTable-expected-output.txt"); - - assertNotNull("The inputstream is null.", inputStream); - - try { - expectedTableAsString = FileCopyUtils.copyToString(new InputStreamReader(inputStream)); - } - catch (IOException e) { - e.printStackTrace(); - fail(); - } - - final String tableRenderedAsString = TableRenderer.renderTextTable(table); - - assertEquals(expectedTableAsString.replaceAll("\r", ""), tableRenderedAsString); - } - - @Test - public void testRenderTextTableWithSingleColumn() { - - final Table table = new Table(); - table.addHeader(1, new TableHeader("Gauge name")); - - final TableRow row = new TableRow(); - row.addValue(1, "simplegauge"); - table.getRows().add(row); - - String expectedTableAsString = null; - - final InputStream inputStream = getClass() - .getClassLoader() - .getResourceAsStream("testRenderTextTable-single-column-expected-output.txt"); - - assertNotNull("The inputstream is null.", inputStream); - - try { - expectedTableAsString = FileCopyUtils.copyToString(new InputStreamReader(inputStream)); - } - catch (IOException e) { - e.printStackTrace(); - fail(); - } - - final String tableRenderedAsString = TableRenderer.renderTextTable(table); - assertEquals(expectedTableAsString.replaceAll("\r", ""), tableRenderedAsString); - } - - @Test - public void testRenderTextTableWithSingleColumnAndWidthOf4() { - - final Table table = new Table(); - final TableHeader tableHeader = new TableHeader("Gauge name"); - tableHeader.setMaxWidth(4); - table.addHeader(1, tableHeader); - - final TableRow row = new TableRow(); - row.addValue(1, "simplegauge"); - table.getRows().add(row); - - String expectedTableAsString = null; - - final InputStream inputStream = getClass() - .getClassLoader() - .getResourceAsStream("testRenderTextTable-single-column-width4-expected-output.txt"); - - assertNotNull("The inputstream is null.", inputStream); - - try { - expectedTableAsString = FileCopyUtils.copyToString(new InputStreamReader(inputStream)); - } - catch (IOException e) { - e.printStackTrace(); - fail(); - } - - final String tableRenderedAsString = TableRenderer.renderTextTable(table); - assertEquals(expectedTableAsString.replaceAll("\r", ""), tableRenderedAsString); - } - - @Test - public void testRenderParameterInfoDataAsTableWithMaxWidth() { - - final Map values = new TreeMap(); - - values.put("Key1", "Lorem ipsum dolor sit posuere."); - values.put("My super key 2", "Lorem ipsum"); - - String expectedTableAsString = null; - - final InputStream inputStream = getClass() - .getClassLoader() - .getResourceAsStream("testRenderParameterInfoDataAsTableWithMaxWidth.txt"); - - assertNotNull("The inputstream is null.", inputStream); - - try { - expectedTableAsString = FileCopyUtils.copyToString(new InputStreamReader(inputStream)); - } - catch (IOException e) { - e.printStackTrace(); - fail(); - } - - final String tableRenderedAsString = TableRenderer.renderParameterInfoDataAsTable(values, false, 20); - assertEquals(expectedTableAsString.replaceAll("\r", ""), tableRenderedAsString); - } - - @Test - public void testRenderTableWithRowShorthand() { - - final Table table = new Table(); - table.addHeader(1, new TableHeader("Property")) - .addHeader(2, new TableHeader("Value")); - - table.addRow("Job Execution ID", String.valueOf(1)) - .addRow("Job Name", "My Job Name") - .addRow("Start Time", "12:30") - .addRow("Step Execution Count", String.valueOf(12)) - .addRow("Status", "COMPLETED"); - - assertNotNull(table.toString()); - - final InputStream inputStream = getClass() - .getClassLoader() - .getResourceAsStream("testRenderTableWithRowShorthand-expected-output.txt"); - - assertNotNull("The inputstream is null.", inputStream); - - String expectedTableAsString = null; - - try { - expectedTableAsString = FileCopyUtils.copyToString(new InputStreamReader(inputStream)); - } - catch (IOException e) { - e.printStackTrace(); - fail(); - } - assertEquals(expectedTableAsString.replaceAll("\r", ""), table.toString()); - } -} diff --git a/src/test/java/org/springframework/shell/support/util/AnsiEscapeCodeTest.java b/src/test/java/org/springframework/shell/support/util/AnsiEscapeCodeTest.java deleted file mode 100644 index d092dbb7..00000000 --- a/src/test/java/org/springframework/shell/support/util/AnsiEscapeCodeTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import java.util.HashSet; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.shell.support.util.AnsiEscapeCode; - -/** - * Unit test for the {@link AnsiEscapeCode} enum. - * - * @author Andrew Swan - * @since 1.2.0 - */ -public class AnsiEscapeCodeTest { - - @Before - public void init() { - System.setProperty("roo.console.ansi", Boolean.TRUE.toString()); - } - - @Test - public void testCodesAreUnique() { - // Set up - final Set codes = new HashSet(); - - // Invoke - for (final AnsiEscapeCode escapeCode : AnsiEscapeCode.values()) { - codes.add(escapeCode.code); - } - - // Check - assertEquals(AnsiEscapeCode.values().length, codes.size()); - } - - @Test - public void testDecorateNullText() { - assertNull(AnsiEscapeCode.decorate(null, AnsiEscapeCode.values()[0])); - } - - @Test - public void testDecorateEmptyText() { - assertEquals("", AnsiEscapeCode.decorate("", AnsiEscapeCode.values()[0])); - } - - @Test - public void testDecorateWhitespace() { - final AnsiEscapeCode effect = AnsiEscapeCode.values()[0]; // Arbitrary - assertEquals(effect.code + " " + AnsiEscapeCode.OFF.code, AnsiEscapeCode.decorate(" ", effect)); - } -} diff --git a/src/test/java/org/springframework/shell/support/util/FileUtilsTest.java b/src/test/java/org/springframework/shell/support/util/FileUtilsTest.java deleted file mode 100644 index 5847af53..00000000 --- a/src/test/java/org/springframework/shell/support/util/FileUtilsTest.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import org.junit.Test; -import org.springframework.shell.support.util.loader.Loader; -import org.springframework.util.FileCopyUtils; - -/** - * Unit test of {@link FileUtils} - * - * @author Andrew Swan - * @since 1.2.0 - */ -public class FileUtilsTest { - - private static final String MISSING_FILE = "no-such-file.txt"; - private static final String TEST_FILE = "sub" + File.separator + "file-utils-test.txt"; - - @Test(expected = NullPointerException.class) - public void testGetSystemDependentPathFromNullArray() { - FileUtils.getSystemDependentPath((String[]) null); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetSystemDependentPathFromNoElements() { - FileUtils.getSystemDependentPath(); - } - - @Test - public void testGetSystemDependentPathFromOneElement() { - assertEquals("foo", FileUtils.getSystemDependentPath("foo")); - } - - @Test - public void testGetSystemDependentPathFromMultipleElements() { - final String expectedPath = "foo" + File.separator + "bar"; - assertEquals(expectedPath, FileUtils.getSystemDependentPath("foo", "bar")); - } - - @Test - public void testGetFileSeparatorAsRegex() throws Exception { - // Set up - final String regex = FileUtils.getFileSeparatorAsRegex(); - final String currentDirectory = new File(FileUtils.CURRENT_DIRECTORY).getCanonicalPath(); - - // Invoke - final String[] pathElements = currentDirectory.split(regex); - - // Check - assertTrue(pathElements.length > 0); - } - - @Test - public void testRemoveTrailingSeparatorFromNullPath() { - assertNull(FileUtils.removeTrailingSeparator(null)); - } - - @Test - public void testRemoveTrailingSeparatorFromEmptyPath() { - assertEquals("", FileUtils.removeTrailingSeparator("")); - } - - @Test - public void testRemoveTrailingSeparatorFromPathWithLeadingSeparator() { - final String path = File.separator + "foo"; - assertEquals(path, FileUtils.removeTrailingSeparator(path)); - } - - @Test - public void testRemoveTrailingSeparatorFromPathWithMultipleTrailingSeparators() { - final String path = "foo" + File.separator + File.separator + File.separator; - assertEquals("foo", FileUtils.removeTrailingSeparator(path)); - } - - @Test(expected = IllegalArgumentException.class) - public void testEnsureTrailingSeparatorForNullPath() { - FileUtils.ensureTrailingSeparator(null); - } - - @Test - public void testEnsureTrailingSeparatorForEmptyPath() { - assertEquals(File.separator, FileUtils.ensureTrailingSeparator("")); - } - - @Test - public void testEnsureTrailingSeparatorForPathWithNoTrailingSeparator() { - final String path = "foo"; - assertEquals(path + File.separator, FileUtils.ensureTrailingSeparator(path)); - } - - @Test - public void testEnsureTrailingSeparatorForPathWithOneTrailingSeparator() { - final String path = "foo" + File.separator; - assertEquals(path, FileUtils.ensureTrailingSeparator(path)); - } - - @Test - public void testEnsureTrailingSeparatorFromPathWithMultipleTrailingSeparators() { - final String path = "foo" + File.separator + File.separator + File.separator; - assertEquals("foo" + File.separator, FileUtils.ensureTrailingSeparator(path)); - } - - @Test - public void testGetCanonicalPathForNullFile() { - assertNull(FileUtils.getCanonicalPath(null)); - } - - @Test(expected = IllegalStateException.class) - public void testGetCanonicalPathForInvalidFile() throws Exception { - // Set up - final File invalidFile = mock(File.class); - when(invalidFile.getCanonicalPath()).thenThrow(new IOException("dummy")); - - // Invoke - FileUtils.getCanonicalPath(invalidFile); - } - - @Test - public void testGetCanonicalPathForValidFile() throws Exception { - // Set up - final File validFile = mock(File.class); - final String canonicalPath = "the_path"; - when(validFile.getCanonicalPath()).thenReturn(canonicalPath); - - // Invoke - final String actualPath = FileUtils.getCanonicalPath(validFile); - - // Check - assertEquals(canonicalPath, actualPath); - } - - @Test - public void testRemoveLeadingAndTrailingSeparatorsFromNullPath() { - assertNull(FileUtils.removeLeadingAndTrailingSeparators(null)); - } - - @Test - public void testRemoveLeadingAndTrailingSeparatorsFromEmptyPath() { - assertEquals("", FileUtils.removeLeadingAndTrailingSeparators("")); - } - - @Test - public void testRemoveLeadingAndTrailingSeparatorsFromPlainPath() { - final String path = "foo"; - assertEquals(path, FileUtils.removeLeadingAndTrailingSeparators(path)); - } - - @Test - public void testRemoveLeadingAndTrailingSeparatorsFromPathWithBoth() { - // Set up - final String separators = File.separator + File.separator + File.separator + File.separator; - final String path = separators + "foo" + separators; - - // Invoke and check - assertEquals("foo", FileUtils.removeLeadingAndTrailingSeparators(path)); - } - - @Test - public void testGetFile() { - assertTrue(FileUtils.getFile(Loader.class, TEST_FILE).isFile()); - } - - @Test - public void testGetPath() { - assertEquals("/org/springframework/shell/support/util/loader/sub/file-utils-test.txt", FileUtils.getPath(Loader.class, "sub/file-utils-test.txt")); - } - - @Test - public void testGetInputStreamOfFileInSubDirectory() throws Exception { - // Invoke - final InputStream inputStream = FileUtils.getInputStream(Loader.class, TEST_FILE); - - // Check - final String contents = FileCopyUtils.copyToString(new InputStreamReader(inputStream)); - assertEquals("This file is required for FileUtilsTest.", contents); - } - - @Test(expected = IllegalArgumentException.class) - public void testGetInputStreamOfInvalidFile() throws Exception { - FileUtils.getInputStream(Loader.class, MISSING_FILE); - } - - private void assertFirstDirectory(final String path, final String expectedFirstDirectory) { - // Invoke - final String firstDirectory = FileUtils.getFirstDirectory(path); - - // Check - assertEquals(expectedFirstDirectory, firstDirectory); - } - - @Test - public void testGetFirstDirectoryOfExistingDirectory() { - // Set up - final String directory = FileUtils.getFile(Loader.class, TEST_FILE).getParent(); - - // Invoke - final String firstDirectory = FileUtils.getFirstDirectory(directory); - - // Check - assertTrue(firstDirectory.endsWith("sub")); - } - - @Test - public void testGetFirstDirectoryOfExistingFile() { - assertFirstDirectory(TEST_FILE, "sub"); - } - - @Test - public void testBackOneDirectory() { - assertEquals("foo" + File.separator + "bar", FileUtils.backOneDirectory("foo" + File.separator + "bar" + File.separator + "baz" + File.separator)); - } -} diff --git a/src/test/java/org/springframework/shell/support/util/IOUtilsTest.java b/src/test/java/org/springframework/shell/support/util/IOUtilsTest.java deleted file mode 100644 index 9b73e080..00000000 --- a/src/test/java/org/springframework/shell/support/util/IOUtilsTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import java.io.Closeable; -import java.io.IOException; - -import org.junit.Test; -import org.springframework.shell.support.util.IOUtils; - -/** - * Unit test of {@link IOUtils}. - * - * @author Andrew Swan - * @since 1.2.0 - */ -public class IOUtilsTest { - - @Test - public void testCloseNullCloseable() { - IOUtils.closeQuietly((Closeable) null); // Shouldn't throw an exception - } - - @Test - public void testCloseNonNullCloseableWithoutError() throws Exception { - // Set up - final Closeable mockCloseable = mock(Closeable.class); - - // Invoke - IOUtils.closeQuietly(mockCloseable); - - // Check - verify(mockCloseable).close(); - } - - @Test - public void testCloseTwoNonNullCloseableWithErrorOnFirst() throws Exception { - // Set up - final Closeable mockCloseable1 = mock(Closeable.class); - doThrow(new IOException("dummy")).when(mockCloseable1).close(); - final Closeable mockCloseable2 = mock(Closeable.class); - - // Invoke - IOUtils.closeQuietly(mockCloseable1, mockCloseable2); - - // Check - verify(mockCloseable1).close(); - verify(mockCloseable2).close(); - } -} diff --git a/src/test/java/org/springframework/shell/support/util/StringUtilsTest.java b/src/test/java/org/springframework/shell/support/util/StringUtilsTest.java deleted file mode 100644 index 2c858dd3..00000000 --- a/src/test/java/org/springframework/shell/support/util/StringUtilsTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class StringUtilsTest { - - @Test - public void testPadRightWithNullString() { - assertEquals(" ", StringUtils.padRight(null, 5)); - } - - @Test - public void testPadRightWithEmptyString() { - assertEquals(" ", StringUtils.padRight("", 5)); - } - - @Test - public void testPadRight() { - assertEquals("foo ", StringUtils.padRight("foo", 5)); - } - - @Test - public void testLeftPad_StringInt() { - assertEquals(null, StringUtils.padLeft(null, 5)); - assertEquals(" ", StringUtils.padLeft("", 5)); - assertEquals(" abc", StringUtils.padLeft("abc", 5)); - assertEquals("abc", StringUtils.padLeft("abc", 2)); - } - - @Test - public void testLeftPad_StringIntChar() { - assertEquals(null, StringUtils.padLeft(null, 5, ' ')); - assertEquals(" ", StringUtils.padLeft("", 5, ' ')); - assertEquals(" abc", StringUtils.padLeft("abc", 5, ' ')); - assertEquals("xxabc", StringUtils.padLeft("abc", 5, 'x')); - assertEquals("\uffff\uffffabc", StringUtils.padLeft("abc", 5, '\uffff')); - assertEquals("abc", StringUtils.padLeft("abc", 2, ' ')); - String str = StringUtils.padLeft("aaa", 10000, 'a'); // bigger than pad length - assertEquals(10000, str.length()); - //Note, did not include the next assert to avoid pulling in a long chain of methods from commons lang - //assertEquals(true, StringUtils.containsOnly(str, new char[] {'a'})); - } - - @Test - public void testLeftPad_StringIntString() { - assertEquals(null, StringUtils.padLeft(null, 5, "-+")); - assertEquals(null, StringUtils.padLeft(null, 5, null)); - assertEquals(" ", StringUtils.padLeft("", 5, " ")); - assertEquals("-+-+abc", StringUtils.padLeft("abc", 7, "-+")); - assertEquals("-+~abc", StringUtils.padLeft("abc", 6, "-+~")); - assertEquals("-+abc", StringUtils.padLeft("abc", 5, "-+~")); - assertEquals("abc", StringUtils.padLeft("abc", 2, " ")); - assertEquals("abc", StringUtils.padLeft("abc", -1, " ")); - assertEquals(" abc", StringUtils.padLeft("abc", 5, null)); - assertEquals(" abc", StringUtils.padLeft("abc", 5, "")); - } -} diff --git a/src/test/java/org/springframework/shell/support/util/loader/Loader.java b/src/test/java/org/springframework/shell/support/util/loader/Loader.java deleted file mode 100644 index 8ec5d5e1..00000000 --- a/src/test/java/org/springframework/shell/support/util/loader/Loader.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2011-2012 the original author or authors. - * - * 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.springframework.shell.support.util.loader; - -import org.springframework.shell.support.util.FileUtilsTest; - -/** - * Required for {@link FileUtilsTest}. - * - * @author Andrew Swan - * @since 1.2.0 - */ -public class Loader {} diff --git a/src/test/java/org/springframework/shell/table/AbstractTestWithSample.java b/src/test/java/org/springframework/shell/table/AbstractTestWithSample.java deleted file mode 100644 index ba9e85a6..00000000 --- a/src/test/java/org/springframework/shell/table/AbstractTestWithSample.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import org.junit.Rule; -import org.junit.rules.TestName; - -import org.springframework.util.Assert; -import org.springframework.util.FileCopyUtils; - -/** - * Base class that allows reading a sample result rendering of a table, based on the actual - * class and method name of the test. - * - * @author Eric Bottard - */ -public class AbstractTestWithSample { - - @Rule - public TestName testName = new TestName(); - - protected String sample() throws IOException { - String sampleName = String.format("%s-%s.txt", - this.getClass().getSimpleName(), testName.getMethodName()); - InputStream stream = TableTest.class.getResourceAsStream(sampleName); - Assert.notNull(stream, "Can't find expected rendering result at " + sampleName); - return FileCopyUtils.copyToString(new InputStreamReader(stream, "UTF-8")).replace("&", ""); - } - - /** - * Generate a simple rows x columns model made of chars. - */ - protected TableModel generate(int rows, int columns) { - Character[][] data = new Character[rows][columns]; - for (int row = 0; row < rows; row++) { - data[row] = new Character[columns]; - for (int column = 0; column < columns; column++) { - data[row][column] = (char) ('a' + row * columns + column); - } - } - return new ArrayTableModel(data); - } - -} diff --git a/src/test/java/org/springframework/shell/table/ArrayTableModelTest.java b/src/test/java/org/springframework/shell/table/ArrayTableModelTest.java deleted file mode 100644 index 9cf6f101..00000000 --- a/src/test/java/org/springframework/shell/table/ArrayTableModelTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -import org.junit.Test; - -/** - * Tests for ArrayTableModel. - * - * @author Eric Bottard - */ -public class ArrayTableModelTest { - - @Test - public void testValid() { - TableModel model = new ArrayTableModel(new String[][] {{"a", "b"}, {"c", "d"}}); - assertThat(model.getColumnCount(), equalTo(2)); - assertThat(model.getRowCount(), equalTo(2)); - assertThat(model.getValue(0, 1), equalTo((Object) "b")); - } - - @Test - public void testEmpty() { - TableModel model = new ArrayTableModel(new String[][] {}); - assertThat(model.getColumnCount(), equalTo(0)); - assertThat(model.getRowCount(), equalTo(0)); - } - - @Test(expected = IllegalArgumentException.class) - public void testInvalidDimensions() { - new ArrayTableModel(new String[][] {{"a", "b"}, {"c", "d", "e"}}); - } - -} \ No newline at end of file diff --git a/src/test/java/org/springframework/shell/table/BeanListTableModelTest.java b/src/test/java/org/springframework/shell/table/BeanListTableModelTest.java deleted file mode 100644 index ddb0fecc..00000000 --- a/src/test/java/org/springframework/shell/table/BeanListTableModelTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; - -import org.junit.Test; - -/** - * Test for BeanListTableModel. - * - * @author Eric Bottard - */ -public class BeanListTableModelTest extends AbstractTestWithSample { - - @Test - public void testSimpleConstructor() throws IOException { - - List data = data(); - - Table table = new TableBuilder(new BeanListTableModel(Person.class, data)).build(); - String result = table.render(80); - assertThat(result, equalTo(sample())); - - } - - @Test - public void testExplicitPropertyNames() throws IOException { - - List data = data(); - - Table table = new TableBuilder(new BeanListTableModel(data, "lastName", "firstName")).build(); - String result = table.render(80); - assertThat(result, equalTo(sample())); - - } - - @Test - public void testHeaderRow() throws IOException { - - List data = data(); - - LinkedHashMap header = new LinkedHashMap(); - header.put("lastName", "Last Name"); - header.put("firstName", "First Name"); - - Table table = new TableBuilder(new BeanListTableModel(data, header)).build(); - String result = table.render(80); - assertThat(result, equalTo(sample())); - - } - - private List data() { - List data = new ArrayList(); - data.add(new Person("Alice", "Clark", 12)); - data.add(new Person("Bob", "Smith", 42)); - data.add(new Person("Sarah", "Connor", 38)); - return data; - } - - public static class Person { - private int age; - - private String firstName; - - private String lastName; - - public Person(String firstName, String lastName, int age) { - this.age = age; - this.firstName = firstName; - this.lastName = lastName; - } - - public int getAge() { - return age; - } - - public String getFirstName() { - return firstName; - } - - public String getLastName() { - return lastName; - } - } - -} \ No newline at end of file diff --git a/src/test/java/org/springframework/shell/table/BorderFactoryTest.java b/src/test/java/org/springframework/shell/table/BorderFactoryTest.java deleted file mode 100644 index 83016a15..00000000 --- a/src/test/java/org/springframework/shell/table/BorderFactoryTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; -import static org.springframework.shell.table.BorderStyle.fancy_double; - -import java.io.IOException; - -import org.junit.Test; - -/** - * Tests for convenience borders factory. - * - * @author Eric Bottard - */ -public class BorderFactoryTest extends AbstractTestWithSample { - - @Test - public void testOutlineBorder() throws IOException { - TableModel model = generate(3, 3); - Table table = new TableBuilder(model).addOutlineBorder(fancy_double).build(); - String result = table.render(80); - assertThat(result, equalTo(sample())); - } - - @Test - public void testFullBorder() throws IOException { - TableModel model = generate(3, 3); - Table table = new TableBuilder(model).addFullBorder(fancy_double).build(); - String result = table.render(80); - assertThat(result, equalTo(sample())); - } - - @Test - public void testHeaderBorder() throws IOException { - TableModel model = generate(3, 3); - Table table = new TableBuilder(model).addHeaderBorder(fancy_double).build(); - String result = table.render(80); - assertThat(result, equalTo(sample())); - } - - @Test - public void testHeaderAndVerticalsBorder() throws IOException { - TableModel model = generate(3, 3); - Table table = new TableBuilder(model).addHeaderAndVerticalsBorders(fancy_double).build(); - String result = table.render(80); - assertThat(result, equalTo(sample())); - } -} \ No newline at end of file diff --git a/src/test/java/org/springframework/shell/table/BorderStyleTests.java b/src/test/java/org/springframework/shell/table/BorderStyleTests.java deleted file mode 100644 index 8d708b65..00000000 --- a/src/test/java/org/springframework/shell/table/BorderStyleTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; - -import org.junit.Test; - -/** - * Tests for BorderStyle rendering and combinations. - * - * @author Eric Bottard - */ -public class BorderStyleTests extends AbstractTestWithSample { - - @Test - public void testOldSchool() throws IOException { - Table table = new TableBuilder(generate(2, 2)).addFullBorder(BorderStyle.oldschool).build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testFancySimple() throws IOException { - Table table = new TableBuilder(generate(2, 2)).addFullBorder(BorderStyle.fancy_light).build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testFancyHeavy() throws IOException { - Table table = new TableBuilder(generate(2, 2)).addFullBorder(BorderStyle.fancy_heavy).build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testFancyDouble() throws IOException { - Table table = new TableBuilder(generate(2, 2)).addFullBorder(BorderStyle.fancy_double).build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testAir() throws IOException { - Table table = new TableBuilder(generate(2, 2)).addFullBorder(BorderStyle.air).build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testMixedOldSchoolWithAir() throws IOException { - Table table = new TableBuilder(generate(2, 2)) - .addFullBorder(BorderStyle.air) - .addOutlineBorder(BorderStyle.oldschool) - .build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testMixedFancyLightAndHeavy() throws IOException { - Table table = new TableBuilder(generate(2, 2)) - .addFullBorder(BorderStyle.fancy_heavy) - .addOutlineBorder(BorderStyle.fancy_light) - .build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testMixedFancyHeavyAndLight() throws IOException { - Table table = new TableBuilder(generate(2, 2)) - .addFullBorder(BorderStyle.fancy_light) - .addOutlineBorder(BorderStyle.fancy_heavy) - .build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testMixedDoubleAndSingle() throws IOException { - Table table = new TableBuilder(generate(2, 2)) - .addFullBorder(BorderStyle.fancy_light) - .addOutlineBorder(BorderStyle.fancy_double) - .build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testMixedSingleAndDouble() throws IOException { - Table table = new TableBuilder(generate(2, 2)) - .addFullBorder(BorderStyle.fancy_double) - .addOutlineBorder(BorderStyle.fancy_light) - .build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testMixedLightInternalAndHeavy() throws IOException { - Table table = new TableBuilder(generate(3, 3)) - .addFullBorder(BorderStyle.fancy_heavy) - .paintBorder(BorderStyle.fancy_light, BorderSpecification.OUTLINE).fromRowColumn(1, 1).toRowColumn(2, 2) - .build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testMixedHeavyInternalAndLight() throws IOException { - Table table = new TableBuilder(generate(3, 3)) - .addFullBorder(BorderStyle.fancy_light) - .paintBorder(BorderStyle.fancy_heavy, BorderSpecification.OUTLINE).fromRowColumn(1, 1).toRowColumn(2, 2) - .build(); - assertThat(table.render(10), is(sample())); - } - - @Test - public void testHeavyOutlineAndHeader_LightVerticals_AirHorizontals() throws IOException { - Table table = new TableBuilder(generate(4, 4)) - .addOutlineBorder(BorderStyle.fancy_heavy) - .paintBorder(BorderStyle.fancy_light, BorderSpecification.INNER_VERTICAL).fromTopLeft().toBottomRight() - .paintBorder(BorderStyle.air, BorderSpecification.INNER_HORIZONTAL).fromTopLeft().toBottomRight() - .paintBorder(BorderStyle.fancy_heavy, BorderSpecification.OUTLINE).fromTopLeft().toRowColumn(1, 4) - .build(); - assertThat(table.render(10), is(sample())); - } -} diff --git a/src/test/java/org/springframework/shell/table/DelimiterTextWrapperTest.java b/src/test/java/org/springframework/shell/table/DelimiterTextWrapperTest.java deleted file mode 100644 index 77372e63..00000000 --- a/src/test/java/org/springframework/shell/table/DelimiterTextWrapperTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -import org.junit.Test; - -/** - * Tests for DelimiterTextWrapper. - * - * @author Eric Bottard - */ -public class DelimiterTextWrapperTest { - - private TextWrapper wrapper = new DelimiterTextWrapper(); - - @Test - public void testNoWordSplit() { - String[] text = new String[] {"the quick brown fox jumps over the lazy dog."}; - assertThat(wrapper.wrap(text, 10), - arrayContaining("the quick ", "brown fox ", "jumps over", "the lazy ", "dog. ")); - - } - - @Test - public void testWordSplit() { - String[] text = new String[] {"the quick brown fox jumps over the lazy dog."}; - assertThat(wrapper.wrap(text, 4), - arrayContaining("the ", "quic", "k ", "brow", "n ", "fox ", "jump", "s ", "over", "the ", "lazy", "dog.")); - - } - -} \ No newline at end of file diff --git a/src/test/java/org/springframework/shell/table/KeyValueRenderingTests.java b/src/test/java/org/springframework/shell/table/KeyValueRenderingTests.java deleted file mode 100644 index 5033f81d..00000000 --- a/src/test/java/org/springframework/shell/table/KeyValueRenderingTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.junit.Test; - -/** - * Tests related to rendering Maps. - * - * @author Eric Bottard - */ -public class KeyValueRenderingTests extends AbstractTestWithSample { - - @Test - public void testRenderConstrained() throws IOException { - Map values = new LinkedHashMap(); - values.put("a", "b"); - values.put("long-key", "c"); - values.put("d", "long-value"); - TableModel model = new ArrayTableModel(new Object[][] {{"Thing", "Properties"}, {"Something", values}}); - TableBuilder tableBuilder = new TableBuilder(model) - .addHeaderAndVerticalsBorders(BorderStyle.fancy_light); - Tables.configureKeyValueRendering(tableBuilder, " = "); - Table table = tableBuilder.build(); - String result = table.render(10); - assertThat(result, is(sample())); - - } - - @Test - public void testRenderUnconstrained() throws IOException { - Map values = new LinkedHashMap(); - values.put("a", "b"); - values.put("long-key", "c"); - values.put("d", "long-value"); - TableModel model = new ArrayTableModel(new Object[][] {{"Thing", "Properties"}, {"Something", values}}); - TableBuilder tableBuilder = new TableBuilder(model) - .addHeaderAndVerticalsBorders(BorderStyle.fancy_light); - Tables.configureKeyValueRendering(tableBuilder, " = "); - Table table = tableBuilder.build(); - String result = table.render(80); - assertThat(result, is(sample())); - - } -} diff --git a/src/test/java/org/springframework/shell/table/TableModelBuilderTests.java b/src/test/java/org/springframework/shell/table/TableModelBuilderTests.java deleted file mode 100644 index c6a985e2..00000000 --- a/src/test/java/org/springframework/shell/table/TableModelBuilderTests.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import static org.hamcrest.CoreMatchers.is; - -import org.junit.Assert; -import org.junit.Test; - -/** - * Tests for TableModelBuilder. - * - * @author Eric Bottard - */ -public class TableModelBuilderTests { - - @Test - public void emptyModel() { - TableModelBuilder builder = new TableModelBuilder(); - TableModel model = builder.build(); - Assert.assertThat(model.getColumnCount(), is(0)); - Assert.assertThat(model.getRowCount(), is(0)); - } - - @Test(expected = IllegalArgumentException.class) - public void testFrozen() { - TableModelBuilder builder = new TableModelBuilder(); - builder.addRow().addValue(5); - builder.build(); - builder.addRow(); - } - - @Test(expected = IllegalArgumentException.class) - public void testAddingTooManyValues() { - TableModelBuilder builder = new TableModelBuilder(); - builder.addRow().addValue(5); - builder.addRow().addValue(1).addValue(2); - builder.build(); - } - - @Test(expected = IllegalArgumentException.class) - public void testAddingLessValues() { - TableModelBuilder builder = new TableModelBuilder(); - builder.addRow().addValue(1).addValue(2); - builder.addRow().addValue(5); - builder.addRow(); - builder.build(); - } - - @Test - public void simpleBuild() { - TableModelBuilder builder = new TableModelBuilder(); - builder - .addRow() - .addValue(7).addValue(2) - .addRow() - .addValue(3).addValue(5.5) - .addRow() - .addValue(1).addValue(4); - - TableModel model = builder.build(); - Assert.assertThat(model.getColumnCount(), is(2)); - Assert.assertThat(model.getRowCount(), is(3)); - Assert.assertThat(model.getValue(1, 1), is((Object)5.5)); - - } -} \ No newline at end of file diff --git a/src/test/java/org/springframework/shell/table/TableModelTest.java b/src/test/java/org/springframework/shell/table/TableModelTest.java deleted file mode 100644 index ef1b9d8c..00000000 --- a/src/test/java/org/springframework/shell/table/TableModelTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -import org.junit.Test; - -/** - * Tests for TableModel. - * - * @author Eric Bottard - */ -public class TableModelTest { - - @Test - public void testTranspose() { - TableModel model = new ArrayTableModel(new String[][] {{"a", "b", "c"}, {"d", "e", "f"}}); - - assertThat(model.transpose().getColumnCount(), equalTo(2)); - assertThat(model.transpose().getRowCount(), equalTo(3)); - assertThat(model.transpose().getValue(2, 1), equalTo((Object) "f")); - } - -} \ No newline at end of file diff --git a/src/test/java/org/springframework/shell/table/TableTest.java b/src/test/java/org/springframework/shell/table/TableTest.java deleted file mode 100644 index cc0f26fa..00000000 --- a/src/test/java/org/springframework/shell/table/TableTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * 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.springframework.shell.table; - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; -import static org.springframework.shell.table.SimpleHorizontalAligner.*; -import static org.springframework.shell.table.SimpleVerticalAligner.*; - -import java.io.IOException; - -import org.junit.Test; - -/** - * Tests for Table rendering. - * - * @author Eric Bottard - */ -public class TableTest extends AbstractTestWithSample { - - @Test - public void testEmptyModel() { - TableModel model = new ArrayTableModel(new Object[0][0]); - Table table = new TableBuilder(model).build(); - String result = table.render(80); - assertThat(result, equalTo("")); - } - - @Test - public void testPreformattedModel() { - TableModel model = generate(2, 2); - Table table = new TableBuilder(model).build(); - String result = table.render(80); - assertThat(result, equalTo("ab\ncd\n")); - } - - @Test - public void testExpandingColumns() throws IOException { - TableModel model = new ArrayTableModel(new String[][] {{"a", "b"}, {"ccc", "d"}}); - Table table = new TableBuilder(model).build(); - String result = table.render(80); - assertThat(result, equalTo(sample())); - } - - @Test - public void testRightAlignment() throws IOException { - TableModel model = new ArrayTableModel(new String[][] {{"a\na\na", "bbb"}, {"ccc", "d"}}); - Table table = new TableBuilder(model).on(CellMatchers.column(1)).addAligner(right).build(); - String result = table.render(80); - assertThat(result, equalTo(sample())); - } - - @Test - public void testVerticalAlignment() throws IOException { - TableModel model = new ArrayTableModel(new String[][] {{"a\na\na", "bbb"}, {"ccc", "d"}}); - Table table = new TableBuilder(model).on(CellMatchers.row(0)).addAligner(middle).build(); - String result = table.render(80); - assertThat(result, equalTo(sample())); - } - - @Test - public void testAutoWrapping() throws IOException { - TableModel model = new ArrayTableModel(new String[][] {{"this is a long line", "bbb"}, {"ccc", "d"}}); - Table table = new TableBuilder(model).build(); - String result = table.render(10); - assertThat(result, equalTo(sample())); - - } - - @Test - public void testOverflow() throws IOException { - TableModel model = new ArrayTableModel(new String[][] {{"this is a long line", "bbb"}, {"ccc", "d"}}); - Table table = new TableBuilder(model).build(); - String result = table.render(3); - assertThat(result, equalTo(sample())); - - } - - @Test - public void testEmptyCellsVerticalAligner() { - TableModel model = new ArrayTableModel(new String[][] {{"a", "b"}, {null, null}}); - Table table = new TableBuilder(model).on(CellMatchers.table()).addAligner(SimpleVerticalAligner.middle).build(); - String result = table.render(3); - - } - -} diff --git a/src/test/resources/META-INF/spring/spring-shell-plugin.xml b/src/test/resources/META-INF/spring/spring-shell-plugin.xml deleted file mode 100644 index 49d5e66e..00000000 --- a/src/test/resources/META-INF/spring/spring-shell-plugin.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties deleted file mode 100644 index 85417af0..00000000 --- a/src/test/resources/log4j.properties +++ /dev/null @@ -1,16 +0,0 @@ -# configure shell first -log4j.category.org.springframework.shell=INFO, out - -# then everything else -log4j.rootCategory=WARN, stdout - -# standard logging including calling site -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %40.40c:%4L - %m%n - - -# standard logging including calling site -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%m%n \ No newline at end of file diff --git a/src/test/resources/org/springframework/shell/support/util/loader/sub/file-utils-test.txt b/src/test/resources/org/springframework/shell/support/util/loader/sub/file-utils-test.txt deleted file mode 100644 index 501d1441..00000000 --- a/src/test/resources/org/springframework/shell/support/util/loader/sub/file-utils-test.txt +++ /dev/null @@ -1 +0,0 @@ -This file is required for FileUtilsTest. \ No newline at end of file diff --git a/src/test/resources/org/springframework/shell/table/BeanListTableModelTest-testExplicitPropertyNames.txt b/src/test/resources/org/springframework/shell/table/BeanListTableModelTest-testExplicitPropertyNames.txt deleted file mode 100644 index 3f0574d5..00000000 --- a/src/test/resources/org/springframework/shell/table/BeanListTableModelTest-testExplicitPropertyNames.txt +++ /dev/null @@ -1,3 +0,0 @@ -Clark Alice& -Smith Bob & -ConnorSarah& diff --git a/src/test/resources/org/springframework/shell/table/BeanListTableModelTest-testHeaderRow.txt b/src/test/resources/org/springframework/shell/table/BeanListTableModelTest-testHeaderRow.txt deleted file mode 100644 index 21155574..00000000 --- a/src/test/resources/org/springframework/shell/table/BeanListTableModelTest-testHeaderRow.txt +++ /dev/null @@ -1,4 +0,0 @@ -Last NameFirst Name& -Clark Alice & -Smith Bob & -Connor Sarah & diff --git a/src/test/resources/org/springframework/shell/table/BeanListTableModelTest-testSimpleConstructor.txt b/src/test/resources/org/springframework/shell/table/BeanListTableModelTest-testSimpleConstructor.txt deleted file mode 100644 index c2b587b3..00000000 --- a/src/test/resources/org/springframework/shell/table/BeanListTableModelTest-testSimpleConstructor.txt +++ /dev/null @@ -1,3 +0,0 @@ -12AliceClark & -42Bob Smith & -38SarahConnor& diff --git a/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testFullBorder.txt b/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testFullBorder.txt deleted file mode 100644 index 8646d826..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testFullBorder.txt +++ /dev/null @@ -1,7 +0,0 @@ -╔═╦═╦═╗ -║a║b║c║ -╠═╬═╬═╣ -║d║e║f║ -╠═╬═╬═╣ -║g║h║i║ -╚═╩═╩═╝ diff --git a/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testHeaderAndVerticalsBorder.txt b/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testHeaderAndVerticalsBorder.txt deleted file mode 100644 index 6049d713..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testHeaderAndVerticalsBorder.txt +++ /dev/null @@ -1,6 +0,0 @@ -╔═╦═╦═╗ -║a║b║c║ -╠═╬═╬═╣ -║d║e║f║ -║g║h║i║ -╚═╩═╩═╝ diff --git a/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testHeaderBorder.txt b/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testHeaderBorder.txt deleted file mode 100644 index 1b02abec..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testHeaderBorder.txt +++ /dev/null @@ -1,6 +0,0 @@ -╔═══╗ -║abc║ -╠═══╣ -║def║ -║ghi║ -╚═══╝ diff --git a/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testOutlineBorder.txt b/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testOutlineBorder.txt deleted file mode 100644 index 14ca640d..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderFactoryTest-testOutlineBorder.txt +++ /dev/null @@ -1,5 +0,0 @@ -╔═══╗ -║abc║ -║def║ -║ghi║ -╚═══╝ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testAir.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testAir.txt deleted file mode 100644 index 76e94529..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testAir.txt +++ /dev/null @@ -1,5 +0,0 @@ - & - a b & - & - c d & - & diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testFancyDouble.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testFancyDouble.txt deleted file mode 100644 index 5ee0a47d..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testFancyDouble.txt +++ /dev/null @@ -1,5 +0,0 @@ -╔═╦═╗ -║a║b║ -╠═╬═╣ -║c║d║ -╚═╩═╝ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testFancyHeavy.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testFancyHeavy.txt deleted file mode 100644 index 6483343f..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testFancyHeavy.txt +++ /dev/null @@ -1,5 +0,0 @@ -┏━┳━┓ -┃a┃b┃ -┣━╋━┫ -┃c┃d┃ -┗━┻━┛ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testFancySimple.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testFancySimple.txt deleted file mode 100644 index fc56b325..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testFancySimple.txt +++ /dev/null @@ -1,5 +0,0 @@ -┌─┬─┐ -│a│b│ -├─┼─┤ -│c│d│ -└─┴─┘ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testHeavyOutlineAndHeader_LightVerticals_AirHorizontals.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testHeavyOutlineAndHeader_LightVerticals_AirHorizontals.txt deleted file mode 100644 index e1132f0d..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testHeavyOutlineAndHeader_LightVerticals_AirHorizontals.txt +++ /dev/null @@ -1,9 +0,0 @@ -┏━┯━┯━┯━┓ -┃a│b│c│d┃ -┣━┿━┿━┿━┫ -┃e│f│g│h┃ -┃ │ │ │ ┃ -┃i│j│k│l┃ -┃ │ │ │ ┃ -┃m│n│o│p┃ -┗━┷━┷━┷━┛ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedDoubleAndSingle.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedDoubleAndSingle.txt deleted file mode 100644 index f03ef353..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedDoubleAndSingle.txt +++ /dev/null @@ -1,5 +0,0 @@ -╔═╤═╗ -║a│b║ -╟─┼─╢ -║c│d║ -╚═╧═╝ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedFancyHeavyAndLight.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedFancyHeavyAndLight.txt deleted file mode 100644 index 4ae9817c..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedFancyHeavyAndLight.txt +++ /dev/null @@ -1,5 +0,0 @@ -┏━┯━┓ -┃a│b┃ -┠─┼─┨ -┃c│d┃ -┗━┷━┛ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedFancyLightAndHeavy.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedFancyLightAndHeavy.txt deleted file mode 100644 index 793f1f98..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedFancyLightAndHeavy.txt +++ /dev/null @@ -1,5 +0,0 @@ -┌─┰─┐ -│a┃b│ -┝━╋━┥ -│c┃d│ -└─┸─┘ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedHeavyInternalAndLight.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedHeavyInternalAndLight.txt deleted file mode 100644 index 8a2be312..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedHeavyInternalAndLight.txt +++ /dev/null @@ -1,7 +0,0 @@ -┌─┬─┬─┐ -│a│b│c│ -├─╆━╅─┤ -│d┃e┃f│ -├─╄━╃─┤ -│g│h│i│ -└─┴─┴─┘ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedLightInternalAndHeavy.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedLightInternalAndHeavy.txt deleted file mode 100644 index 208de4c9..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedLightInternalAndHeavy.txt +++ /dev/null @@ -1,7 +0,0 @@ -┏━┳━┳━┓ -┃a┃b┃c┃ -┣━╃─╄━┫ -┃d│e│f┃ -┣━╅─╆━┫ -┃g┃h┃i┃ -┗━┻━┻━┛ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedOldSchoolWithAir.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedOldSchoolWithAir.txt deleted file mode 100644 index 4898ef20..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedOldSchoolWithAir.txt +++ /dev/null @@ -1,5 +0,0 @@ -+---+ -|a b| -| | -|c d| -+---+ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedSingleAndDouble.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedSingleAndDouble.txt deleted file mode 100644 index b38fe0d0..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedSingleAndDouble.txt +++ /dev/null @@ -1,5 +0,0 @@ -┌─╥─┐ -│a║b│ -╞═╬═╡ -│c║d│ -└─╨─┘ diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedSingleInternalAndDouble.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testMixedSingleInternalAndDouble.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testOldSchool.txt b/src/test/resources/org/springframework/shell/table/BorderStyleTests-testOldSchool.txt deleted file mode 100644 index 1dfa83b8..00000000 --- a/src/test/resources/org/springframework/shell/table/BorderStyleTests-testOldSchool.txt +++ /dev/null @@ -1,5 +0,0 @@ -+-+-+ -|a|b| -+-+-+ -|c|d| -+-+-+ diff --git a/src/test/resources/org/springframework/shell/table/KeyValueRenderingTests-testRenderConstrained.txt b/src/test/resources/org/springframework/shell/table/KeyValueRenderingTests-testRenderConstrained.txt deleted file mode 100644 index 1fa83024..00000000 --- a/src/test/resources/org/springframework/shell/table/KeyValueRenderingTests-testRenderConstrained.txt +++ /dev/null @@ -1,9 +0,0 @@ -┌─────────┬──────────┐ -│Thing │Properties│ -├─────────┼──────────┤ -│Something│a = b │ -│ │long-key │ -│ │ = c │ -│ │d = │ -│ │long-value│ -└─────────┴──────────┘ diff --git a/src/test/resources/org/springframework/shell/table/KeyValueRenderingTests-testRenderUnconstrained.txt b/src/test/resources/org/springframework/shell/table/KeyValueRenderingTests-testRenderUnconstrained.txt deleted file mode 100644 index 7029aca1..00000000 --- a/src/test/resources/org/springframework/shell/table/KeyValueRenderingTests-testRenderUnconstrained.txt +++ /dev/null @@ -1,7 +0,0 @@ -┌─────────┬─────────────────────┐ -│Thing │Properties │ -├─────────┼─────────────────────┤ -│Something│ a = b │ -│ │long-key = c │ -│ │ d = long-value│ -└─────────┴─────────────────────┘ diff --git a/src/test/resources/org/springframework/shell/table/TableTest-testAutoWrapping.txt b/src/test/resources/org/springframework/shell/table/TableTest-testAutoWrapping.txt deleted file mode 100644 index 27ff050f..00000000 --- a/src/test/resources/org/springframework/shell/table/TableTest-testAutoWrapping.txt +++ /dev/null @@ -1,4 +0,0 @@ -this isbbb& -a long & -line & -ccc d & diff --git a/src/test/resources/org/springframework/shell/table/TableTest-testExpandingColumns.txt b/src/test/resources/org/springframework/shell/table/TableTest-testExpandingColumns.txt deleted file mode 100644 index 9e0cab8e..00000000 --- a/src/test/resources/org/springframework/shell/table/TableTest-testExpandingColumns.txt +++ /dev/null @@ -1,2 +0,0 @@ -a b& -cccd& diff --git a/src/test/resources/org/springframework/shell/table/TableTest-testOverflow.txt b/src/test/resources/org/springframework/shell/table/TableTest-testOverflow.txt deleted file mode 100644 index f52d06da..00000000 --- a/src/test/resources/org/springframework/shell/table/TableTest-testOverflow.txt +++ /dev/null @@ -1,5 +0,0 @@ -thisbbb& -is a & -long & -line & -ccc d & diff --git a/src/test/resources/org/springframework/shell/table/TableTest-testRightAlignment.txt b/src/test/resources/org/springframework/shell/table/TableTest-testRightAlignment.txt deleted file mode 100644 index c8bdc6ec..00000000 --- a/src/test/resources/org/springframework/shell/table/TableTest-testRightAlignment.txt +++ /dev/null @@ -1,4 +0,0 @@ -a bbb& -a & -a & -ccc d& diff --git a/src/test/resources/org/springframework/shell/table/TableTest-testVerticalAlignment.txt b/src/test/resources/org/springframework/shell/table/TableTest-testVerticalAlignment.txt deleted file mode 100644 index c19dd858..00000000 --- a/src/test/resources/org/springframework/shell/table/TableTest-testVerticalAlignment.txt +++ /dev/null @@ -1,4 +0,0 @@ -a & -a bbb& -a & -cccd & diff --git a/src/test/resources/testRenderParameterInfoDataAsTableWithMaxWidth.txt b/src/test/resources/testRenderParameterInfoDataAsTableWithMaxWidth.txt deleted file mode 100644 index 8e40391d..00000000 --- a/src/test/resources/testRenderParameterInfoDataAsTableWithMaxWidth.txt +++ /dev/null @@ -1,5 +0,0 @@ - -------------- -------------------- - Key1 Lorem ipsum dolor si - t posuere. - My super key 2 Lorem ipsum - -------------- -------------------- diff --git a/src/test/resources/testRenderTableWithRowShorthand-expected-output.txt b/src/test/resources/testRenderTableWithRowShorthand-expected-output.txt deleted file mode 100644 index 428e7da4..00000000 --- a/src/test/resources/testRenderTableWithRowShorthand-expected-output.txt +++ /dev/null @@ -1,7 +0,0 @@ - Property Value - -------------------- ----------- - Job Execution ID 1 - Job Name My Job Name - Start Time 12:30 - Step Execution Count 12 - Status COMPLETED diff --git a/src/test/resources/testRenderTextTable-expected-output.txt b/src/test/resources/testRenderTextTable-expected-output.txt deleted file mode 100644 index 598af963..00000000 --- a/src/test/resources/testRenderTextTable-expected-output.txt +++ /dev/null @@ -1,5 +0,0 @@ - Tap Name Stream Name Tap Definition - -------- ----------- ---------------- - tap1 ticktock tap@ticktock|log - tap2 ticktock tap@ticktock|log - tap3 ticktock tap@ticktock|log diff --git a/src/test/resources/testRenderTextTable-single-column-expected-output.txt b/src/test/resources/testRenderTextTable-single-column-expected-output.txt deleted file mode 100644 index 5b36a888..00000000 --- a/src/test/resources/testRenderTextTable-single-column-expected-output.txt +++ /dev/null @@ -1,3 +0,0 @@ - Gauge name - ----------- - simplegauge diff --git a/src/test/resources/testRenderTextTable-single-column-width4-expected-output.txt b/src/test/resources/testRenderTextTable-single-column-width4-expected-output.txt deleted file mode 100644 index deda57c9..00000000 --- a/src/test/resources/testRenderTextTable-single-column-width4-expected-output.txt +++ /dev/null @@ -1,7 +0,0 @@ - Gaug - e na - me - ---- - simp - lega - uge