diff --git a/README.md b/README.md index 78f5a5114..937b52b4d 100644 --- a/README.md +++ b/README.md @@ -97,17 +97,6 @@ Here is a brief summary of each module: If you want to deploy in a web server, you will ` restx-servlet ` -### Shell modules: - -- `restx-shell`: The pluggable shell. -- `restx-shell-manager`: Plugin to manage the shell: install plugins, upgrade shell version. -- `restx-build`: The very simple tool which generates POM / Ivy files from `md.restx.json` files -- `restx-core-shell`: Plugin providing RESTX core support in the shell: app comilation and running, ... -- `restx-build-shell`: Plugin prodividing build support in the shell, especially to generate POM/Ivy files from `md.restx.json` files. -- `restx-specs-shell`: Plugin providing RESTX specs based HTTP mock server. -- `restx-package`: assembly module to package the shell - - ### Metrics: - `restx-monitor-codahale`: Codahale metrics for monitor module. Not compatible with Google App Engine. diff --git a/pom.xml b/pom.xml index 15517ca2a..4c63c0280 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,6 @@ 3.2.7 1.7.5 1.0.13 - 2.3 1 1.8 0.9.9-RC1 @@ -133,16 +132,6 @@ restx-security-basic ${restx.version} - - io.restx - restx-shell - ${restx.version} - - - io.restx - restx-build - ${restx.version} - io.restx restx-classloader @@ -153,11 +142,6 @@ restx-apidocs-doclet ${restx.version} - - io.restx - restx-shell-manager - ${restx.version} - io.restx restx-specs-tests @@ -248,11 +232,6 @@ restx-server-tomcat ${restx.version} - - io.restx - restx-core-shell - ${restx.version} - io.restx restx-specs-server @@ -353,13 +332,6 @@ ${reflections.version} - - - org.apache.ivy - ivy - ${ivy.version} - - org.mindrot @@ -422,13 +394,6 @@ ${janino.version} - - - jline - jline - ${jline.version} - - de.undercouch @@ -476,11 +441,6 @@ assertj-core ${assertj-core.version} - - org.apache.maven.shared - maven-verifier - ${maven-verifier.version} - org.mockito mockito-all @@ -565,8 +525,6 @@ restx-barbarywatch restx-classloader restx-security-basic - restx-package - restx-build restx-core restx-core-annotation-processor restx-annotation-processors-package @@ -592,17 +550,6 @@ restx-server-simple restx-server-testing restx-samplest - - restx-core-shell - restx-shell - restx-shell-manager - restx-build-shell - restx-specs-shell restx-validation restx-webjars diff --git a/restx-build-shell/md.restx.json b/restx-build-shell/md.restx.json deleted file mode 100644 index b3c9a32df..000000000 --- a/restx-build-shell/md.restx.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "parent": "io.restx:restx-parent:${restx.version}", - "module": "io.restx:restx-build-shell:${restx.version}", - - "properties": { - "@files": ["../restx.build.properties.json"] - }, - - "fragments": { - "maven": [ - "classpath:///restx/build/fragments/maven/testing-build-shell.xml" - ] - }, - - "dependencies": { - "compile": [ - "io.restx:restx-factory:${restx.version}", - "io.restx:restx-shell:${restx.version}", - "io.restx:restx-build:${restx.version}" - ], - "test": [ - "junit:junit:4.11", - "com.googlecode.junit-toolbox:junit-toolbox:2.3", - "org.assertj:assertj-core:1.6.0", - "org.apache.maven.shared:maven-verifier:${maven-verifier.version}" - ] - } -} diff --git a/restx-build-shell/module.ivy b/restx-build-shell/module.ivy deleted file mode 100644 index 3f68f1475..000000000 --- a/restx-build-shell/module.ivy +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/restx-build-shell/pom.xml b/restx-build-shell/pom.xml deleted file mode 100644 index 0cab1b2a9..000000000 --- a/restx-build-shell/pom.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - 4.0.0 - - - io.restx - restx-parent - 0.35-SNAPSHOT - - - restx-build-shell - restx-build-shell - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${project.basedir}/../ - 10 - - - - - - - - - io.restx - restx-factory - - - io.restx - restx-shell - - - io.restx - restx-build - - - junit - junit - test - - - - com.googlecode.junit-toolbox - junit-toolbox - 2.3 - test - - - org.assertj - assertj-core - test - - - org.apache.maven.shared - maven-verifier - test - - - diff --git a/restx-build-shell/src/main/java/restx/build/shell/BuildShellCommand.java b/restx-build-shell/src/main/java/restx/build/shell/BuildShellCommand.java deleted file mode 100644 index 146959f85..000000000 --- a/restx-build-shell/src/main/java/restx/build/shell/BuildShellCommand.java +++ /dev/null @@ -1,116 +0,0 @@ -package restx.build.shell; - -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; -import jline.console.completer.ArgumentCompleter; -import jline.console.completer.Completer; -import jline.console.completer.StringsCompleter; -import restx.build.RestxBuild; -import restx.factory.Component; -import restx.shell.RestxShell; -import restx.shell.ShellCommandRunner; -import restx.shell.StdShellCommand; - -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.StandardWatchEventKinds; -import java.nio.file.WatchEvent; -import java.util.List; - -/** - * User: xavierhanin - * Date: 4/16/13 - * Time: 5:08 PM - */ -@Component -public class BuildShellCommand extends StdShellCommand { - protected BuildShellCommand() { - super(ImmutableList.of("build"), "build commands: generate pom, ivy, ..."); - } - - @Override - protected Optional doMatch(String line) { - final List args = splitArgs(line); - if (args.size() < 2) { - return Optional.absent(); - } - switch (args.get(1)) { - case "generate": - if (args.size() < 3) { - return Optional.absent(); - } - switch (args.get(2)) { - case "ivy": - return Optional.of(new GenerateModuleCommandRunner("module.ivy")); - case "pom": - return Optional.of(new GenerateModuleCommandRunner("pom.xml")); - } - break; - case "watch": - return Optional.of(new WatchCommandRunner()); - } - - return Optional.absent(); - } - - @Override - protected String resourceMan() { - return "restx/build/shell/build.man"; - } - - @Override - public Iterable getCompleters() { - return ImmutableList.of( - new ArgumentCompleter(new StringsCompleter("build"), new StringsCompleter("generate"), new StringsCompleter("ivy", "pom")), - new ArgumentCompleter(new StringsCompleter("build"), new StringsCompleter("watch"))); - } - - private class GenerateModuleCommandRunner implements ShellCommandRunner { - private final String target; - - public GenerateModuleCommandRunner(String target) { - this.target = target; - } - - @Override - public void run(RestxShell shell) throws Exception { - Path currentLocationAbsolutePath = shell.currentLocation().toAbsolutePath(); - List convert = RestxBuild.convert(currentLocationAbsolutePath + "/**/md.restx.json", target); - if (convert.isEmpty()) { - shell.println("no mathing file found. module descriptors should be named `md.restx.json`"); - } else { - shell.println("converted:"); - for (Path path : convert) { - shell.println("\t" + currentLocationAbsolutePath.relativize(path)); - } - } - } - } - - private class WatchCommandRunner implements ShellCommandRunner, RestxShell.WatchListener { - @Override - public void run(RestxShell shell) throws Exception { - shell.watchFile(this); - shell.printIn("now watching md.restx.json files\n", RestxShell.AnsiCodes.ANSI_YELLOW); - } - - @Override - public void onEvent(RestxShell shell, WatchEvent.Kind kind, Path path) { - if (path.endsWith("md.restx.json") && kind == StandardWatchEventKinds.ENTRY_MODIFY) { - mayConvertTo(shell, path, path.getParent().resolve("pom.xml")); - mayConvertTo(shell, path, path.getParent().resolve("ivy.xml")); - mayConvertTo(shell, path, path.getParent().resolve("module.ivy")); - } - } - - private void mayConvertTo(RestxShell shell, Path source, Path target) { - if (target.toFile().exists()) { - try { - RestxBuild.convert(source, target); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - } -} diff --git a/restx-build-shell/src/main/resources/restx/build/shell/build.man b/restx-build-shell/src/main/resources/restx/build/shell/build.man deleted file mode 100644 index e36a8d816..000000000 --- a/restx-build-shell/src/main/resources/restx/build/shell/build.man +++ /dev/null @@ -1,15 +0,0 @@ -## build generate pom|ivy - -Use this command to update a pom or ivy file based on your `md.restx.json` file. - -Remember that it is recommended in restx app to declare your dependencies in `md.restx.json`, which is a sort of meta -build file, used by restx to provide basic features: dependencies management with `deps install`, compilation and app -running with `app run`. - -You can use this command at the root of a multi module app in which case it will search for all your `md.restx.json` -files and update corresponding module files. - -## build watch - -Use this command to start file system watching to auto update your `pom.xml` and `module.ivy` files when `md.restx.json` -files change. \ No newline at end of file diff --git a/restx-build-shell/src/test/java/restx/build/shell/RestxModuleDescriptorsDiscrepanciesDetectorWithPomAndIvyTest.java b/restx-build-shell/src/test/java/restx/build/shell/RestxModuleDescriptorsDiscrepanciesDetectorWithPomAndIvyTest.java deleted file mode 100644 index c8a8805f0..000000000 --- a/restx-build-shell/src/test/java/restx/build/shell/RestxModuleDescriptorsDiscrepanciesDetectorWithPomAndIvyTest.java +++ /dev/null @@ -1,195 +0,0 @@ -package restx.build.shell; - -import com.google.common.base.Charsets; -import com.google.common.base.Throwables; -import com.google.common.collect.Lists; -import com.google.common.io.LineProcessor; -import com.googlecode.junittoolbox.ParallelParameterized; -import org.apache.maven.it.VerificationException; -import org.apache.maven.it.Verifier; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import restx.build.*; -import restx.common.OSUtils; - -import java.io.*; -import java.nio.file.*; -import java.util.ArrayList; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -@RunWith(ParallelParameterized.class) -public class RestxModuleDescriptorsDiscrepanciesDetectorWithPomAndIvyTest { - - private enum GenerationType { - IVY("module.ivy") { - @Override - public RestxBuild.Generator generator() { - return new IvySupport(); - } - - }, POM("pom.xml") { - @Override - public RestxBuild.Generator generator() { - return new MavenSupport(); - } - - class RunMavenEffectivePom implements Runnable { - File targetPom; - File effectivePom; - - public RunMavenEffectivePom(File targetPom, File effectivePom) { - this.targetPom = targetPom; - this.effectivePom = effectivePom; - } - - @Override - public void run() { - - try { - Verifier mavenVerifier = new Verifier(targetPom.getParentFile().getAbsolutePath()); - - if (OSUtils.isMacOSX()) { - // on MacOSX, when using the verifier JAVA_HOME is not always properly detected - // sometimes it points to JRE, making javadoc call fail. - // Here is a workaround for that problem - String javaHome = System.getProperty("java.home"); - if (javaHome.endsWith("jre")) { - javaHome = new File(javaHome).getParentFile().getCanonicalPath(); - mavenVerifier.setEnvironmentVariable("JAVA_HOME", javaHome); - } - } - if(System.getProperty("skip-offline") == null) { - mavenVerifier.addCliOption("--offline"); - } - mavenVerifier.addCliOption("-f "+targetPom.getAbsolutePath()); - mavenVerifier.addCliOption("--no-snapshot-updates"); - mavenVerifier.setSystemProperty("output", effectivePom.getAbsolutePath()); - mavenVerifier.setAutoclean(false); - String logFileName = "___log.txt"; - File logFile = targetPom.getParentFile().toPath().resolve(logFileName).toFile(); - mavenVerifier.setLogFileName(logFileName); - mavenVerifier.executeGoal("org.apache.maven.plugins:maven-help-plugin:2.2:effective-pom"); - mavenVerifier.verifyErrorFreeLog(); - - assertTrue(logFile.delete()); - removeGeneratedLineIn(effectivePom); - } catch (VerificationException | IOException e) { - throw Throwables.propagate(e); - } - - System.out.println("Over"); - } - } - - @Override - public void assertExistingAndGeneratedDescriptorsAreSimilar(File existingDescriptor, File generatedDescriptor, TemporaryFolder tempFolder) throws IOException { - File existingEffectivePom = tempFolder.newFile("existingEffectivePom"); - File generatedEffectivePom = tempFolder.newFile("generatedEffectivePom"); - - // I tried to execute those tasks through a fixedThreadPool(2) executor but ... doesn't detect some testing failures - // (for unknown reasons) - new RunMavenEffectivePom(existingDescriptor, existingEffectivePom).run(); - new RunMavenEffectivePom(generatedDescriptor, generatedEffectivePom).run(); - - super.assertExistingAndGeneratedDescriptorsAreSimilar(existingEffectivePom, generatedEffectivePom, tempFolder); - } - - private void removeGeneratedLineIn(File file) throws IOException { - List trimmedLines = com.google.common.io.Files.readLines(file, Charsets.UTF_8, new LineProcessor>() { - List result = Lists.newArrayList(); - - @Override - public boolean processLine(String line) throws IOException { - if(!line.contains("Generated by Maven Help Plugin on")) { - result.add(line); - } - return true; - } - - @Override - public List getResult() { - return result; - } - }); - - Files.write(file.toPath(), trimmedLines, Charsets.UTF_8, StandardOpenOption.CREATE); - } - }; - - private String filename; - GenerationType(String filename) { - this.filename = filename; - } - - public abstract RestxBuild.Generator generator(); - public void assertExistingAndGeneratedDescriptorsAreSimilar(File existingDescriptor, File generatedDescriptor, TemporaryFolder tempFolder) throws IOException { - assertEquals(com.google.common.io.Files.toString(existingDescriptor, Charsets.UTF_8), - com.google.common.io.Files.toString(generatedDescriptor, Charsets.UTF_8)); - } - } - - private final String moduleName; - private final GenerationType generationType; - - @Rule - public TemporaryFolder tempFolder = new TemporaryFolder(); - - @Parameterized.Parameters(name="{0}/{1}") - public static Iterable data(){ - Path restxSourcesRootDir = getRestxSourcesRootDir(); - String[] directories = restxSourcesRootDir.toFile().list(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return new File(dir, name).isDirectory(); - } - }); - - List testingData = new ArrayList<>(); - for(String moduleName: directories) { - if(Files.exists(restxSourcesRootDir.resolve(moduleName).resolve("md.restx.json"))) { - for(GenerationType generationType: GenerationType.values()) { - if(Files.exists(restxSourcesRootDir.resolve(moduleName).resolve(generationType.filename))) { - testingData.add(new Object[]{ moduleName, generationType }); - } - } - } - } - - return testingData; - } - - private static Path getRestxSourcesRootDir() { - return Paths.get(System.getProperty("restxSourcesRootDir")); - } - - public RestxModuleDescriptorsDiscrepanciesDetectorWithPomAndIvyTest(String moduleName, GenerationType generationType) { - this.moduleName = moduleName; - this.generationType = generationType; - } - - @Test - public void should_restx_module_descriptor_and_pom_or_ivy_descriptors_equivalents() throws IOException { - Path restxSourcesRootDir = getRestxSourcesRootDir(); - Path moduleDirectory = restxSourcesRootDir.resolve(this.moduleName); - File existingDescriptor = moduleDirectory.resolve(this.generationType.filename).toFile(); - - ModuleDescriptor moduleDescriptor = new RestxJsonSupport().parse(moduleDirectory.resolve("md.restx.json")); - // Generating the generated descriptor into the same directory than existingDescriptor, in case we would have file-tree - // related stuff into the descriptor (particularly for maven) - File generatedDescriptor = existingDescriptor.getParentFile().toPath().resolve("generated-"+this.generationType.name()+"-descriptor").toFile(); - assertTrue(generatedDescriptor.createNewFile()); - generatedDescriptor.deleteOnExit(); - - try (Writer w = com.google.common.io.Files.newWriter(generatedDescriptor, Charsets.UTF_8)) { - this.generationType.generator().generate(moduleDescriptor, w); - } - - this.generationType.assertExistingAndGeneratedDescriptorsAreSimilar(existingDescriptor, generatedDescriptor, tempFolder); - } -} diff --git a/restx-build/md.restx.json b/restx-build/md.restx.json deleted file mode 100644 index 3f447ca06..000000000 --- a/restx-build/md.restx.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "parent": "io.restx:restx-parent:${restx.version}", - "module": "io.restx:restx-build:${restx.version}", - - "properties": { - "@files": ["../restx.build.properties.json"], - "project.main.classname": "restx.build.RestxBuild" - }, - - "fragments": { - "maven": [ - "classpath:///restx/build/fragments/maven/jar-main-class.xml" - ] - }, - - "dependencies": { - "test": [ - "junit:junit:${junit.version}", - "org.assertj:assertj-core:${assertj-core.version}" - ] - } -} diff --git a/restx-build/module.ivy b/restx-build/module.ivy deleted file mode 100644 index 925fc4dc0..000000000 --- a/restx-build/module.ivy +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/restx-build/pom.xml b/restx-build/pom.xml deleted file mode 100644 index 8a15ea6be..000000000 --- a/restx-build/pom.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - 4.0.0 - - - io.restx - restx-parent - 0.35-SNAPSHOT - - - restx-build - restx-build - - - restx.build.RestxBuild - - - - - junit - junit - test - - - org.assertj - assertj-core - test - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - ${project.main.classname} - - - - - - - diff --git a/restx-build/src/main/java/restx/build/GAV.java b/restx-build/src/main/java/restx/build/GAV.java deleted file mode 100644 index 8e24b07eb..000000000 --- a/restx-build/src/main/java/restx/build/GAV.java +++ /dev/null @@ -1,98 +0,0 @@ -package restx.build; - -/** - * User: xavierhanin - * Date: 4/14/13 - * Time: 2:21 PM - */ -public class GAV { - private static final String OPTIONAL_SUFFIX = "!optional"; - public static GAV parse(String gav) { - String[] parts = gav.split(":"); - if (parts.length < 3 || parts.length > 5) { - throw new IllegalArgumentException("can't parse '" + gav + "' as a module coordinates (GAV). " + - "It must have at least 3 parts separated by columns. (4th and 5th are optional and correspond to artifact type and classifier)"); - } - boolean optional = false; - if(parts[parts.length-1].endsWith(OPTIONAL_SUFFIX)) { - optional = true; - parts[parts.length-1] = parts[parts.length-1].substring(0, parts[parts.length-1].length()-OPTIONAL_SUFFIX.length()); - } - if(parts.length == 3) { - return new GAV(parts[0], parts[1], parts[2], optional); - } - if(parts.length == 4) { - return new GAV(parts[0], parts[1], parts[2], parts[3], optional); - } - return new GAV(parts[0], parts[1], parts[2], parts[3], parts[4], optional); - } - - private final String groupId; - private final String artifactId; - private final String version; - private final String type; - private final String classifier; - private final boolean optional; - - public GAV(String groupId, String artifactId, String version, final boolean optional) { - this(groupId, artifactId, version, null, null, optional); - } - - public GAV(String groupId, String artifactId, String version, String type, final boolean optional) { - this(groupId, artifactId, version, type, null, optional); - } - - public GAV(final String groupId, final String artifactId, final String version, final String type, final String classifier, final boolean optional) { - this.groupId = groupId; - this.artifactId = artifactId; - this.version = version; - this.type = type; - this.classifier = classifier; - this.optional = optional; - } - - public String getGroupId() { - return groupId; - } - - public String getArtifactId() { - return artifactId; - } - - public String getVersion() { - return version; - } - - public String getType() { - return type; - } - - public String getClassifier() { - return classifier; - } - - public boolean isOptional() { - return optional; - } - - @Override - public String toString() { - return groupId + ":" + artifactId + ":" + version; - } - - /** - * toString() will only generate simple GAV whereas toParseableString() - * should generate a String that should return the same GAV content when parsed - * through GAV.parse() - */ - public String toParseableString(){ - String suffix = optional?OPTIONAL_SUFFIX:""; - if (type == null){ - return groupId + ":" + artifactId + ":" + version + suffix; - } - if(classifier == null) { - return groupId + ":" + artifactId + ":" + version + ":" + type + suffix; - } - return groupId + ":" + artifactId + ":" + version + ":" + type + ":" + classifier + suffix; - } -} diff --git a/restx-build/src/main/java/restx/build/IvySupport.java b/restx-build/src/main/java/restx/build/IvySupport.java deleted file mode 100644 index 57e28d789..000000000 --- a/restx-build/src/main/java/restx/build/IvySupport.java +++ /dev/null @@ -1,85 +0,0 @@ -package restx.build; - -import java.io.IOException; -import java.io.Writer; -import java.util.Map; - -/** - * User: xavierhanin - * Date: 4/14/13 - * Time: 2:08 PM - */ -public class IvySupport implements RestxBuild.Generator { - private String eaVersion = "0.9"; - - public void generate(ModuleDescriptor md, Writer w) throws IOException { - if (md.hasClassifier()) { - w.write("\n"); - } else { - w.write("\n"); - } - - w.write(" \n"); - - String buildType = md.getPackaging().equals("war") ? "build-webapp-java" : "build-std-java"; - w.write(" entry : md.getProperties().entrySet()) { - if (entry.getKey().equals("java.version")) { - w.write(" compile.java.source.version=\"" + entry.getValue() + "\"\n"); - w.write(" compile.java.target.version=\"" + entry.getValue() + "\"\n"); - } else if (entry.getKey().endsWith(".version")) { - // versions are inlined, no need to put them here - } else { - w.write(" " + entry.getKey() + "=\"" + entry.getValue() + "\"\n"); - } - } - - w.write(" />\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n"); - - w.write(" \n"); - for (String scope : md.getDependencyScopes()) { - for (ModuleDependency dependency : md.getDependencies(scope)) { - String groupId = dependency.getGav().getGroupId(); - String version = RestxBuildHelper.expandProperty(dependency.getGav().getVersion(), "module.version", md.getGav().getVersion()); - String expandedVersion = RestxBuildHelper.expandProperties(md.getProperties(), version); - if (expandedVersion.endsWith("-SNAPSHOT")) { - expandedVersion = "latest.integration"; - } - if (dependency.getGav().getClassifier() == null) { - w.write(String.format(" \n", - groupId, dependency.getGav().getArtifactId(), - expandedVersion, - "compile".equals(scope) ? "default" : scope +"->default")); - } else { - w.write(String.format(" \n \n \n", - groupId, dependency.getGav().getArtifactId(), - expandedVersion, - "compile".equals(scope) ? "default" : scope +"->default", - dependency.getGav().getArtifactId(), dependency.getGav().getClassifier())); - } - } - } - w.write(" \n"); - - w.write("\n"); - } - - @Override - public String getDefaultFileName() { - return "module.ivy"; - } -} diff --git a/restx-build/src/main/java/restx/build/MavenSupport.java b/restx-build/src/main/java/restx/build/MavenSupport.java deleted file mode 100644 index 98dad40a5..000000000 --- a/restx-build/src/main/java/restx/build/MavenSupport.java +++ /dev/null @@ -1,235 +0,0 @@ -package restx.build; - -import restx.build.org.json.JSONArray; -import restx.build.org.json.JSONObject; -import restx.build.org.json.XML; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.io.Writer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; -import java.util.regex.Pattern; - -/** - * User: xavierhanin - * Date: 4/14/13 - * Time: 2:08 PM - */ -public class MavenSupport implements RestxBuild.Parser, RestxBuild.Generator { - static class Parser { - public ModuleDescriptor parse(InputStream stream) throws IOException { - JSONObject jsonObject = XML.toJSONObject(RestxBuildHelper.toString(stream)).getJSONObject("project"); - - GAV parent; - if (jsonObject.has("parent")) { - JSONObject parentObject = jsonObject.getJSONObject("parent"); - // No packaging type is allowed on tag - parent = getGav(parentObject, null, null); - } else { - parent = null; - } - // Packaging is defined with tag on artefact definition - GAV gav = getGav(jsonObject, "packaging", parent); - String packaging = jsonObject.has("packaging") ? jsonObject.getString("packaging") : "jar"; - - Map properties = new LinkedHashMap<>(); - Map calculatedProperties = new LinkedHashMap<>(); - if (jsonObject.has("properties")) { - JSONObject props = jsonObject.getJSONObject("properties"); - for (Object o : props.keySet()) { - String p = (String) o; - - if (p.equals("maven.compiler.target") || p.equals("maven.compiler.source")) { - calculatedProperties.put("java.version", String.valueOf(props.get(p))); - } else { - calculatedProperties.put(p, String.valueOf(props.get(p))); - } - properties.put(p, String.valueOf(props.get(p))); - } - } - - Map> dependencies = new LinkedHashMap<>(); - - if (jsonObject.has("dependencies")) { - JSONArray deps = jsonObject.getJSONObject("dependencies").getJSONArray("dependency"); - - for (int i = 0; i < deps.length(); i++) { - JSONObject dep = deps.getJSONObject(i); - String scope = dep.has("scope") ? dep.getString("scope") : "compile"; - - List scopeDependencies = dependencies.get(scope); - if (scopeDependencies == null) { - dependencies.put(scope, scopeDependencies = new ArrayList<>()); - } - - // Packaging is defined with tag on dependencies - scopeDependencies.add(new ModuleDependency(getGav(dep, "type", null))); - } - } - - ModuleDescriptor parsedMavenDescriptor = new ModuleDescriptor(parent, gav, packaging, - properties, Collections.emptyList(), new HashMap>(), dependencies, null); - - return new ModuleDescriptor(parent, gav, packaging, - calculatedProperties, Collections.emptyList(), new HashMap>(), dependencies, parsedMavenDescriptor); - } - - private GAV getGav(JSONObject jsonObject, String typeKey, GAV parentGAV) { - return new GAV( - jsonObject.has("groupId")?jsonObject.getString("groupId"):parentGAV==null?null:parentGAV.getGroupId(), - jsonObject.has("artifactId")?jsonObject.getString("artifactId"):parentGAV==null?null:parentGAV.getArtifactId(), - jsonObject.has("version")?String.valueOf(jsonObject.get("version")):parentGAV==null?null:parentGAV.getVersion(), - typeKey==null?null:jsonObject.has(typeKey)?jsonObject.getString(typeKey):parentGAV==null?null:parentGAV.getType(), - jsonObject.has("classifier")?jsonObject.getString("classifier"):null, - jsonObject.has("optional")?jsonObject.getBoolean("optional"):false); - } - } - static class Generator { - private static final Pattern PLUGIN_PATTERN = Pattern.compile("^\\s*\\Q\\E.+\\Q\\E\\s*$", Pattern.DOTALL); - - public void generate(ModuleDescriptor md, Writer w) throws IOException { - w.write(HEADER); - - if (md.getParent() != null) { - w.write(" \n"); - toMavenGAV(md.getParent(), " ", w); - w.write(" \n\n"); - } - - toMavenGAV(md.getGav(), " ", w); - writeXmlTag(w, " ", "packaging", md.getPackaging()); - - writeXmlTag(w, " ", "name", md.getGav().getArtifactId()); - w.write("\n"); - - w.write(" \n"); - for (Map.Entry entry : md.getProperties().entrySet()) { - if (entry.getKey().equals("java.version")) { - writeXmlTag(w, " ", "maven.compiler.target", entry.getValue()); - writeXmlTag(w, " ", "maven.compiler.source", entry.getValue()); - } else if (entry.getKey().endsWith(".version")) { - if (isVersionPropertyUsed(md, entry.getKey())) { - writeXmlTag(w, " ", entry.getKey(), entry.getValue()); - } - } else { - writeXmlTag(w, " ", entry.getKey(), entry.getValue()); - } - } - w.write(" \n\n"); - - w.write(" \n"); - for (String scope : md.getDependencyScopes()) { - for (ModuleDependency dependency : md.getParsedModuleDescriptor().getDependencies(scope)) { - w.write(" \n"); - toMavenGAV(dependency.getGav(), " ", w); - if (!"compile".equals(scope)) { - writeXmlTag(w, " ", "scope", scope); - } - if ("system".equals(scope)) { - if (dependency.getGav().getGroupId().equals("com.sun.tools") - && dependency.getGav().getArtifactId().equals("tools")) { - writeXmlTag(w, " ", "systemPath", "${java.home}/../lib/tools.jar"); - } - } - w.write(" \n"); - } - } - w.write(" \n"); - - StringWriter plugins = new StringWriter(); - StringWriter others = new StringWriter(); - for (ModuleFragment fragment : md.getFragments("maven")) { - if (fragment.matches(PLUGIN_PATTERN)) { - fragment.write(md, plugins); - } else if(fragment.resolvedContent()) { - fragment.write(md, others); - } - } - - if (plugins.toString().length() > 0) { - w.write(" \n"); - w.write(" \n"); - w.write(plugins.toString()); - w.write(" \n"); - w.write(" \n"); - } - if (others.toString().length() > 0) { - w.write(others.toString()); - } - - w.write(FOOTER); - } - - private boolean isVersionPropertyUsed(ModuleDescriptor md, String property) { - for (String scope : md.getDependencyScopes()) { - for (ModuleDependency dependency : md.getParsedModuleDescriptor().getDependencies(scope)) { - if (dependency.getGav().getVersion().indexOf("${" + property + "}") != -1) { - return true; - } - } - } - return false; - } - - private void toMavenGAV(GAV gav, String indent, Writer w) throws IOException { - writeXmlTag(w, indent, "groupId", gav.getGroupId()); - writeXmlTag(w, indent, "artifactId", gav.getArtifactId()); - writeXmlTag(w, indent, "version", gav.getVersion()); - if(gav.getType() != null) { - writeXmlTag(w, indent, "type", gav.getType()); - } - if(gav.getClassifier() != null) { - writeXmlTag(w, indent, "classifier", gav.getClassifier()); - } - if(gav.isOptional()) { - writeXmlTag(w, indent, "optional", Boolean.TRUE.toString()); - } - } - - private void writeXmlTag(Writer w, String indent, String tag, String val) throws IOException { - w.write(indent); - w.write("<"); w.write(tag); w.write(">"); - w.write(val); - w.write("\n"); - } - - - private static final String HEADER = - "\n" + - "\n" + - " 4.0.0\n\n"; - - private static final String FOOTER = "\n"; - - } - - private final Parser parser = new Parser(); - private final Generator generator = new Generator(); - - @Override - public ModuleDescriptor parse(Path path) throws IOException { - try (InputStream inputStream = Files.newInputStream(path)) { - return parse(inputStream); - } - } - - @Override - public ModuleDescriptor parse(InputStream stream) throws IOException { - return parser.parse(stream); - } - - @Override - public void generate(ModuleDescriptor md, Writer w) throws IOException { - generator.generate(md, w); - } - - @Override - public String getDefaultFileName() { - return "pom.xml"; - } -} diff --git a/restx-build/src/main/java/restx/build/ModuleDependency.java b/restx-build/src/main/java/restx/build/ModuleDependency.java deleted file mode 100644 index 8bbcd4590..000000000 --- a/restx-build/src/main/java/restx/build/ModuleDependency.java +++ /dev/null @@ -1,18 +0,0 @@ -package restx.build; - -/** - * User: xavierhanin - * Date: 4/14/13 - * Time: 3:19 PM - */ -public class ModuleDependency { - private final GAV gav; - - public ModuleDependency(GAV gav) { - this.gav = gav; - } - - public GAV getGav() { - return gav; - } -} diff --git a/restx-build/src/main/java/restx/build/ModuleDescriptor.java b/restx-build/src/main/java/restx/build/ModuleDescriptor.java deleted file mode 100644 index 285becb23..000000000 --- a/restx-build/src/main/java/restx/build/ModuleDescriptor.java +++ /dev/null @@ -1,99 +0,0 @@ -package restx.build; - -import java.util.*; - -/** - * User: xavierhanin - * Date: 4/14/13 - * Time: 2:07 PM - */ -public class ModuleDescriptor { - private final GAV parent; - private final GAV gav; - private final String packaging; - private final Map properties; - private final List propertiesFileReferences; - private final Map> fragments; - private final Map> dependencies; - private final ModuleDescriptor parsedModuleDescriptor; - - public ModuleDescriptor(GAV parent, GAV gav, String packaging, - Map properties, - List propertiesFileReferences, - Map> fragments, - Map> dependencies, - ModuleDescriptor parsedModuleDescriptor) { - this.parent = parent; - this.gav = gav; - this.packaging = packaging; - this.propertiesFileReferences = propertiesFileReferences; - this.fragments = Collections.unmodifiableMap(fragments); - this.properties = Collections.unmodifiableMap(properties); - this.dependencies = Collections.unmodifiableMap(dependencies); - this.parsedModuleDescriptor = parsedModuleDescriptor; - } - - public GAV getParent() { - return parent; - } - - public GAV getGav() { - return gav; - } - - public String getPackaging() { - return packaging; - } - - public Map getProperties() { - return properties; - } - - public Set getDependencyScopes() { - return dependencies.keySet(); - } - - public List getDependencies(String scope) { - return dependencies.get(scope); - } - - public Set getFragmentTypes() { - return fragments.keySet(); - } - - public List getFragments(String s) { - List moduleFragments = fragments.get(s); - return moduleFragments == null ? Collections.emptyList() : moduleFragments; - } - - public ModuleDescriptor concatDependency(String scope, ModuleDependency dep) { - LinkedHashMap> newDeps = new LinkedHashMap<>(dependencies); - if (!newDeps.containsKey(scope)) { - newDeps.put(scope, new ArrayList()); - } else { - newDeps.put(scope, new ArrayList(newDeps.get(scope))); - } - newDeps.get(scope).add(dep); - - return new ModuleDescriptor(parent, gav, packaging, properties, propertiesFileReferences, fragments, newDeps, parsedModuleDescriptor); - } - - public boolean hasClassifier() { - for (String scope : this.getDependencyScopes()) { - for (ModuleDependency dependency : this.getDependencies(scope)) { - if (dependency.getGav().getClassifier()!=null) { - return true; - } - } - } - return false; - } - - public ModuleDescriptor getParsedModuleDescriptor() { - return parsedModuleDescriptor==null?this:parsedModuleDescriptor; - } - - public List getPropertiesFileReferences() { - return propertiesFileReferences; - } -} diff --git a/restx-build/src/main/java/restx/build/ModuleFragment.java b/restx-build/src/main/java/restx/build/ModuleFragment.java deleted file mode 100644 index ed2ee1361..000000000 --- a/restx-build/src/main/java/restx/build/ModuleFragment.java +++ /dev/null @@ -1,72 +0,0 @@ -package restx.build; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Writer; -import java.net.URL; -import java.util.regex.Pattern; - -/** - * User: xavierhanin - * Date: 4/15/13 - * Time: 12:32 PM - */ -public class ModuleFragment { - private final String url; - private boolean lazyContentLoaded = false; - private String lazyContent = null; - - public ModuleFragment(String url) { - this.url = url; - } - - public String getUrl() { - return url; - } - - public void write(ModuleDescriptor md, Writer w) throws IOException { - String content = getLazilyContent(); - if(content != null) { - w.write(content); - } - } - - public boolean resolvedContent() { - try { - String content = getLazilyContent(); - return content != null; - } catch (IOException e) { - return false; - } - } - - public boolean matches(Pattern pattern) throws IOException { - String content = getLazilyContent(); - return pattern.matcher(content).matches(); - } - - public String getLazilyContent() throws IOException { - if(!lazyContentLoaded) { - try { - if (url.startsWith("classpath://")) { - String fragmentPath = url.substring("classpath://".length()); - try(InputStream stream = getClass().getResourceAsStream(fragmentPath)) { - if (stream == null) { - throw new IllegalArgumentException("classpath fragment not found: '" + fragmentPath + "'" + - ". Check your classpath."); - } - lazyContent = RestxBuildHelper.toString(stream); - } - } else { - URL fragmentUrl = new URL(url); - try (InputStream stream = fragmentUrl.openStream()) { - lazyContent = RestxBuildHelper.toString(stream); - } - } - } finally { - lazyContentLoaded = true; - } - } - return lazyContent; - } -} diff --git a/restx-build/src/main/java/restx/build/RestxBuild.java b/restx-build/src/main/java/restx/build/RestxBuild.java deleted file mode 100644 index dbc5acc6c..000000000 --- a/restx-build/src/main/java/restx/build/RestxBuild.java +++ /dev/null @@ -1,121 +0,0 @@ -package restx.build; - -import java.io.*; -import java.nio.file.*; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static java.nio.file.FileVisitResult.CONTINUE; - -/** - * User: xavierhanin - * Date: 4/14/13 - * Time: 10:49 PM - */ -public class RestxBuild { - public static interface Parser { - public ModuleDescriptor parse(Path path) throws IOException; - public ModuleDescriptor parse(InputStream stream) throws IOException; - } - public static interface Generator { - public void generate(ModuleDescriptor md, Writer w) throws IOException; - public String getDefaultFileName(); - } - - public static void main(String[] args) throws IOException { - final PrintStream out = System.out; - if (args.length != 3 || !args[0].equalsIgnoreCase("convert")) { - out.println("usage: restx-build convert \n" + - "\teg: restx-build convert md.restx.json pom.xml\n\n" + - "you can also use **/ syntax to convert a bunch of files:" + - "\t restx-build convert **/md.restx.json module.ivy"); - System.exit(1); - } - - convert(args[1], args[2]); - out.println("conversion done."); - } - - /** - * Converts one or a bunch of module descriptor to another format. - * - * @param from either a module descriptor path, or a path using ** notation a la Ant - * @param to the name of the target module descriptor, relative to where from module descriptors are found - * @return the list of paths converted - * @throws IOException - */ - public static List convert(String from, final String to) throws IOException { - final List converted = new ArrayList<>(); - int idx = from.indexOf("**/"); - if (idx != -1) { - Path startFrom = Paths.get(from.substring(0, idx)); - final String name = from.substring(idx + "**/".length()); - Files.walkFileTree(startFrom, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (attrs.isRegularFile() && file.endsWith(name)) { - convert(file, file.getParent().resolve(to)); - converted.add(file); - } - return CONTINUE; - } - }); - } else { - Path fromPath = Paths.get(from); - Path toPath = Paths.get(to); - - convert(fromPath, toPath); - converted.add(fromPath); - } - return converted; - } - - /** - * Converts one module descriptor to another format. - * - * @param fromPath the path of the module descriptor to convert - * @param toPath the path of the target module descriptor - * @throws IOException - */ - public static void convert(Path fromPath, Path toPath) throws IOException { - Parser parser = guessParserFor(fromPath); - Generator generator = guessGeneratorFor(toPath); - - try (FileWriter writer = new FileWriter(toPath.toFile())) { - ModuleDescriptor md = parser.parse(fromPath); - generator.generate(md, writer); - } - } - - private static Generator guessGeneratorFor(Path path) { - if (path.toString().endsWith(".ivy") || path.endsWith("ivy.xml")) { - return new IvySupport(); - } - if (path.endsWith("pom.xml")) { - return new MavenSupport(); - } - return new RestxJsonSupport(); - } - - private static Parser guessParserFor(Path path) { - if (path.endsWith("pom.xml")) { - return new MavenSupport(); - } - return new RestxJsonSupport(); - } - - public static List resolveForeignModuleDescriptorsIn(Path directory) { - List possibleForeignModuleDescriptors = Arrays.asList( - directory.resolve("pom.xml"), directory.resolve("module.ivy")); - - List existingForeignModuleDescriptors = new ArrayList<>(); - for(Path possibleForeignModuleDescriptor : possibleForeignModuleDescriptors){ - if(Files.exists(possibleForeignModuleDescriptor)) { - existingForeignModuleDescriptors.add(possibleForeignModuleDescriptor); - } - } - return existingForeignModuleDescriptors; - } -} diff --git a/restx-build/src/main/java/restx/build/RestxBuildHelper.java b/restx-build/src/main/java/restx/build/RestxBuildHelper.java deleted file mode 100644 index f435f8138..000000000 --- a/restx-build/src/main/java/restx/build/RestxBuildHelper.java +++ /dev/null @@ -1,36 +0,0 @@ -package restx.build; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Map; - -/** - * User: xavierhanin - * Date: 4/16/13 - * Time: 11:55 PM - */ -public class RestxBuildHelper { - // don't want to introduce a dependency just for that - public static String toString(InputStream inputStream) throws IOException { - StringBuilder sb = new StringBuilder(); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - sb.append(line).append("\n"); - } - } - return sb.toString(); - } - - public static String expandProperties(Map properties, String s) { - for (Map.Entry entry : properties.entrySet()) { - s = expandProperty(s, entry.getKey(), entry.getValue()); - } - return s; - } - - public static String expandProperty(String s, String key, String value) { - return s.replace("${" + key + "}", value); - } -} diff --git a/restx-build/src/main/java/restx/build/RestxJsonSupport.java b/restx-build/src/main/java/restx/build/RestxJsonSupport.java deleted file mode 100644 index ec8791103..000000000 --- a/restx-build/src/main/java/restx/build/RestxJsonSupport.java +++ /dev/null @@ -1,256 +0,0 @@ -package restx.build; - -import restx.build.org.json.JSONArray; -import restx.build.org.json.JSONObject; -import restx.build.org.json.JSONTokener; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; - -import static restx.build.RestxBuildHelper.expandProperties; - -/** - * User: xavierhanin - * Date: 4/14/13 - * Time: 2:08 PM - */ -public class RestxJsonSupport implements RestxBuild.Parser, RestxBuild.Generator { - - static class Generator { - public void generate(ModuleDescriptor md, Writer w) throws IOException { - w.write("{\n"); - - if (md.getParent() != null) { - w.write(String.format(" \"parent\": \"%s\",\n", md.getParent().toParseableString())); - } - w.write(String.format(" \"module\": \"%s\",\n", md.getGav().toString())); - if (!"jar".equals(md.getPackaging())) { - w.write(String.format(" \"packaging\": \"%s\",\n", md.getPackaging())); - } - w.write("\n"); - - w.write(" \"properties\": {\n"); - for (Iterator> iterator = md.getProperties().entrySet().iterator(); iterator.hasNext(); ) { - Map.Entry entry = iterator.next(); - w.write(String.format(" \"%s\": \"%s\"", entry.getKey(), entry.getValue())); - if (iterator.hasNext() || !md.getPropertiesFileReferences().isEmpty()) { - w.write(","); - } - w.write("\n"); - } - if(!md.getPropertiesFileReferences().isEmpty()) { - w.write(" \"@files\": [\n"); - for (Iterator itFileRef = md.getPropertiesFileReferences().iterator(); itFileRef.hasNext(); ) { - w.write(String.format(" \"%s\"", itFileRef.next())); - if(itFileRef.hasNext()) { - w.write(","); - } - w.write("\n"); - } - w.write(" ]\n"); - } - w.write(" },\n\n"); - - if(!md.getFragmentTypes().isEmpty()) { - w.write(" \"fragments\": {\n"); - for (Iterator itFragmentType = md.getFragmentTypes().iterator(); itFragmentType.hasNext(); ) { - String fragmentType = itFragmentType.next(); - w.write(String.format(" \"%s\": [\n", fragmentType)); - for (Iterator itFragment = md.getFragments(fragmentType).iterator(); itFragment.hasNext(); ) { - w.write(String.format(" \"%s\"", itFragment.next().getUrl())); - if(itFragment.hasNext()) { - w.write(","); - } - w.write("\n"); - } - w.write(" ]"); - if(itFragmentType.hasNext()) { - w.write(","); - } - w.write("\n"); - } - w.write(" },\n\n"); - } - - w.write(" \"dependencies\": {\n"); - Set scopes = md.getDependencyScopes(); - for (Iterator itScopes = scopes.iterator(); itScopes.hasNext(); ) { - String scope = itScopes.next(); - w.write(String.format(" \"%s\": [\n", scope)); - for (Iterator itDeps = md.getDependencies(scope).iterator(); itDeps.hasNext(); ) { - ModuleDependency dependency = itDeps.next(); - w.write(String.format(" \"%s\"", dependency.getGav().toParseableString())); - if (itDeps.hasNext()) { - w.write(","); - } - w.write("\n"); - } - w.write(" ]"); - if (itScopes.hasNext()) { - w.write(","); - } - w.write("\n"); - } - w.write(" }\n"); - - w.write("}\n"); - } - } - - static class Parser { - public ModuleDescriptor parse(Path path) throws IOException { - try (InputStream inputStream = Files.newInputStream(path)) { - return parse(path, inputStream); - } - } - public ModuleDescriptor parse(InputStream inputStream) throws IOException { - return parse(null, inputStream); - } - private ModuleDescriptor parse(Path path, InputStream inputStream) throws IOException { - JSONObject jsonObject = new JSONObject(new JSONTokener(new InputStreamReader(inputStream, "UTF-8"))); - - JSONObject propertiesJSONObj = null; - Map properties = new LinkedHashMap<>(); - List propertiesFileReferences = new ArrayList<>(); - if (jsonObject.has("properties")) { - propertiesJSONObj = jsonObject.getJSONObject("properties"); - for(Object p: propertiesJSONObj.keySet()) { - String key = p.toString(); - if("@files".equals(key)) { - JSONArray propertyFiles = propertiesJSONObj.getJSONArray(key); - for (int i = 0; i < propertyFiles.length(); i++) { - propertiesFileReferences.add(propertyFiles.getString(i)); - } - } else { - properties.put(key, propertiesJSONObj.getString(key)); - } - } - } - - GAV parent = null; - if (jsonObject.has("parent")) { - parent = GAV.parse(jsonObject.getString("parent")); - } - GAV gav = GAV.parse(jsonObject.getString("module")); - - String packaging = jsonObject.has("packaging") ? jsonObject.getString("packaging") : "jar"; - - Map> dependencies = new LinkedHashMap<>(); - if (jsonObject.has("dependencies")) { - JSONObject scopes = jsonObject.getJSONObject("dependencies"); - for (Object s : scopes.keySet()) { - String scope = s.toString(); - List scopeDeps = new ArrayList<>(); - dependencies.put(scope, scopeDeps); - - JSONArray deps = scopes.getJSONArray(scope); - for (int i = 0; i < deps.length(); i++) { - scopeDeps.add(new ModuleDependency(GAV.parse(deps.getString(i)))); - } - } - } - - Map> fragments = new LinkedHashMap<>(); - if (jsonObject.has("fragments")) { - JSONObject jsonFragments = jsonObject.getJSONObject("fragments"); - for (Object key : jsonFragments.keySet()) { - String type = (String) key; - List fragmentsForType = new ArrayList<>(); - - JSONArray array = jsonFragments.getJSONArray(type); - for (int i = 0; i < array.length(); i++) { - String url = array.getString(i); - fragmentsForType.add(new ModuleFragment(url)); - } - - fragments.put(type, fragmentsForType); - } - } - - ModuleDescriptor parsedModuleDescriptor = new ModuleDescriptor(parent, gav, packaging, properties, propertiesFileReferences, fragments, dependencies, null); - - // Interpolating stuff in parsed module descriptor ... - - Map interpolatedProperties = new LinkedHashMap<>(); - if(propertiesJSONObj != null) { - loadJsonProperties(path == null ? null : path.getParent(), interpolatedProperties, propertiesJSONObj); - } - - GAV interpolatedParent = parent==null?null:GAV.parse(expandProperties(interpolatedProperties, parent.toParseableString())); - GAV interpolatedGAV = GAV.parse(expandProperties(interpolatedProperties, gav.toParseableString())); - - Map> interpolatedDependencies = new LinkedHashMap<>(); - for(Map.Entry> scopedDependenciesEntry: dependencies.entrySet()) { - List scopedDependencies = new ArrayList<>(); - for(ModuleDependency dep: scopedDependenciesEntry.getValue()) { - scopedDependencies.add(new ModuleDependency(GAV.parse(expandProperties(interpolatedProperties, dep.getGav().toParseableString())))); - } - interpolatedDependencies.put(scopedDependenciesEntry.getKey(), scopedDependencies); - } - - Map> interpolatedFragmentsPerModuleType = new LinkedHashMap<>(); - for(Map.Entry> perModuleTypeFragment: fragments.entrySet()) { - List interpolatedFragments = new ArrayList<>(); - for(ModuleFragment fragment: perModuleTypeFragment.getValue()) { - interpolatedFragments.add(new ModuleFragment(expandProperties(interpolatedProperties, fragment.getUrl()))); - } - interpolatedFragmentsPerModuleType.put(perModuleTypeFragment.getKey(), interpolatedFragments); - } - - return new ModuleDescriptor(interpolatedParent, interpolatedGAV, packaging, interpolatedProperties, propertiesFileReferences, interpolatedFragmentsPerModuleType, interpolatedDependencies, parsedModuleDescriptor); - } - - private void loadJsonProperties(Path path, Map properties, JSONObject props) throws IOException { - for (Object p : props.keySet()) { - String key = p.toString(); - - if (key.equals("@files")) { - JSONArray propertyFiles = props.getJSONArray(key); - for (int i = 0; i < propertyFiles.length(); i++) { - String propertyFile = propertyFiles.getString(i); - Path propertyFilePath = path == null ? Paths.get(propertyFile) : path.resolve(propertyFile); - - if (!propertyFilePath.toFile().exists()) { - throw new IllegalArgumentException( - "can't resolve property file " + propertyFilePath.toAbsolutePath() + "." + - " Not found." + - (path == null ? - " Note that parsing from mere inputstream resolve files " + - "relative to current directory." : - "")); - } - - try (InputStreamReader reader = new InputStreamReader(Files.newInputStream(propertyFilePath))) { - loadJsonProperties(propertyFilePath.getParent(), properties, new JSONObject(new JSONTokener(reader))); - } - } - } else { - properties.put(key, props.getString(key)); - } - } - } - } - - private final Generator generator = new Generator(); - private final Parser parser = new Parser(); - - public void generate(ModuleDescriptor md, Writer w) throws IOException { - generator.generate(md, w); - } - - public ModuleDescriptor parse(InputStream inputStream) throws IOException { - return parser.parse(inputStream); - } - - public ModuleDescriptor parse(Path path) throws IOException { - return parser.parse(path); - } - - @Override - public String getDefaultFileName() { - return "md.restx.json"; - } -} diff --git a/restx-build/src/main/java/restx/build/org/json/JSONArray.java b/restx-build/src/main/java/restx/build/org/json/JSONArray.java deleted file mode 100644 index 038b12422..000000000 --- a/restx-build/src/main/java/restx/build/org/json/JSONArray.java +++ /dev/null @@ -1,948 +0,0 @@ -package restx.build.org.json; - -/* - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; - -/** - * A JSONArray is an ordered sequence of values. Its external text form is a - * string wrapped in square brackets with commas separating the values. The - * internal form is an object having get and opt - * methods for accessing the values by index, and put methods for - * adding or replacing values. The values can be any of these types: - * Boolean, JSONArray, JSONObject, - * Number, String, or the - * JSONObject.NULL object. - *

- * The constructor can convert a JSON text into a Java object. The - * toString method converts to JSON text. - *

- * A get method returns a value if one can be found, and throws an - * exception if one cannot be found. An opt method returns a - * default value instead of throwing an exception, and so is useful for - * obtaining optional values. - *

- * The generic get() and opt() methods return an - * object which you can cast or query for type. There are also typed - * get and opt methods that do type checking and type - * coercion for you. - *

- * The texts produced by the toString methods strictly conform to - * JSON syntax rules. The constructors are more forgiving in the texts they will - * accept: - *

    - *
  • An extra , (comma) may appear just - * before the closing bracket.
  • - *
  • The null value will be inserted when there is , - *  (comma) elision.
  • - *
  • Strings may be quoted with ' (single - * quote).
  • - *
  • Strings do not need to be quoted at all if they do not begin with a quote - * or single quote, and if they do not contain leading or trailing spaces, and - * if they do not contain any of these characters: - * { } [ ] / \ : , = ; # and if they do not look like numbers and - * if they are not the reserved words true, false, or - * null.
  • - *
  • Values can be separated by ; (semicolon) as - * well as by , (comma).
  • - *
- * - * @author JSON.org - * @version 2012-11-13 - */ -@SuppressWarnings("unchecked") -public class JSONArray { - - /** - * The arrayList where the JSONArray's properties are kept. - */ - private final ArrayList myArrayList; - - /** - * Construct an empty JSONArray. - */ - public JSONArray() { - this.myArrayList = new ArrayList(); - } - - /** - * Construct a JSONArray from a JSONTokener. - * - * @param x - * A JSONTokener - * @throws JSONException - * If there is a syntax error. - */ - public JSONArray(JSONTokener x) throws JSONException { - this(); - if (x.nextClean() != '[') { - throw x.syntaxError("A JSONArray text must start with '['"); - } - if (x.nextClean() != ']') { - x.back(); - for (;;) { - if (x.nextClean() == ',') { - x.back(); - this.myArrayList.add(JSONObject.NULL); - } else { - x.back(); - this.myArrayList.add(x.nextValue()); - } - switch (x.nextClean()) { - case ';': - case ',': - if (x.nextClean() == ']') { - return; - } - x.back(); - break; - case ']': - return; - default: - throw x.syntaxError("Expected a ',' or ']'"); - } - } - } - } - - /** - * Construct a JSONArray from a source JSON text. - * - * @param source - * A string that begins with [ (left - * bracket) and ends with ] - *  (right bracket). - * @throws JSONException - * If there is a syntax error. - */ - public JSONArray(String source) throws JSONException { - this(new JSONTokener(source)); - } - - /** - * Construct a JSONArray from a Collection. - * - * @param collection - * A Collection. - */ - public JSONArray(Collection collection) { - this.myArrayList = new ArrayList(); - if (collection != null) { - Iterator iter = collection.iterator(); - while (iter.hasNext()) { - this.myArrayList.add(JSONObject.wrap(iter.next())); - } - } - } - - /** - * Construct a JSONArray from an array - * - * @throws JSONException - * If not an array. - */ - public JSONArray(Object array) throws JSONException { - this(); - if (array.getClass().isArray()) { - int length = Array.getLength(array); - for (int i = 0; i < length; i += 1) { - this.put(JSONObject.wrap(Array.get(array, i))); - } - } else { - throw new JSONException( - "JSONArray initial value should be a string or collection or array."); - } - } - - /** - * Get the object value associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return An object value. - * @throws JSONException - * If there is no value for the index. - */ - public Object get(int index) throws JSONException { - Object object = this.opt(index); - if (object == null) { - throw new JSONException("JSONArray[" + index + "] not found."); - } - return object; - } - - /** - * Get the boolean value associated with an index. The string values "true" - * and "false" are converted to boolean. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The truth. - * @throws JSONException - * If there is no value for the index or if the value is not - * convertible to boolean. - */ - public boolean getBoolean(int index) throws JSONException { - Object object = this.get(index); - if (object.equals(Boolean.FALSE) - || (object instanceof String && ((String) object) - .equalsIgnoreCase("false"))) { - return false; - } else if (object.equals(Boolean.TRUE) - || (object instanceof String && ((String) object) - .equalsIgnoreCase("true"))) { - return true; - } - throw new JSONException("JSONArray[" + index + "] is not a boolean."); - } - - /** - * Get the double value associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException - * If the key is not found or if the value cannot be converted - * to a number. - */ - public double getDouble(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number ? ((Number) object).doubleValue() - : Double.parseDouble((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + "] is not a number."); - } - } - - /** - * Get the int value associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException - * If the key is not found or if the value is not a number. - */ - public int getInt(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number ? ((Number) object).intValue() - : Integer.parseInt((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + "] is not a number."); - } - } - - /** - * Get the JSONArray associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return A JSONArray value. - * @throws JSONException - * If there is no value for the index. or if the value is not a - * JSONArray - */ - public JSONArray getJSONArray(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof JSONArray) { - return (JSONArray) object; - } - throw new JSONException("JSONArray[" + index + "] is not a JSONArray."); - } - - /** - * Get the JSONObject associated with an index. - * - * @param index - * subscript - * @return A JSONObject value. - * @throws JSONException - * If there is no value for the index or if the value is not a - * JSONObject - */ - public JSONObject getJSONObject(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof JSONObject) { - return (JSONObject) object; - } - throw new JSONException("JSONArray[" + index + "] is not a JSONObject."); - } - - /** - * Get the long value associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException - * If the key is not found or if the value cannot be converted - * to a number. - */ - public long getLong(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number ? ((Number) object).longValue() - : Long.parseLong((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + "] is not a number."); - } - } - - /** - * Get the string associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return A string value. - * @throws JSONException - * If there is no string value for the index. - */ - public String getString(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof String) { - return (String) object; - } - throw new JSONException("JSONArray[" + index + "] not a string."); - } - - /** - * Determine if the value is null. - * - * @param index - * The index must be between 0 and length() - 1. - * @return true if the value at the index is null, or if there is no value. - */ - public boolean isNull(int index) { - return JSONObject.NULL.equals(this.opt(index)); - } - - /** - * Make a string from the contents of this JSONArray. The - * separator string is inserted between each element. Warning: - * This method assumes that the data structure is acyclical. - * - * @param separator - * A string that will be inserted between the elements. - * @return a string. - * @throws JSONException - * If the array contains an invalid number. - */ - public String join(String separator) throws JSONException { - int len = this.length(); - StringBuffer sb = new StringBuffer(); - - for (int i = 0; i < len; i += 1) { - if (i > 0) { - sb.append(separator); - } - sb.append(JSONObject.valueToString(this.myArrayList.get(i))); - } - return sb.toString(); - } - - /** - * Get the number of elements in the JSONArray, included nulls. - * - * @return The length (or size). - */ - public int length() { - return this.myArrayList.size(); - } - - /** - * Get the optional object value associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return An object value, or null if there is no object at that index. - */ - public Object opt(int index) { - return (index < 0 || index >= this.length()) ? null : this.myArrayList - .get(index); - } - - /** - * Get the optional boolean value associated with an index. It returns false - * if there is no value at that index, or if the value is not Boolean.TRUE - * or the String "true". - * - * @param index - * The index must be between 0 and length() - 1. - * @return The truth. - */ - public boolean optBoolean(int index) { - return this.optBoolean(index, false); - } - - /** - * Get the optional boolean value associated with an index. It returns the - * defaultValue if there is no value at that index or if it is not a Boolean - * or the String "true" or "false" (case insensitive). - * - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * A boolean default. - * @return The truth. - */ - public boolean optBoolean(int index, boolean defaultValue) { - try { - return this.getBoolean(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional double value associated with an index. NaN is returned - * if there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - */ - public double optDouble(int index) { - return this.optDouble(index, Double.NaN); - } - - /** - * Get the optional double value associated with an index. The defaultValue - * is returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index - * subscript - * @param defaultValue - * The default value. - * @return The value. - */ - public double optDouble(int index, double defaultValue) { - try { - return this.getDouble(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional int value associated with an index. Zero is returned if - * there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - */ - public int optInt(int index) { - return this.optInt(index, 0); - } - - /** - * Get the optional int value associated with an index. The defaultValue is - * returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * The default value. - * @return The value. - */ - public int optInt(int index, int defaultValue) { - try { - return this.getInt(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional JSONArray associated with an index. - * - * @param index - * subscript - * @return A JSONArray value, or null if the index has no value, or if the - * value is not a JSONArray. - */ - public JSONArray optJSONArray(int index) { - Object o = this.opt(index); - return o instanceof JSONArray ? (JSONArray) o : null; - } - - /** - * Get the optional JSONObject associated with an index. Null is returned if - * the key is not found, or null if the index has no value, or if the value - * is not a JSONObject. - * - * @param index - * The index must be between 0 and length() - 1. - * @return A JSONObject value. - */ - public JSONObject optJSONObject(int index) { - Object o = this.opt(index); - return o instanceof JSONObject ? (JSONObject) o : null; - } - - /** - * Get the optional long value associated with an index. Zero is returned if - * there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - */ - public long optLong(int index) { - return this.optLong(index, 0); - } - - /** - * Get the optional long value associated with an index. The defaultValue is - * returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * The default value. - * @return The value. - */ - public long optLong(int index, long defaultValue) { - try { - return this.getLong(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional string value associated with an index. It returns an - * empty string if there is no value at that index. If the value is not a - * string and is not null, then it is coverted to a string. - * - * @param index - * The index must be between 0 and length() - 1. - * @return A String value. - */ - public String optString(int index) { - return this.optString(index, ""); - } - - /** - * Get the optional string associated with an index. The defaultValue is - * returned if the key is not found. - * - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * The default value. - * @return A String value. - */ - public String optString(int index, String defaultValue) { - Object object = this.opt(index); - return JSONObject.NULL.equals(object) ? defaultValue : object - .toString(); - } - - /** - * Append a boolean value. This increases the array's length by one. - * - * @param value - * A boolean value. - * @return this. - */ - public JSONArray put(boolean value) { - this.put(value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONArray which - * is produced from a Collection. - * - * @param value - * A Collection value. - * @return this. - */ - public JSONArray put(Collection value) { - this.put(new JSONArray(value)); - return this; - } - - /** - * Append a double value. This increases the array's length by one. - * - * @param value - * A double value. - * @throws JSONException - * if the value is not finite. - * @return this. - */ - public JSONArray put(double value) throws JSONException { - Double d = new Double(value); - JSONObject.testValidity(d); - this.put(d); - return this; - } - - /** - * Append an int value. This increases the array's length by one. - * - * @param value - * An int value. - * @return this. - */ - public JSONArray put(int value) { - this.put(new Integer(value)); - return this; - } - - /** - * Append an long value. This increases the array's length by one. - * - * @param value - * A long value. - * @return this. - */ - public JSONArray put(long value) { - this.put(new Long(value)); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONObject which - * is produced from a Map. - * - * @param value - * A Map value. - * @return this. - */ - public JSONArray put(Map value) { - this.put(new JSONObject(value)); - return this; - } - - /** - * Append an object value. This increases the array's length by one. - * - * @param value - * An object value. The value should be a Boolean, Double, - * Integer, JSONArray, JSONObject, Long, or String, or the - * JSONObject.NULL object. - * @return this. - */ - public JSONArray put(Object value) { - this.myArrayList.add(value); - return this; - } - - /** - * Put or replace a boolean value in the JSONArray. If the index is greater - * than the length of the JSONArray, then null elements will be added as - * necessary to pad it out. - * - * @param index - * The subscript. - * @param value - * A boolean value. - * @return this. - * @throws JSONException - * If the index is negative. - */ - public JSONArray put(int index, boolean value) throws JSONException { - this.put(index, value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONArray which - * is produced from a Collection. - * - * @param index - * The subscript. - * @param value - * A Collection value. - * @return this. - * @throws JSONException - * If the index is negative or if the value is not finite. - */ - public JSONArray put(int index, Collection value) throws JSONException { - this.put(index, new JSONArray(value)); - return this; - } - - /** - * Put or replace a double value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index - * The subscript. - * @param value - * A double value. - * @return this. - * @throws JSONException - * If the index is negative or if the value is not finite. - */ - public JSONArray put(int index, double value) throws JSONException { - this.put(index, new Double(value)); - return this; - } - - /** - * Put or replace an int value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index - * The subscript. - * @param value - * An int value. - * @return this. - * @throws JSONException - * If the index is negative. - */ - public JSONArray put(int index, int value) throws JSONException { - this.put(index, new Integer(value)); - return this; - } - - /** - * Put or replace a long value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index - * The subscript. - * @param value - * A long value. - * @return this. - * @throws JSONException - * If the index is negative. - */ - public JSONArray put(int index, long value) throws JSONException { - this.put(index, new Long(value)); - return this; - } - - /** - * Put a value in the JSONArray, where the value will be a JSONObject that - * is produced from a Map. - * - * @param index - * The subscript. - * @param value - * The Map value. - * @return this. - * @throws JSONException - * If the index is negative or if the the value is an invalid - * number. - */ - public JSONArray put(int index, Map value) throws JSONException { - this.put(index, new JSONObject(value)); - return this; - } - - /** - * Put or replace an object value in the JSONArray. If the index is greater - * than the length of the JSONArray, then null elements will be added as - * necessary to pad it out. - * - * @param index - * The subscript. - * @param value - * The value to put into the array. The value should be a - * Boolean, Double, Integer, JSONArray, JSONObject, Long, or - * String, or the JSONObject.NULL object. - * @return this. - * @throws JSONException - * If the index is negative or if the the value is an invalid - * number. - */ - public JSONArray put(int index, Object value) throws JSONException { - JSONObject.testValidity(value); - if (index < 0) { - throw new JSONException("JSONArray[" + index + "] not found."); - } - if (index < this.length()) { - this.myArrayList.set(index, value); - } else { - while (index != this.length()) { - this.put(JSONObject.NULL); - } - this.put(value); - } - return this; - } - - /** - * Remove an index and close the hole. - * - * @param index - * The index of the element to be removed. - * @return The value that was associated with the index, or null if there - * was no value. - */ - public Object remove(int index) { - Object o = this.opt(index); - this.myArrayList.remove(index); - return o; - } - - /** - * Produce a JSONObject by combining a JSONArray of names with the values of - * this JSONArray. - * - * @param names - * A JSONArray containing a list of key strings. These will be - * paired with the values. - * @return A JSONObject, or null if there are no names or if this JSONArray - * has no values. - * @throws JSONException - * If any of the names are null. - */ - public JSONObject toJSONObject(JSONArray names) throws JSONException { - if (names == null || names.length() == 0 || this.length() == 0) { - return null; - } - JSONObject jo = new JSONObject(); - for (int i = 0; i < names.length(); i += 1) { - jo.put(names.getString(i), this.opt(i)); - } - return jo; - } - - /** - * Make a JSON text of this JSONArray. For compactness, no unnecessary - * whitespace is added. If it is not possible to produce a syntactically - * correct JSON text then null will be returned instead. This could occur if - * the array contains an invalid number. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return a printable, displayable, transmittable representation of the - * array. - */ - public String toString() { - try { - return this.toString(0); - } catch (Exception e) { - return null; - } - } - - /** - * Make a prettyprinted JSON text of this JSONArray. Warning: This method - * assumes that the data structure is acyclical. - * - * @param indentFactor - * The number of spaces to add to each level of indentation. - * @return a printable, displayable, transmittable representation of the - * object, beginning with [ (left - * bracket) and ending with ] - *  (right bracket). - * @throws JSONException - */ - public String toString(int indentFactor) throws JSONException { - StringWriter sw = new StringWriter(); - synchronized (sw.getBuffer()) { - return this.write(sw, indentFactor, 0).toString(); - } - } - - /** - * Write the contents of the JSONArray as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return The writer. - * @throws JSONException - */ - public Writer write(Writer writer) throws JSONException { - return this.write(writer, 0, 0); - } - - /** - * Write the contents of the JSONArray as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @param indentFactor - * The number of spaces to add to each level of indentation. - * @param indent - * The indention of the top level. - * @return The writer. - * @throws JSONException - */ - Writer write(Writer writer, int indentFactor, int indent) - throws JSONException { - try { - boolean commanate = false; - int length = this.length(); - writer.write('['); - - if (length == 1) { - JSONObject.writeValue(writer, this.myArrayList.get(0), - indentFactor, indent); - } else if (length != 0) { - final int newindent = indent + indentFactor; - - for (int i = 0; i < length; i += 1) { - if (commanate) { - writer.write(','); - } - if (indentFactor > 0) { - writer.write('\n'); - } - JSONObject.indent(writer, newindent); - JSONObject.writeValue(writer, this.myArrayList.get(i), - indentFactor, newindent); - commanate = true; - } - if (indentFactor > 0) { - writer.write('\n'); - } - JSONObject.indent(writer, indent); - } - writer.write(']'); - return writer; - } catch (IOException e) { - throw new JSONException(e); - } - } -} diff --git a/restx-build/src/main/java/restx/build/org/json/JSONException.java b/restx-build/src/main/java/restx/build/org/json/JSONException.java deleted file mode 100755 index 633ca7be1..000000000 --- a/restx-build/src/main/java/restx/build/org/json/JSONException.java +++ /dev/null @@ -1,41 +0,0 @@ -package restx.build.org.json; - -/** - * The JSONException is thrown by the JSON.org classes when things are amiss. - * - * @author JSON.org - * @version 2013-02-10 - */ -public class JSONException extends RuntimeException { - private static final long serialVersionUID = 0; - private Throwable cause; - - /** - * Constructs a JSONException with an explanatory message. - * - * @param message - * Detail about the reason for the exception. - */ - public JSONException(String message) { - super(message); - } - - /** - * Constructs a new JSONException with the specified cause. - */ - public JSONException(Throwable cause) { - super(cause.getMessage()); - this.cause = cause; - } - - /** - * Returns the cause of this exception or null if the cause is nonexistent - * or unknown. - * - * @return the cause of this exception or null if the cause is nonexistent - * or unknown. - */ - public Throwable getCause() { - return this.cause; - } -} diff --git a/restx-build/src/main/java/restx/build/org/json/JSONObject.java b/restx-build/src/main/java/restx/build/org/json/JSONObject.java deleted file mode 100755 index 27b24f7fc..000000000 --- a/restx-build/src/main/java/restx/build/org/json/JSONObject.java +++ /dev/null @@ -1,1622 +0,0 @@ -package restx.build.org.json; - -/* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.*; - -/** - * A JSONObject is an unordered collection of name/value pairs. Its external - * form is a string wrapped in curly braces with colons between the names and - * values, and commas between the values and names. The internal form is an - * object having get and opt methods for accessing the - * values by name, and put methods for adding or replacing values - * by name. The values can be any of these types: Boolean, - * JSONArray, JSONObject, Number, - * String, or the JSONObject.NULL object. A JSONObject - * constructor can be used to convert an external form JSON text into an - * internal form whose values can be retrieved with the get and - * opt methods, or to convert values into a JSON text using the - * put and toString methods. A get method - * returns a value if one can be found, and throws an exception if one cannot be - * found. An opt method returns a default value instead of throwing - * an exception, and so is useful for obtaining optional values. - *

- * The generic get() and opt() methods return an - * object, which you can cast or query for type. There are also typed - * get and opt methods that do type checking and type - * coercion for you. The opt methods differ from the get methods in that they do - * not throw. Instead, they return a specified value, such as null. - *

- * The put methods add or replace values in an object. For example, - * - *

- * myString = new JSONObject().put("JSON", "Hello, World!").toString();
- * 
- * - * produces the string {"JSON": "Hello, World"}. - *

- * The texts produced by the toString methods strictly conform to - * the JSON syntax rules. The constructors are more forgiving in the texts they - * will accept: - *

    - *
  • An extra , (comma) may appear just - * before the closing brace.
  • - *
  • Strings may be quoted with ' (single - * quote).
  • - *
  • Strings do not need to be quoted at all if they do not begin with a quote - * or single quote, and if they do not contain leading or trailing spaces, and - * if they do not contain any of these characters: - * { } [ ] / \ : , = ; # and if they do not look like numbers and - * if they are not the reserved words true, false, or - * null.
  • - *
  • Keys can be followed by = or => as well as by - * :.
  • - *
  • Values can be followed by ; (semicolon) as - * well as by , (comma).
  • - *
- * - * @author JSON.org - * @version 2012-12-01 - */ -@SuppressWarnings("unchecked") -public class JSONObject { - /** - * The maximum number of keys in the key pool. - */ - private static final int keyPoolSize = 100; - - /** - * Key pooling is like string interning, but without permanently tying up - * memory. To help conserve memory, storage of duplicated key strings in - * JSONObjects will be avoided by using a key pool to manage unique key - * string objects. This is used by JSONObject.put(string, object). - */ - private static HashMap keyPool = new HashMap(keyPoolSize); - - /** - * JSONObject.NULL is equivalent to the value that JavaScript calls null, - * whilst Java's null is equivalent to the value that JavaScript calls - * undefined. - */ - private static final class Null { - - /** - * There is only intended to be a single instance of the NULL object, - * so the clone method returns itself. - * @return NULL. - */ - protected final Object clone() { - return this; - } - - /** - * A Null object is equal to the null value and to itself. - * @param object An object to test for nullness. - * @return true if the object parameter is the JSONObject.NULL object - * or null. - */ - public boolean equals(Object object) { - return object == null || object == this; - } - - /** - * Get the "null" string value. - * @return The string "null". - */ - public String toString() { - return "null"; - } - } - - - /** - * The map where the JSONObject's properties are kept. - */ - private final Map map; - - - /** - * It is sometimes more convenient and less ambiguous to have a - * NULL object than to use Java's null value. - * JSONObject.NULL.equals(null) returns true. - * JSONObject.NULL.toString() returns "null". - */ - public static final Object NULL = new Null(); - - - /** - * Construct an empty JSONObject. - */ - public JSONObject() { - this.map = new LinkedHashMap(); - } - - - /** - * Construct a JSONObject from a subset of another JSONObject. - * An array of strings is used to identify the keys that should be copied. - * Missing keys are ignored. - * @param jo A JSONObject. - * @param names An array of strings. - * @throws JSONException - * @exception JSONException If a value is a non-finite number or if a name is duplicated. - */ - public JSONObject(JSONObject jo, String[] names) { - this(); - for (int i = 0; i < names.length; i += 1) { - try { - this.putOnce(names[i], jo.opt(names[i])); - } catch (Exception ignore) { - } - } - } - - - /** - * Construct a JSONObject from a JSONTokener. - * @param x A JSONTokener object containing the source string. - * @throws JSONException If there is a syntax error in the source string - * or a duplicated key. - */ - public JSONObject(JSONTokener x) throws JSONException { - this(); - char c; - String key; - - if (x.nextClean() != '{') { - throw x.syntaxError("A JSONObject text must begin with '{'"); - } - for (;;) { - c = x.nextClean(); - switch (c) { - case 0: - throw x.syntaxError("A JSONObject text must end with '}'"); - case '}': - return; - default: - x.back(); - key = x.nextValue().toString(); - } - -// The key is followed by ':'. We will also tolerate '=' or '=>'. - - c = x.nextClean(); - if (c == '=') { - if (x.next() != '>') { - x.back(); - } - } else if (c != ':') { - throw x.syntaxError("Expected a ':' after a key"); - } - this.putOnce(key, x.nextValue()); - -// Pairs are separated by ','. We will also tolerate ';'. - - switch (x.nextClean()) { - case ';': - case ',': - if (x.nextClean() == '}') { - return; - } - x.back(); - break; - case '}': - return; - default: - throw x.syntaxError("Expected a ',' or '}'"); - } - } - } - - - /** - * Construct a JSONObject from a Map. - * - * @param map A map object that can be used to initialize the contents of - * the JSONObject. - * @throws JSONException - */ - public JSONObject(Map map) { - this.map = new HashMap(); - if (map != null) { - Iterator i = map.entrySet().iterator(); - while (i.hasNext()) { - Map.Entry e = (Map.Entry)i.next(); - Object value = e.getValue(); - if (value != null) { - this.map.put(e.getKey(), wrap(value)); - } - } - } - } - - - /** - * Construct a JSONObject from an Object using bean getters. - * It reflects on all of the public methods of the object. - * For each of the methods with no parameters and a name starting - * with "get" or "is" followed by an uppercase letter, - * the method is invoked, and a key and the value returned from the getter method - * are put into the new JSONObject. - * - * The key is formed by removing the "get" or "is" prefix. - * If the second remaining character is not upper case, then the first - * character is converted to lower case. - * - * For example, if an object has a method named "getName", and - * if the result of calling object.getName() is "Larry Fine", - * then the JSONObject will contain "name": "Larry Fine". - * - * @param bean An object that has getter methods that should be used - * to make a JSONObject. - */ - public JSONObject(Object bean) { - this(); - this.populateMap(bean); - } - - - /** - * Construct a JSONObject from an Object, using reflection to find the - * public members. The resulting JSONObject's keys will be the strings - * from the names array, and the values will be the field values associated - * with those keys in the object. If a key is not found or not visible, - * then it will not be copied into the new JSONObject. - * @param object An object that has fields that should be used to make a - * JSONObject. - * @param names An array of strings, the names of the fields to be obtained - * from the object. - */ - public JSONObject(Object object, String names[]) { - this(); - Class c = object.getClass(); - for (int i = 0; i < names.length; i += 1) { - String name = names[i]; - try { - this.putOpt(name, c.getField(name).get(object)); - } catch (Exception ignore) { - } - } - } - - - /** - * Construct a JSONObject from a source JSON text string. - * This is the most commonly used JSONObject constructor. - * @param source A string beginning - * with { (left brace) and ending - * with } (right brace). - * @exception JSONException If there is a syntax error in the source - * string or a duplicated key. - */ - public JSONObject(String source) throws JSONException { - this(new JSONTokener(source)); - } - - - /** - * Construct a JSONObject from a ResourceBundle. - * @param baseName The ResourceBundle base name. - * @param locale The Locale to load the ResourceBundle for. - * @throws JSONException If any JSONExceptions are detected. - */ - public JSONObject(String baseName, Locale locale) throws JSONException { - this(); - ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale, - Thread.currentThread().getContextClassLoader()); - -// Iterate through the keys in the bundle. - - Enumeration keys = bundle.getKeys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - if (key instanceof String) { - -// Go through the path, ensuring that there is a nested JSONObject for each -// segment except the last. Add the value using the last segment's name into -// the deepest nested JSONObject. - - String[] path = ((String)key).split("\\."); - int last = path.length - 1; - JSONObject target = this; - for (int i = 0; i < last; i += 1) { - String segment = path[i]; - JSONObject nextTarget = target.optJSONObject(segment); - if (nextTarget == null) { - nextTarget = new JSONObject(); - target.put(segment, nextTarget); - } - target = nextTarget; - } - target.put(path[last], bundle.getString((String)key)); - } - } - } - - - /** - * Accumulate values under a key. It is similar to the put method except - * that if there is already an object stored under the key then a - * JSONArray is stored under the key to hold all of the accumulated values. - * If there is already a JSONArray, then the new value is appended to it. - * In contrast, the put method replaces the previous value. - * - * If only one value is accumulated that is not a JSONArray, then the - * result will be the same as using put. But if multiple values are - * accumulated, then the result will be like append. - * @param key A key string. - * @param value An object to be accumulated under the key. - * @return this. - * @throws JSONException If the value is an invalid number - * or if the key is null. - */ - public JSONObject accumulate( - String key, - Object value - ) throws JSONException { - testValidity(value); - Object object = this.opt(key); - if (object == null) { - this.put(key, value instanceof JSONArray - ? new JSONArray().put(value) - : value); - } else if (object instanceof JSONArray) { - ((JSONArray)object).put(value); - } else { - this.put(key, new JSONArray().put(object).put(value)); - } - return this; - } - - - /** - * Append values to the array under a key. If the key does not exist in the - * JSONObject, then the key is put in the JSONObject with its value being a - * JSONArray containing the value parameter. If the key was already - * associated with a JSONArray, then the value parameter is appended to it. - * @param key A key string. - * @param value An object to be accumulated under the key. - * @return this. - * @throws JSONException If the key is null or if the current value - * associated with the key is not a JSONArray. - */ - public JSONObject append(String key, Object value) throws JSONException { - testValidity(value); - Object object = this.opt(key); - if (object == null) { - this.put(key, new JSONArray().put(value)); - } else if (object instanceof JSONArray) { - this.put(key, ((JSONArray)object).put(value)); - } else { - throw new JSONException("JSONObject[" + key + - "] is not a JSONArray."); - } - return this; - } - - - /** - * Produce a string from a double. The string "null" will be returned if - * the number is not finite. - * @param d A double. - * @return A String. - */ - public static String doubleToString(double d) { - if (Double.isInfinite(d) || Double.isNaN(d)) { - return "null"; - } - -// Shave off trailing zeros and decimal point, if possible. - - String string = Double.toString(d); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && - string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; - } - - - /** - * Get the value object associated with a key. - * - * @param key A key string. - * @return The object associated with the key. - * @throws JSONException if the key is not found. - */ - public Object get(String key) throws JSONException { - if (key == null) { - throw new JSONException("Null key."); - } - Object object = this.opt(key); - if (object == null) { - throw new JSONException("JSONObject[" + quote(key) + - "] not found."); - } - return object; - } - - - /** - * Get the boolean value associated with a key. - * - * @param key A key string. - * @return The truth. - * @throws JSONException - * if the value is not a Boolean or the String "true" or "false". - */ - public boolean getBoolean(String key) throws JSONException { - Object object = this.get(key); - if (object.equals(Boolean.FALSE) || - (object instanceof String && - ((String)object).equalsIgnoreCase("false"))) { - return false; - } else if (object.equals(Boolean.TRUE) || - (object instanceof String && - ((String)object).equalsIgnoreCase("true"))) { - return true; - } - throw new JSONException("JSONObject[" + quote(key) + - "] is not a Boolean."); - } - - - /** - * Get the double value associated with a key. - * @param key A key string. - * @return The numeric value. - * @throws JSONException if the key is not found or - * if the value is not a Number object and cannot be converted to a number. - */ - public double getDouble(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number)object).doubleValue() - : Double.parseDouble((String)object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + - "] is not a number."); - } - } - - - /** - * Get the int value associated with a key. - * - * @param key A key string. - * @return The integer value. - * @throws JSONException if the key is not found or if the value cannot - * be converted to an integer. - */ - public int getInt(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number)object).intValue() - : Integer.parseInt((String)object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + - "] is not an int."); - } - } - - - /** - * Get the JSONArray value associated with a key. - * - * @param key A key string. - * @return A JSONArray which is the value. - * @throws JSONException if the key is not found or - * if the value is not a JSONArray. - */ - public JSONArray getJSONArray(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof JSONArray) { - return (JSONArray)object; - } - throw new JSONException("JSONObject[" + quote(key) + - "] is not a JSONArray."); - } - - - /** - * Get the JSONObject value associated with a key. - * - * @param key A key string. - * @return A JSONObject which is the value. - * @throws JSONException if the key is not found or - * if the value is not a JSONObject. - */ - public JSONObject getJSONObject(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof JSONObject) { - return (JSONObject)object; - } - throw new JSONException("JSONObject[" + quote(key) + - "] is not a JSONObject."); - } - - - /** - * Get the long value associated with a key. - * - * @param key A key string. - * @return The long value. - * @throws JSONException if the key is not found or if the value cannot - * be converted to a long. - */ - public long getLong(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number)object).longValue() - : Long.parseLong((String)object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + - "] is not a long."); - } - } - - - /** - * Get an array of field names from a JSONObject. - * - * @return An array of field names, or null if there are no names. - */ - public static String[] getNames(JSONObject jo) { - int length = jo.length(); - if (length == 0) { - return null; - } - Iterator iterator = jo.keys(); - String[] names = new String[length]; - int i = 0; - while (iterator.hasNext()) { - names[i] = (String)iterator.next(); - i += 1; - } - return names; - } - - - /** - * Get an array of field names from an Object. - * - * @return An array of field names, or null if there are no names. - */ - public static String[] getNames(Object object) { - if (object == null) { - return null; - } - Class klass = object.getClass(); - Field[] fields = klass.getFields(); - int length = fields.length; - if (length == 0) { - return null; - } - String[] names = new String[length]; - for (int i = 0; i < length; i += 1) { - names[i] = fields[i].getName(); - } - return names; - } - - - /** - * Get the string associated with a key. - * - * @param key A key string. - * @return A string which is the value. - * @throws JSONException if there is no string value for the key. - */ - public String getString(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof String) { - return (String)object; - } - throw new JSONException("JSONObject[" + quote(key) + - "] not a string."); - } - - - /** - * Determine if the JSONObject contains a specific key. - * @param key A key string. - * @return true if the key exists in the JSONObject. - */ - public boolean has(String key) { - return this.map.containsKey(key); - } - - - /** - * Increment a property of a JSONObject. If there is no such property, - * create one with a value of 1. If there is such a property, and if - * it is an Integer, Long, Double, or Float, then add one to it. - * @param key A key string. - * @return this. - * @throws JSONException If there is already a property with this name - * that is not an Integer, Long, Double, or Float. - */ - public JSONObject increment(String key) throws JSONException { - Object value = this.opt(key); - if (value == null) { - this.put(key, 1); - } else if (value instanceof Integer) { - this.put(key, ((Integer)value).intValue() + 1); - } else if (value instanceof Long) { - this.put(key, ((Long)value).longValue() + 1); - } else if (value instanceof Double) { - this.put(key, ((Double)value).doubleValue() + 1); - } else if (value instanceof Float) { - this.put(key, ((Float)value).floatValue() + 1); - } else { - throw new JSONException("Unable to increment [" + quote(key) + "]."); - } - return this; - } - - - /** - * Determine if the value associated with the key is null or if there is - * no value. - * @param key A key string. - * @return true if there is no value associated with the key or if - * the value is the JSONObject.NULL object. - */ - public boolean isNull(String key) { - return JSONObject.NULL.equals(this.opt(key)); - } - - - /** - * Get an enumeration of the keys of the JSONObject. - * - * @return An iterator of the keys. - */ - public Iterator keys() { - return this.keySet().iterator(); - } - - - /** - * Get a set of keys of the JSONObject. - * - * @return A keySet. - */ - public Set keySet() { - return this.map.keySet(); - } - - - /** - * Get the number of keys stored in the JSONObject. - * - * @return The number of keys in the JSONObject. - */ - public int length() { - return this.map.size(); - } - - - /** - * Produce a JSONArray containing the names of the elements of this - * JSONObject. - * @return A JSONArray containing the key strings, or null if the JSONObject - * is empty. - */ - public JSONArray names() { - JSONArray ja = new JSONArray(); - Iterator keys = this.keys(); - while (keys.hasNext()) { - ja.put(keys.next()); - } - return ja.length() == 0 ? null : ja; - } - - /** - * Produce a string from a Number. - * @param number A Number - * @return A String. - * @throws JSONException If n is a non-finite number. - */ - public static String numberToString(Number number) - throws JSONException { - if (number == null) { - throw new JSONException("Null pointer"); - } - testValidity(number); - -// Shave off trailing zeros and decimal point, if possible. - - String string = number.toString(); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && - string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; - } - - - /** - * Get an optional value associated with a key. - * @param key A key string. - * @return An object which is the value, or null if there is no value. - */ - public Object opt(String key) { - return key == null ? null : this.map.get(key); - } - - - /** - * Get an optional boolean associated with a key. - * It returns false if there is no such key, or if the value is not - * Boolean.TRUE or the String "true". - * - * @param key A key string. - * @return The truth. - */ - public boolean optBoolean(String key) { - return this.optBoolean(key, false); - } - - - /** - * Get an optional boolean associated with a key. - * It returns the defaultValue if there is no such key, or if it is not - * a Boolean or the String "true" or "false" (case insensitive). - * - * @param key A key string. - * @param defaultValue The default. - * @return The truth. - */ - public boolean optBoolean(String key, boolean defaultValue) { - try { - return this.getBoolean(key); - } catch (Exception e) { - return defaultValue; - } - } - - - /** - * Get an optional double associated with a key, - * or NaN if there is no such key or if its value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A string which is the key. - * @return An object which is the value. - */ - public double optDouble(String key) { - return this.optDouble(key, Double.NaN); - } - - - /** - * Get an optional double associated with a key, or the - * defaultValue if there is no such key or if its value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public double optDouble(String key, double defaultValue) { - try { - return this.getDouble(key); - } catch (Exception e) { - return defaultValue; - } - } - - - /** - * Get an optional int value associated with a key, - * or zero if there is no such key or if the value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A key string. - * @return An object which is the value. - */ - public int optInt(String key) { - return this.optInt(key, 0); - } - - - /** - * Get an optional int value associated with a key, - * or the default if there is no such key or if the value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public int optInt(String key, int defaultValue) { - try { - return this.getInt(key); - } catch (Exception e) { - return defaultValue; - } - } - - - /** - * Get an optional JSONArray associated with a key. - * It returns null if there is no such key, or if its value is not a - * JSONArray. - * - * @param key A key string. - * @return A JSONArray which is the value. - */ - public JSONArray optJSONArray(String key) { - Object o = this.opt(key); - return o instanceof JSONArray ? (JSONArray)o : null; - } - - - /** - * Get an optional JSONObject associated with a key. - * It returns null if there is no such key, or if its value is not a - * JSONObject. - * - * @param key A key string. - * @return A JSONObject which is the value. - */ - public JSONObject optJSONObject(String key) { - Object object = this.opt(key); - return object instanceof JSONObject ? (JSONObject)object : null; - } - - - /** - * Get an optional long value associated with a key, - * or zero if there is no such key or if the value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A key string. - * @return An object which is the value. - */ - public long optLong(String key) { - return this.optLong(key, 0); - } - - - /** - * Get an optional long value associated with a key, - * or the default if there is no such key or if the value is not a number. - * If the value is a string, an attempt will be made to evaluate it as - * a number. - * - * @param key A key string. - * @param defaultValue The default. - * @return An object which is the value. - */ - public long optLong(String key, long defaultValue) { - try { - return this.getLong(key); - } catch (Exception e) { - return defaultValue; - } - } - - - /** - * Get an optional string associated with a key. - * It returns an empty string if there is no such key. If the value is not - * a string and is not null, then it is converted to a string. - * - * @param key A key string. - * @return A string which is the value. - */ - public String optString(String key) { - return this.optString(key, ""); - } - - - /** - * Get an optional string associated with a key. - * It returns the defaultValue if there is no such key. - * - * @param key A key string. - * @param defaultValue The default. - * @return A string which is the value. - */ - public String optString(String key, String defaultValue) { - Object object = this.opt(key); - return NULL.equals(object) ? defaultValue : object.toString(); - } - - - private void populateMap(Object bean) { - Class klass = bean.getClass(); - -// If klass is a System class then set includeSuperClass to false. - - boolean includeSuperClass = klass.getClassLoader() != null; - - Method[] methods = includeSuperClass - ? klass.getMethods() - : klass.getDeclaredMethods(); - for (int i = 0; i < methods.length; i += 1) { - try { - Method method = methods[i]; - if (Modifier.isPublic(method.getModifiers())) { - String name = method.getName(); - String key = ""; - if (name.startsWith("get")) { - if ("getClass".equals(name) || - "getDeclaringClass".equals(name)) { - key = ""; - } else { - key = name.substring(3); - } - } else if (name.startsWith("is")) { - key = name.substring(2); - } - if (key.length() > 0 && - Character.isUpperCase(key.charAt(0)) && - method.getParameterTypes().length == 0) { - if (key.length() == 1) { - key = key.toLowerCase(); - } else if (!Character.isUpperCase(key.charAt(1))) { - key = key.substring(0, 1).toLowerCase() + - key.substring(1); - } - - Object result = method.invoke(bean, (Object[])null); - if (result != null) { - this.map.put(key, wrap(result)); - } - } - } - } catch (Exception ignore) { - } - } - } - - - /** - * Put a key/boolean pair in the JSONObject. - * - * @param key A key string. - * @param value A boolean which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, boolean value) throws JSONException { - this.put(key, value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - - /** - * Put a key/value pair in the JSONObject, where the value will be a - * JSONArray which is produced from a Collection. - * @param key A key string. - * @param value A Collection value. - * @return this. - * @throws JSONException - */ - public JSONObject put(String key, Collection value) throws JSONException { - this.put(key, new JSONArray(value)); - return this; - } - - - /** - * Put a key/double pair in the JSONObject. - * - * @param key A key string. - * @param value A double which is the value. - * @return this. - * @throws JSONException If the key is null or if the number is invalid. - */ - public JSONObject put(String key, double value) throws JSONException { - this.put(key, new Double(value)); - return this; - } - - - /** - * Put a key/int pair in the JSONObject. - * - * @param key A key string. - * @param value An int which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, int value) throws JSONException { - this.put(key, new Integer(value)); - return this; - } - - - /** - * Put a key/long pair in the JSONObject. - * - * @param key A key string. - * @param value A long which is the value. - * @return this. - * @throws JSONException If the key is null. - */ - public JSONObject put(String key, long value) throws JSONException { - this.put(key, new Long(value)); - return this; - } - - - /** - * Put a key/value pair in the JSONObject, where the value will be a - * JSONObject which is produced from a Map. - * @param key A key string. - * @param value A Map value. - * @return this. - * @throws JSONException - */ - public JSONObject put(String key, Map value) throws JSONException { - this.put(key, new JSONObject(value)); - return this; - } - - - /** - * Put a key/value pair in the JSONObject. If the value is null, - * then the key will be removed from the JSONObject if it is present. - * @param key A key string. - * @param value An object which is the value. It should be of one of these - * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, - * or the JSONObject.NULL object. - * @return this. - * @throws JSONException If the value is non-finite number - * or if the key is null. - */ - public JSONObject put(String key, Object value) throws JSONException { - String pooled; - if (key == null) { - throw new JSONException("Null key."); - } - if (value != null) { - testValidity(value); - pooled = (String)keyPool.get(key); - if (pooled == null) { - if (keyPool.size() >= keyPoolSize) { - keyPool = new HashMap(keyPoolSize); - } - keyPool.put(key, key); - } else { - key = pooled; - } - this.map.put(key, value); - } else { - this.remove(key); - } - return this; - } - - - /** - * Put a key/value pair in the JSONObject, but only if the key and the - * value are both non-null, and only if there is not already a member - * with that name. - * @param key - * @param value - * @return his. - * @throws JSONException if the key is a duplicate - */ - public JSONObject putOnce(String key, Object value) throws JSONException { - if (key != null && value != null) { - if (this.opt(key) != null) { - throw new JSONException("Duplicate key \"" + key + "\""); - } - this.put(key, value); - } - return this; - } - - - /** - * Put a key/value pair in the JSONObject, but only if the - * key and the value are both non-null. - * @param key A key string. - * @param value An object which is the value. It should be of one of these - * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, - * or the JSONObject.NULL object. - * @return this. - * @throws JSONException If the value is a non-finite number. - */ - public JSONObject putOpt(String key, Object value) throws JSONException { - if (key != null && value != null) { - this.put(key, value); - } - return this; - } - - - /** - * Produce a string in double quotes with backslash sequences in all the - * right places. A backslash will be inserted within </, producing <\/, - * allowing JSON text to be delivered in HTML. In JSON text, a string - * cannot contain a control character or an unescaped quote or backslash. - * @param string A String - * @return A String correctly formatted for insertion in a JSON text. - */ - public static String quote(String string) { - StringWriter sw = new StringWriter(); - synchronized (sw.getBuffer()) { - try { - return quote(string, sw).toString(); - } catch (IOException ignored) { - // will never happen - we are writing to a string writer - return ""; - } - } - } - - public static Writer quote(String string, Writer w) throws IOException { - if (string == null || string.length() == 0) { - w.write("\"\""); - return w; - } - - char b; - char c = 0; - String hhhh; - int i; - int len = string.length(); - - w.write('"'); - for (i = 0; i < len; i += 1) { - b = c; - c = string.charAt(i); - switch (c) { - case '\\': - case '"': - w.write('\\'); - w.write(c); - break; - case '/': - if (b == '<') { - w.write('\\'); - } - w.write(c); - break; - case '\b': - w.write("\\b"); - break; - case '\t': - w.write("\\t"); - break; - case '\n': - w.write("\\n"); - break; - case '\f': - w.write("\\f"); - break; - case '\r': - w.write("\\r"); - break; - default: - if (c < ' ' || (c >= '\u0080' && c < '\u00a0') - || (c >= '\u2000' && c < '\u2100')) { - w.write("\\u"); - hhhh = Integer.toHexString(c); - w.write("0000", 0, 4 - hhhh.length()); - w.write(hhhh); - } else { - w.write(c); - } - } - } - w.write('"'); - return w; - } - - /** - * Remove a name and its value, if present. - * @param key The name to be removed. - * @return The value that was associated with the name, - * or null if there was no value. - */ - public Object remove(String key) { - return this.map.remove(key); - } - - /** - * Try to convert a string into a number, boolean, or null. If the string - * can't be converted, return the string. - * @param string A String. - * @return A simple JSON value. - */ - public static Object stringToValue(String string) { - Double d; - if (string.equals("")) { - return string; - } - if (string.equalsIgnoreCase("true")) { - return Boolean.TRUE; - } - if (string.equalsIgnoreCase("false")) { - return Boolean.FALSE; - } - if (string.equalsIgnoreCase("null")) { - return JSONObject.NULL; - } - - /* - * If it might be a number, try converting it. - * If a number cannot be produced, then the value will just - * be a string. Note that the plus and implied string - * conventions are non-standard. A JSON parser may accept - * non-JSON forms as long as it accepts all correct JSON forms. - */ - - char b = string.charAt(0); - if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') { - try { - if (string.indexOf('.') > -1 || - string.indexOf('e') > -1 || string.indexOf('E') > -1) { - d = Double.valueOf(string); - if (!d.isInfinite() && !d.isNaN()) { - return d; - } - } else { - Long myLong = new Long(string); - if (myLong.longValue() == myLong.intValue()) { - return new Integer(myLong.intValue()); - } else { - return myLong; - } - } - } catch (Exception ignore) { - } - } - return string; - } - - - /** - * Throw an exception if the object is a NaN or infinite number. - * @param o The object to test. - * @throws JSONException If o is a non-finite number. - */ - public static void testValidity(Object o) throws JSONException { - if (o != null) { - if (o instanceof Double) { - if (((Double)o).isInfinite() || ((Double)o).isNaN()) { - throw new JSONException( - "JSON does not allow non-finite numbers."); - } - } else if (o instanceof Float) { - if (((Float)o).isInfinite() || ((Float)o).isNaN()) { - throw new JSONException( - "JSON does not allow non-finite numbers."); - } - } - } - } - - - /** - * Produce a JSONArray containing the values of the members of this - * JSONObject. - * @param names A JSONArray containing a list of key strings. This - * determines the sequence of the values in the result. - * @return A JSONArray of values. - * @throws JSONException If any of the values are non-finite numbers. - */ - public JSONArray toJSONArray(JSONArray names) throws JSONException { - if (names == null || names.length() == 0) { - return null; - } - JSONArray ja = new JSONArray(); - for (int i = 0; i < names.length(); i += 1) { - ja.put(this.opt(names.getString(i))); - } - return ja; - } - - /** - * Make a JSON text of this JSONObject. For compactness, no whitespace - * is added. If this would not result in a syntactically correct JSON text, - * then null will be returned instead. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return a printable, displayable, portable, transmittable - * representation of the object, beginning - * with { (left brace) and ending - * with } (right brace). - */ - public String toString() { - try { - return this.toString(0); - } catch (Exception e) { - return null; - } - } - - - /** - * Make a prettyprinted JSON text of this JSONObject. - *

- * Warning: This method assumes that the data structure is acyclical. - * @param indentFactor The number of spaces to add to each level of - * indentation. - * @return a printable, displayable, portable, transmittable - * representation of the object, beginning - * with { (left brace) and ending - * with } (right brace). - * @throws JSONException If the object contains an invalid number. - */ - public String toString(int indentFactor) throws JSONException { - StringWriter w = new StringWriter(); - synchronized (w.getBuffer()) { - return this.write(w, indentFactor, 0).toString(); - } - } - - /** - * Make a JSON text of an Object value. If the object has an - * value.toJSONString() method, then that method will be used to produce - * the JSON text. The method is required to produce a strictly - * conforming text. If the object does not contain a toJSONString - * method (which is the most common case), then a text will be - * produced by other means. If the value is an array or Collection, - * then a JSONArray will be made from it and its toJSONString method - * will be called. If the value is a MAP, then a JSONObject will be made - * from it and its toJSONString method will be called. Otherwise, the - * value's toString method will be called, and the result will be quoted. - * - *

- * Warning: This method assumes that the data structure is acyclical. - * @param value The value to be serialized. - * @return a printable, displayable, transmittable - * representation of the object, beginning - * with { (left brace) and ending - * with } (right brace). - * @throws JSONException If the value is or contains an invalid number. - */ - public static String valueToString(Object value) throws JSONException { - if (value == null || value.equals(null)) { - return "null"; - } - if (value instanceof JSONString) { - Object object; - try { - object = ((JSONString)value).toJSONString(); - } catch (Exception e) { - throw new JSONException(e); - } - if (object instanceof String) { - return (String)object; - } - throw new JSONException("Bad value from toJSONString: " + object); - } - if (value instanceof Number) { - return numberToString((Number) value); - } - if (value instanceof Boolean || value instanceof JSONObject || - value instanceof JSONArray) { - return value.toString(); - } - if (value instanceof Map) { - return new JSONObject((Map)value).toString(); - } - if (value instanceof Collection) { - return new JSONArray((Collection)value).toString(); - } - if (value.getClass().isArray()) { - return new JSONArray(value).toString(); - } - return quote(value.toString()); - } - - /** - * Wrap an object, if necessary. If the object is null, return the NULL - * object. If it is an array or collection, wrap it in a JSONArray. If - * it is a map, wrap it in a JSONObject. If it is a standard property - * (Double, String, et al) then it is already wrapped. Otherwise, if it - * comes from one of the java packages, turn it into a string. And if - * it doesn't, try to wrap it in a JSONObject. If the wrapping fails, - * then null is returned. - * - * @param object The object to wrap - * @return The wrapped value - */ - public static Object wrap(Object object) { - try { - if (object == null) { - return NULL; - } - if (object instanceof JSONObject || object instanceof JSONArray || - NULL.equals(object) || object instanceof JSONString || - object instanceof Byte || object instanceof Character || - object instanceof Short || object instanceof Integer || - object instanceof Long || object instanceof Boolean || - object instanceof Float || object instanceof Double || - object instanceof String) { - return object; - } - - if (object instanceof Collection) { - return new JSONArray((Collection)object); - } - if (object.getClass().isArray()) { - return new JSONArray(object); - } - if (object instanceof Map) { - return new JSONObject((Map)object); - } - Package objectPackage = object.getClass().getPackage(); - String objectPackageName = objectPackage != null - ? objectPackage.getName() - : ""; - if ( - objectPackageName.startsWith("java.") || - objectPackageName.startsWith("javax.") || - object.getClass().getClassLoader() == null - ) { - return object.toString(); - } - return new JSONObject(object); - } catch(Exception exception) { - return null; - } - } - - - /** - * Write the contents of the JSONObject as JSON text to a writer. - * For compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return The writer. - * @throws JSONException - */ - public Writer write(Writer writer) throws JSONException { - return this.write(writer, 0, 0); - } - - - static final Writer writeValue(Writer writer, Object value, - int indentFactor, int indent) throws JSONException, IOException { - if (value == null || value.equals(null)) { - writer.write("null"); - } else if (value instanceof JSONObject) { - ((JSONObject) value).write(writer, indentFactor, indent); - } else if (value instanceof JSONArray) { - ((JSONArray) value).write(writer, indentFactor, indent); - } else if (value instanceof Map) { - new JSONObject((Map) value).write(writer, indentFactor, indent); - } else if (value instanceof Collection) { - new JSONArray((Collection) value).write(writer, indentFactor, - indent); - } else if (value.getClass().isArray()) { - new JSONArray(value).write(writer, indentFactor, indent); - } else if (value instanceof Number) { - writer.write(numberToString((Number) value)); - } else if (value instanceof Boolean) { - writer.write(value.toString()); - } else if (value instanceof JSONString) { - Object o; - try { - o = ((JSONString) value).toJSONString(); - } catch (Exception e) { - throw new JSONException(e); - } - writer.write(o != null ? o.toString() : quote(value.toString())); - } else { - quote(value.toString(), writer); - } - return writer; - } - - static final void indent(Writer writer, int indent) throws IOException { - for (int i = 0; i < indent; i += 1) { - writer.write(' '); - } - } - - /** - * Write the contents of the JSONObject as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return The writer. - * @throws JSONException - */ - Writer write(Writer writer, int indentFactor, int indent) - throws JSONException { - try { - boolean commanate = false; - final int length = this.length(); - Iterator keys = this.keys(); - writer.write('{'); - - if (length == 1) { - Object key = keys.next(); - writer.write(quote(key.toString())); - writer.write(':'); - if (indentFactor > 0) { - writer.write(' '); - } - writeValue(writer, this.map.get(key), indentFactor, indent); - } else if (length != 0) { - final int newindent = indent + indentFactor; - while (keys.hasNext()) { - Object key = keys.next(); - if (commanate) { - writer.write(','); - } - if (indentFactor > 0) { - writer.write('\n'); - } - indent(writer, newindent); - writer.write(quote(key.toString())); - writer.write(':'); - if (indentFactor > 0) { - writer.write(' '); - } - writeValue(writer, this.map.get(key), indentFactor, - newindent); - commanate = true; - } - if (indentFactor > 0) { - writer.write('\n'); - } - indent(writer, indent); - } - writer.write('}'); - return writer; - } catch (IOException exception) { - throw new JSONException(exception); - } - } -} diff --git a/restx-build/src/main/java/restx/build/org/json/JSONString.java b/restx-build/src/main/java/restx/build/org/json/JSONString.java deleted file mode 100755 index ae2151d81..000000000 --- a/restx-build/src/main/java/restx/build/org/json/JSONString.java +++ /dev/null @@ -1,18 +0,0 @@ -package restx.build.org.json; -/** - * The JSONString interface allows a toJSONString() - * method so that a class can change the behavior of - * JSONObject.toString(), JSONArray.toString(), - * and JSONWriter.value(Object). The - * toJSONString method will be used instead of the default behavior - * of using the Object's toString() method and quoting the result. - */ -public interface JSONString { - /** - * The toJSONString method allows a class to produce its own JSON - * serialization. - * - * @return A strictly syntactically correct JSON text. - */ - public String toJSONString(); -} diff --git a/restx-build/src/main/java/restx/build/org/json/JSONTokener.java b/restx-build/src/main/java/restx/build/org/json/JSONTokener.java deleted file mode 100644 index 15bf5d8f0..000000000 --- a/restx-build/src/main/java/restx/build/org/json/JSONTokener.java +++ /dev/null @@ -1,446 +0,0 @@ -package restx.build.org.json; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; - -/* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -/** - * A JSONTokener takes a source string and extracts characters and tokens from - * it. It is used by the JSONObject and JSONArray constructors to parse - * JSON source strings. - * @author JSON.org - * @version 2012-02-16 - */ -public class JSONTokener { - - private long character; - private boolean eof; - private long index; - private long line; - private char previous; - private Reader reader; - private boolean usePrevious; - - - /** - * Construct a JSONTokener from a Reader. - * - * @param reader A reader. - */ - public JSONTokener(Reader reader) { - this.reader = reader.markSupported() - ? reader - : new BufferedReader(reader); - this.eof = false; - this.usePrevious = false; - this.previous = 0; - this.index = 0; - this.character = 1; - this.line = 1; - } - - - /** - * Construct a JSONTokener from an InputStream. - */ - public JSONTokener(InputStream inputStream) throws JSONException { - this(new InputStreamReader(inputStream)); - } - - - /** - * Construct a JSONTokener from a string. - * - * @param s A source string. - */ - public JSONTokener(String s) { - this(new StringReader(s)); - } - - - /** - * Back up one character. This provides a sort of lookahead capability, - * so that you can test for a digit or letter before attempting to parse - * the next number or identifier. - */ - public void back() throws JSONException { - if (this.usePrevious || this.index <= 0) { - throw new JSONException("Stepping back two steps is not supported"); - } - this.index -= 1; - this.character -= 1; - this.usePrevious = true; - this.eof = false; - } - - - /** - * Get the hex value of a character (base16). - * @param c A character between '0' and '9' or between 'A' and 'F' or - * between 'a' and 'f'. - * @return An int between 0 and 15, or -1 if c was not a hex digit. - */ - public static int dehexchar(char c) { - if (c >= '0' && c <= '9') { - return c - '0'; - } - if (c >= 'A' && c <= 'F') { - return c - ('A' - 10); - } - if (c >= 'a' && c <= 'f') { - return c - ('a' - 10); - } - return -1; - } - - public boolean end() { - return this.eof && !this.usePrevious; - } - - - /** - * Determine if the source string still contains characters that next() - * can consume. - * @return true if not yet at the end of the source. - */ - public boolean more() throws JSONException { - this.next(); - if (this.end()) { - return false; - } - this.back(); - return true; - } - - - /** - * Get the next character in the source string. - * - * @return The next character, or 0 if past the end of the source string. - */ - public char next() throws JSONException { - int c; - if (this.usePrevious) { - this.usePrevious = false; - c = this.previous; - } else { - try { - c = this.reader.read(); - } catch (IOException exception) { - throw new JSONException(exception); - } - - if (c <= 0) { // End of stream - this.eof = true; - c = 0; - } - } - this.index += 1; - if (this.previous == '\r') { - this.line += 1; - this.character = c == '\n' ? 0 : 1; - } else if (c == '\n') { - this.line += 1; - this.character = 0; - } else { - this.character += 1; - } - this.previous = (char) c; - return this.previous; - } - - - /** - * Consume the next character, and check that it matches a specified - * character. - * @param c The character to match. - * @return The character. - * @throws JSONException if the character does not match. - */ - public char next(char c) throws JSONException { - char n = this.next(); - if (n != c) { - throw this.syntaxError("Expected '" + c + "' and instead saw '" + - n + "'"); - } - return n; - } - - - /** - * Get the next n characters. - * - * @param n The number of characters to take. - * @return A string of n characters. - * @throws JSONException - * Substring bounds error if there are not - * n characters remaining in the source string. - */ - public String next(int n) throws JSONException { - if (n == 0) { - return ""; - } - - char[] chars = new char[n]; - int pos = 0; - - while (pos < n) { - chars[pos] = this.next(); - if (this.end()) { - throw this.syntaxError("Substring bounds error"); - } - pos += 1; - } - return new String(chars); - } - - - /** - * Get the next char in the string, skipping whitespace. - * @throws JSONException - * @return A character, or 0 if there are no more characters. - */ - public char nextClean() throws JSONException { - for (;;) { - char c = this.next(); - if (c == 0 || c > ' ') { - return c; - } - } - } - - - /** - * Return the characters up to the next close quote character. - * Backslash processing is done. The formal JSON format does not - * allow strings in single quotes, but an implementation is allowed to - * accept them. - * @param quote The quoting character, either - * " (double quote) or - * ' (single quote). - * @return A String. - * @throws JSONException Unterminated string. - */ - public String nextString(char quote) throws JSONException { - char c; - StringBuffer sb = new StringBuffer(); - for (;;) { - c = this.next(); - switch (c) { - case 0: - case '\n': - case '\r': - throw this.syntaxError("Unterminated string"); - case '\\': - c = this.next(); - switch (c) { - case 'b': - sb.append('\b'); - break; - case 't': - sb.append('\t'); - break; - case 'n': - sb.append('\n'); - break; - case 'f': - sb.append('\f'); - break; - case 'r': - sb.append('\r'); - break; - case 'u': - sb.append((char)Integer.parseInt(this.next(4), 16)); - break; - case '"': - case '\'': - case '\\': - case '/': - sb.append(c); - break; - default: - throw this.syntaxError("Illegal escape."); - } - break; - default: - if (c == quote) { - return sb.toString(); - } - sb.append(c); - } - } - } - - - /** - * Get the text up but not including the specified character or the - * end of line, whichever comes first. - * @param delimiter A delimiter character. - * @return A string. - */ - public String nextTo(char delimiter) throws JSONException { - StringBuffer sb = new StringBuffer(); - for (;;) { - char c = this.next(); - if (c == delimiter || c == 0 || c == '\n' || c == '\r') { - if (c != 0) { - this.back(); - } - return sb.toString().trim(); - } - sb.append(c); - } - } - - - /** - * Get the text up but not including one of the specified delimiter - * characters or the end of line, whichever comes first. - * @param delimiters A set of delimiter characters. - * @return A string, trimmed. - */ - public String nextTo(String delimiters) throws JSONException { - char c; - StringBuffer sb = new StringBuffer(); - for (;;) { - c = this.next(); - if (delimiters.indexOf(c) >= 0 || c == 0 || - c == '\n' || c == '\r') { - if (c != 0) { - this.back(); - } - return sb.toString().trim(); - } - sb.append(c); - } - } - - - /** - * Get the next value. The value can be a Boolean, Double, Integer, - * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. - * @throws JSONException If syntax error. - * - * @return An object. - */ - public Object nextValue() throws JSONException { - char c = this.nextClean(); - String string; - - switch (c) { - case '"': - case '\'': - return this.nextString(c); - case '{': - this.back(); - return new JSONObject(this); - case '[': - this.back(); - return new JSONArray(this); - } - - /* - * Handle unquoted text. This could be the values true, false, or - * null, or it can be a number. An implementation (such as this one) - * is allowed to also accept non-standard forms. - * - * Accumulate characters until we reach the end of the text or a - * formatting character. - */ - - StringBuffer sb = new StringBuffer(); - while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { - sb.append(c); - c = this.next(); - } - this.back(); - - string = sb.toString().trim(); - if ("".equals(string)) { - throw this.syntaxError("Missing value"); - } - return JSONObject.stringToValue(string); - } - - - /** - * Skip characters until the next character is the requested character. - * If the requested character is not found, no characters are skipped. - * @param to A character to skip to. - * @return The requested character, or zero if the requested character - * is not found. - */ - public char skipTo(char to) throws JSONException { - char c; - try { - long startIndex = this.index; - long startCharacter = this.character; - long startLine = this.line; - this.reader.mark(1000000); - do { - c = this.next(); - if (c == 0) { - this.reader.reset(); - this.index = startIndex; - this.character = startCharacter; - this.line = startLine; - return c; - } - } while (c != to); - } catch (IOException exc) { - throw new JSONException(exc); - } - - this.back(); - return c; - } - - - /** - * Make a JSONException to signal a syntax error. - * - * @param message The error message. - * @return A JSONException object, suitable for throwing - */ - public JSONException syntaxError(String message) { - return new JSONException(message + this.toString()); - } - - - /** - * Make a printable string of this JSONTokener. - * - * @return " at {index} [character {character} line {line}]" - */ - public String toString() { - return " at " + this.index + " [character " + this.character + " line " + - this.line + "]"; - } -} diff --git a/restx-build/src/main/java/restx/build/org/json/None.java b/restx-build/src/main/java/restx/build/org/json/None.java deleted file mode 100644 index 33bcd28f7..000000000 --- a/restx-build/src/main/java/restx/build/org/json/None.java +++ /dev/null @@ -1,9 +0,0 @@ -package restx.build.org.json; - -public interface None { - /** - * Negative One - */ - public static final int none = -1; - -} diff --git a/restx-build/src/main/java/restx/build/org/json/README b/restx-build/src/main/java/restx/build/org/json/README deleted file mode 100755 index b77c71a21..000000000 --- a/restx-build/src/main/java/restx/build/org/json/README +++ /dev/null @@ -1,68 +0,0 @@ -JSON in Java [package org.json] - -Douglas Crockford -douglas@crockford.com - -2011-02-02 - - -JSON is a light-weight, language independent, data interchange format. -See http://www.JSON.org/ - -The files in this package implement JSON encoders/decoders in Java. -It also includes the capability to convert between JSON and XML, HTTP -headers, Cookies, and CDL. - -This is a reference implementation. There is a large number of JSON packages -in Java. Perhaps someday the Java community will standardize on one. Until -then, choose carefully. - -The license includes this restriction: "The software shall be used for good, -not evil." If your conscience cannot live with that, then choose a different -package. - -The package compiles on Java 1.2 thru Java 1.4. - - -JSONObject.java: The JSONObject can parse text from a String or a JSONTokener -to produce a map-like object. The object provides methods for manipulating its -contents, and for producing a JSON compliant object serialization. - -JSONArray.java: The JSONObject can parse text from a String or a JSONTokener -to produce a vector-like object. The object provides methods for manipulating -its contents, and for producing a JSON compliant array serialization. - -JSONTokener.java: The JSONTokener breaks a text into a sequence of individual -tokens. It can be constructed from a String, Reader, or InputStream. - -JSONException.java: The JSONException is the standard exception type thrown -by this package. - - -JSONString.java: The JSONString interface requires a toJSONString method, -allowing an object to provide its own serialization. - -JSONStringer.java: The JSONStringer provides a convenient facility for -building JSON strings. - -JSONWriter.java: The JSONWriter provides a convenient facility for building -JSON text through a writer. - - -CDL.java: CDL provides support for converting between JSON and comma -delimited lists. - -Cookie.java: Cookie provides support for converting between JSON and cookies. - -CookieList.java: CookieList provides support for converting between JSON and -cookie lists. - -HTTP.java: HTTP provides support for converting between JSON and HTTP headers. - -HTTPTokener.java: HTTPTokener extends JSONTokener for parsing HTTP headers. - -XML.java: XML provides support for converting between JSON and XML. - -JSONML.java: JSONML provides support for converting between JSONML and XML. - -XMLTokener.java: XMLTokener extends JSONTokener for parsing XML text. diff --git a/restx-build/src/main/java/restx/build/org/json/XML.java b/restx-build/src/main/java/restx/build/org/json/XML.java deleted file mode 100755 index 226ba5f29..000000000 --- a/restx-build/src/main/java/restx/build/org/json/XML.java +++ /dev/null @@ -1,508 +0,0 @@ -package restx.build.org.json; - -/* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -import java.util.Iterator; - - -/** - * This provides static methods to convert an XML text into a JSONObject, - * and to covert a JSONObject into an XML text. - * @author JSON.org - * @version 2012-10-26 - */ -public class XML { - - /** The Character '&'. */ - public static final Character AMP = new Character('&'); - - /** The Character '''. */ - public static final Character APOS = new Character('\''); - - /** The Character '!'. */ - public static final Character BANG = new Character('!'); - - /** The Character '='. */ - public static final Character EQ = new Character('='); - - /** The Character '>'. */ - public static final Character GT = new Character('>'); - - /** The Character '<'. */ - public static final Character LT = new Character('<'); - - /** The Character '?'. */ - public static final Character QUEST = new Character('?'); - - /** The Character '"'. */ - public static final Character QUOT = new Character('"'); - - /** The Character '/'. */ - public static final Character SLASH = new Character('/'); - - /** - * Replace special characters with XML escapes: - *

-     * & (ampersand) is replaced by &amp;
-     * < (less than) is replaced by &lt;
-     * > (greater than) is replaced by &gt;
-     * " (double quote) is replaced by &quot;
-     * 
- * @param string The string to be escaped. - * @return The escaped string. - */ - public static String escape(String string) { - StringBuffer sb = new StringBuffer(); - for (int i = 0, length = string.length(); i < length; i++) { - char c = string.charAt(i); - switch (c) { - case '&': - sb.append("&"); - break; - case '<': - sb.append("<"); - break; - case '>': - sb.append(">"); - break; - case '"': - sb.append("""); - break; - case '\'': - sb.append("'"); - break; - default: - sb.append(c); - } - } - return sb.toString(); - } - - /** - * Throw an exception if the string contains whitespace. - * Whitespace is not allowed in tagNames and attributes. - * @param string - * @throws JSONException - */ - public static void noSpace(String string) throws JSONException { - int i, length = string.length(); - if (length == 0) { - throw new JSONException("Empty string."); - } - for (i = 0; i < length; i += 1) { - if (Character.isWhitespace(string.charAt(i))) { - throw new JSONException("'" + string + - "' contains a space character."); - } - } - } - - /** - * Scan the content following the named tag, attaching it to the context. - * @param x The XMLTokener containing the source string. - * @param context The JSONObject that will include the new material. - * @param name The tag name. - * @return true if the close tag is processed. - * @throws JSONException - */ - private static boolean parse(XMLTokener x, JSONObject context, - String name) throws JSONException { - char c; - int i; - JSONObject jsonobject = null; - String string; - String tagName; - Object token; - -// Test for and skip past these forms: -// -// -// -// -// Report errors for these forms: -// <> -// <= -// << - - token = x.nextToken(); - -// "); - return false; - } - x.back(); - } else if (c == '[') { - token = x.nextToken(); - if ("CDATA".equals(token)) { - if (x.next() == '[') { - string = x.nextCDATA(); - if (string.length() > 0) { - context.accumulate("content", string); - } - return false; - } - } - throw x.syntaxError("Expected 'CDATA['"); - } - i = 1; - do { - token = x.nextMeta(); - if (token == null) { - throw x.syntaxError("Missing '>' after ' 0); - return false; - } else if (token == QUEST) { - -// "); - return false; - } else if (token == SLASH) { - -// Close tag - - } else if (token == SLASH) { - if (x.nextToken() != GT) { - throw x.syntaxError("Misshaped tag"); - } - if (jsonobject.length() > 0) { - context.accumulate(tagName, jsonobject); - } else { - context.accumulate(tagName, ""); - } - return false; - -// Content, between <...> and - - } else if (token == GT) { - for (;;) { - token = x.nextContent(); - if (token == null) { - if (tagName != null) { - throw x.syntaxError("Unclosed tag " + tagName); - } - return false; - } else if (token instanceof String) { - string = (String)token; - if (string.length() > 0) { - jsonobject.accumulate("content", - XML.stringToValue(string)); - } - -// Nested element - - } else if (token == LT) { - if (parse(x, jsonobject, tagName)) { - if (jsonobject.length() == 0) { - context.accumulate(tagName, ""); - } else if (jsonobject.length() == 1 && - jsonobject.opt("content") != null) { - context.accumulate(tagName, - jsonobject.opt("content")); - } else { - context.accumulate(tagName, jsonobject); - } - return false; - } - } - } - } else { - throw x.syntaxError("Misshaped tag"); - } - } - } - } - - - /** - * Try to convert a string into a number, boolean, or null. If the string - * can't be converted, return the string. This is much less ambitious than - * JSONObject.stringToValue, especially because it does not attempt to - * convert plus forms, octal forms, hex forms, or E forms lacking decimal - * points. - * @param string A String. - * @return A simple JSON value. - */ - public static Object stringToValue(String string) { - if ("".equals(string)) { - return string; - } - if ("true".equalsIgnoreCase(string)) { - return Boolean.TRUE; - } - if ("false".equalsIgnoreCase(string)) { - return Boolean.FALSE; - } - if ("null".equalsIgnoreCase(string)) { - return JSONObject.NULL; - } - if ("0".equals(string)) { - return new Integer(0); - } - -// If it might be a number, try converting it. If that doesn't work, -// return the string. - - try { - char initial = string.charAt(0); - boolean negative = false; - if (initial == '-') { - initial = string.charAt(1); - negative = true; - } - if (initial == '0' && string.charAt(negative ? 2 : 1) == '0') { - return string; - } - if ((initial >= '0' && initial <= '9')) { - if (string.indexOf('.') >= 0) { - return Double.valueOf(string); - } else if (string.indexOf('e') < 0 && string.indexOf('E') < 0) { - Long myLong = new Long(string); - if (myLong.longValue() == myLong.intValue()) { - return new Integer(myLong.intValue()); - } else { - return myLong; - } - } - } - } catch (Exception ignore) { - } - return string; - } - - - /** - * Convert a well-formed (but not necessarily valid) XML string into a - * JSONObject. Some information may be lost in this transformation - * because JSON is a data format and XML is a document format. XML uses - * elements, attributes, and content text, while JSON uses unordered - * collections of name/value pairs and arrays of values. JSON does not - * does not like to distinguish between elements and attributes. - * Sequences of similar elements are represented as JSONArrays. Content - * text may be placed in a "content" member. Comments, prologs, DTDs, and - * <[ [ ]]> are ignored. - * @param string The source string. - * @return A JSONObject containing the structured data from the XML string. - * @throws JSONException - */ - public static JSONObject toJSONObject(String string) throws JSONException { - JSONObject jo = new JSONObject(); - XMLTokener x = new XMLTokener(string); - while (x.more() && x.skipPast("<")) { - parse(x, jo, null); - } - return jo; - } - - - /** - * Convert a JSONObject into a well-formed, element-normal XML string. - * @param object A JSONObject. - * @return A string. - * @throws JSONException - */ - public static String toString(Object object) throws JSONException { - return toString(object, null); - } - - - /** - * Convert a JSONObject into a well-formed, element-normal XML string. - * @param object A JSONObject. - * @param tagName The optional name of the enclosing tag. - * @return A string. - * @throws JSONException - */ - public static String toString(Object object, String tagName) - throws JSONException { - StringBuffer sb = new StringBuffer(); - int i; - JSONArray ja; - JSONObject jo; - String key; - Iterator keys; - int length; - String string; - Object value; - if (object instanceof JSONObject) { - -// Emit - - if (tagName != null) { - sb.append('<'); - sb.append(tagName); - sb.append('>'); - } - -// Loop thru the keys. - - jo = (JSONObject)object; - keys = jo.keys(); - while (keys.hasNext()) { - key = keys.next().toString(); - value = jo.opt(key); - if (value == null) { - value = ""; - } - if (value instanceof String) { - string = (String)value; - } else { - string = null; - } - -// Emit content in body - - if ("content".equals(key)) { - if (value instanceof JSONArray) { - ja = (JSONArray)value; - length = ja.length(); - for (i = 0; i < length; i += 1) { - if (i > 0) { - sb.append('\n'); - } - sb.append(escape(ja.get(i).toString())); - } - } else { - sb.append(escape(value.toString())); - } - -// Emit an array of similar keys - - } else if (value instanceof JSONArray) { - ja = (JSONArray)value; - length = ja.length(); - for (i = 0; i < length; i += 1) { - value = ja.get(i); - if (value instanceof JSONArray) { - sb.append('<'); - sb.append(key); - sb.append('>'); - sb.append(toString(value)); - sb.append("'); - } else { - sb.append(toString(value, key)); - } - } - } else if ("".equals(value)) { - sb.append('<'); - sb.append(key); - sb.append("/>"); - -// Emit a new tag - - } else { - sb.append(toString(value, key)); - } - } - if (tagName != null) { - -// Emit the close tag - - sb.append("'); - } - return sb.toString(); - -// XML does not have good support for arrays. If an array appears in a place -// where XML is lacking, synthesize an element. - - } else { - if (object.getClass().isArray()) { - object = new JSONArray(object); - } - if (object instanceof JSONArray) { - ja = (JSONArray)object; - length = ja.length(); - for (i = 0; i < length; i += 1) { - sb.append(toString(ja.opt(i), tagName == null ? "array" : tagName)); - } - return sb.toString(); - } else { - string = (object == null) ? "null" : escape(object.toString()); - return (tagName == null) ? "\"" + string + "\"" : - (string.length() == 0) ? "<" + tagName + "/>" : - "<" + tagName + ">" + string + ""; - } - } - } -} diff --git a/restx-build/src/main/java/restx/build/org/json/XMLTokener.java b/restx-build/src/main/java/restx/build/org/json/XMLTokener.java deleted file mode 100755 index 88b9b48fb..000000000 --- a/restx-build/src/main/java/restx/build/org/json/XMLTokener.java +++ /dev/null @@ -1,366 +0,0 @@ -package restx.build.org.json; - -/* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -/** - * The XMLTokener extends the JSONTokener to provide additional methods - * for the parsing of XML texts. - * @author JSON.org - * @version 2012-11-13 - */ -@SuppressWarnings("unchecked") -public class XMLTokener extends JSONTokener { - - - /** The table of entity values. It initially contains Character values for - * amp, apos, gt, lt, quot. - */ - public static final java.util.HashMap entity; - - static { - entity = new java.util.HashMap(8); - entity.put("amp", XML.AMP); - entity.put("apos", XML.APOS); - entity.put("gt", XML.GT); - entity.put("lt", XML.LT); - entity.put("quot", XML.QUOT); - } - - /** - * Construct an XMLTokener from a string. - * @param s A source string. - */ - public XMLTokener(String s) { - super(s); - } - - /** - * Get the text in the CDATA block. - * @return The string up to the ]]>. - * @throws JSONException If the ]]> is not found. - */ - public String nextCDATA() throws JSONException { - char c; - int i; - StringBuffer sb = new StringBuffer(); - for (;;) { - c = next(); - if (end()) { - throw syntaxError("Unclosed CDATA"); - } - sb.append(c); - i = sb.length() - 3; - if (i >= 0 && sb.charAt(i) == ']' && - sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') { - sb.setLength(i); - return sb.toString(); - } - } - } - - - /** - * Get the next XML outer token, trimming whitespace. There are two kinds - * of tokens: the '<' character which begins a markup tag, and the content - * text between markup tags. - * - * @return A string, or a '<' Character, or null if there is no more - * source text. - * @throws JSONException - */ - public Object nextContent() throws JSONException { - char c; - StringBuffer sb; - do { - c = next(); - } while (Character.isWhitespace(c)); - if (c == 0) { - return null; - } - if (c == '<') { - return XML.LT; - } - sb = new StringBuffer(); - for (;;) { - if (c == '<' || c == 0) { - back(); - return sb.toString().trim(); - } - if (c == '&') { - sb.append(nextEntity(c)); - } else { - sb.append(c); - } - c = next(); - } - } - - - /** - * Return the next entity. These entities are translated to Characters: - * & ' > < ". - * @param ampersand An ampersand character. - * @return A Character or an entity String if the entity is not recognized. - * @throws JSONException If missing ';' in XML entity. - */ - public Object nextEntity(char ampersand) throws JSONException { - StringBuffer sb = new StringBuffer(); - for (;;) { - char c = next(); - if (Character.isLetterOrDigit(c) || c == '#') { - sb.append(Character.toLowerCase(c)); - } else if (c == ';') { - break; - } else { - throw syntaxError("Missing ';' in XML entity: &" + sb); - } - } - String string = sb.toString(); - Object object = entity.get(string); - return object != null ? object : ampersand + string + ";"; - } - - - /** - * Returns the next XML meta token. This is used for skipping over <!...> - * and <?...?> structures. - * @return Syntax characters (< > / = ! ?) are returned as - * Character, and strings and names are returned as Boolean. We don't care - * what the values actually are. - * @throws JSONException If a string is not properly closed or if the XML - * is badly structured. - */ - public Object nextMeta() throws JSONException { - char c; - char q; - do { - c = next(); - } while (Character.isWhitespace(c)); - switch (c) { - case 0: - throw syntaxError("Misshaped meta tag"); - case '<': - return XML.LT; - case '>': - return XML.GT; - case '/': - return XML.SLASH; - case '=': - return XML.EQ; - case '!': - return XML.BANG; - case '?': - return XML.QUEST; - case '"': - case '\'': - q = c; - for (;;) { - c = next(); - if (c == 0) { - throw syntaxError("Unterminated string"); - } - if (c == q) { - return Boolean.TRUE; - } - } - default: - for (;;) { - c = next(); - if (Character.isWhitespace(c)) { - return Boolean.TRUE; - } - switch (c) { - case 0: - case '<': - case '>': - case '/': - case '=': - case '!': - case '?': - case '"': - case '\'': - back(); - return Boolean.TRUE; - } - } - } - } - - - /** - * Get the next XML Token. These tokens are found inside of angle - * brackets. It may be one of these characters: / > = ! ? or it - * may be a string wrapped in single quotes or double quotes, or it may be a - * name. - * @return a String or a Character. - * @throws JSONException If the XML is not well formed. - */ - public Object nextToken() throws JSONException { - char c; - char q; - StringBuffer sb; - do { - c = next(); - } while (Character.isWhitespace(c)); - switch (c) { - case 0: - throw syntaxError("Misshaped element"); - case '<': - throw syntaxError("Misplaced '<'"); - case '>': - return XML.GT; - case '/': - return XML.SLASH; - case '=': - return XML.EQ; - case '!': - return XML.BANG; - case '?': - return XML.QUEST; - -// Quoted string - - case '"': - case '\'': - q = c; - sb = new StringBuffer(); - for (;;) { - c = next(); - if (c == 0) { - throw syntaxError("Unterminated string"); - } - if (c == q) { - return sb.toString(); - } - if (c == '&') { - sb.append(nextEntity(c)); - } else { - sb.append(c); - } - } - default: - -// Name - - sb = new StringBuffer(); - for (;;) { - sb.append(c); - c = next(); - if (Character.isWhitespace(c)) { - return sb.toString(); - } - switch (c) { - case 0: - return sb.toString(); - case '>': - case '/': - case '=': - case '!': - case '?': - case '[': - case ']': - back(); - return sb.toString(); - case '<': - case '"': - case '\'': - throw syntaxError("Bad character in a name"); - } - } - } - } - - - /** - * Skip characters until past the requested string. - * If it is not found, we are left at the end of the source with a result of false. - * @param to A string to skip past. - * @throws JSONException - */ - public boolean skipPast(String to) throws JSONException { - boolean b; - char c; - int i; - int j; - int offset = 0; - int length = to.length(); - char[] circle = new char[length]; - - /* - * First fill the circle buffer with as many characters as are in the - * to string. If we reach an early end, bail. - */ - - for (i = 0; i < length; i += 1) { - c = next(); - if (c == 0) { - return false; - } - circle[i] = c; - } - - /* We will loop, possibly for all of the remaining characters. */ - - for (;;) { - j = offset; - b = true; - - /* Compare the circle buffer with the to string. */ - - for (i = 0; i < length; i += 1) { - if (circle[j] != to.charAt(i)) { - b = false; - break; - } - j += 1; - if (j >= length) { - j -= length; - } - } - - /* If we exit the loop with b intact, then victory is ours. */ - - if (b) { - return true; - } - - /* Get the next character. If there isn't one, then defeat is ours. */ - - c = next(); - if (c == 0) { - return false; - } - /* - * Shove the character in the circle buffer and advance the - * circle offset. The offset is mod n. - */ - circle[offset] = c; - offset += 1; - if (offset >= length) { - offset -= length; - } - } - } -} diff --git a/restx-build/src/main/resources/restx/build/fragments/maven/annotation-processing-disable.xml b/restx-build/src/main/resources/restx/build/fragments/maven/annotation-processing-disable.xml deleted file mode 100644 index 30760718a..000000000 --- a/restx-build/src/main/resources/restx/build/fragments/maven/annotation-processing-disable.xml +++ /dev/null @@ -1,7 +0,0 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - -proc:none - - diff --git a/restx-build/src/main/resources/restx/build/fragments/maven/copy-dependencies.xml b/restx-build/src/main/resources/restx/build/fragments/maven/copy-dependencies.xml deleted file mode 100644 index 772bf7fba..000000000 --- a/restx-build/src/main/resources/restx/build/fragments/maven/copy-dependencies.xml +++ /dev/null @@ -1,17 +0,0 @@ - - maven-dependency-plugin - - - copy-dependencies - install - - copy-dependencies - - - compile - runtime - test - - - - diff --git a/restx-build/src/main/resources/restx/build/fragments/maven/custom-war-resources.xml b/restx-build/src/main/resources/restx/build/fragments/maven/custom-war-resources.xml deleted file mode 100644 index 35f2e1b00..000000000 --- a/restx-build/src/main/resources/restx/build/fragments/maven/custom-war-resources.xml +++ /dev/null @@ -1,12 +0,0 @@ - - org.apache.maven.plugins - maven-war-plugin - - - - - ${project.war.resources.directory} - - - - diff --git a/restx-build/src/main/resources/restx/build/fragments/maven/jar-main-class.xml b/restx-build/src/main/resources/restx/build/fragments/maven/jar-main-class.xml deleted file mode 100644 index 33a25db9c..000000000 --- a/restx-build/src/main/resources/restx/build/fragments/maven/jar-main-class.xml +++ /dev/null @@ -1,11 +0,0 @@ - - org.apache.maven.plugins - maven-jar-plugin - - - - ${project.main.classname} - - - - diff --git a/restx-build/src/main/resources/restx/build/fragments/maven/java-agent.xml b/restx-build/src/main/resources/restx/build/fragments/maven/java-agent.xml deleted file mode 100644 index 4ae15e1cd..000000000 --- a/restx-build/src/main/resources/restx/build/fragments/maven/java-agent.xml +++ /dev/null @@ -1,21 +0,0 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - -proc:none - - - - org.apache.maven.plugins - maven-jar-plugin - - - - ${project.premain.classname} - ${project.agent.can-redefine-classes} - ${project.agent.can-retransform-classes} - ${project.agent.can-set-native-method-prefix} - - - - diff --git a/restx-build/src/main/resources/restx/build/fragments/maven/javadoc-apidoclet.xml b/restx-build/src/main/resources/restx/build/fragments/maven/javadoc-apidoclet.xml deleted file mode 100644 index 74fcfa634..000000000 --- a/restx-build/src/main/resources/restx/build/fragments/maven/javadoc-apidoclet.xml +++ /dev/null @@ -1,27 +0,0 @@ - - org.apache.maven.plugins - maven-javadoc-plugin - - - attach-docs - - prepare-package - - jar - - - - - ${maven.compiler.source} - restx.apidocs.doclet.ApidocsDoclet - - io.restx - restx-apidocs-doclet - ${restx.version} - - -restx-target-dir ${project.basedir}/target/classes - - diff --git a/restx-build/src/main/resources/restx/build/fragments/maven/testing-build-shell.xml b/restx-build/src/main/resources/restx/build/fragments/maven/testing-build-shell.xml deleted file mode 100644 index 78e9fc08c..000000000 --- a/restx-build/src/main/resources/restx/build/fragments/maven/testing-build-shell.xml +++ /dev/null @@ -1,10 +0,0 @@ - - org.apache.maven.plugins - maven-surefire-plugin - - - ${project.basedir}/../ - 10 - - - diff --git a/restx-build/src/main/resources/restx/build/fragments/maven/uber-jar.xml b/restx-build/src/main/resources/restx/build/fragments/maven/uber-jar.xml deleted file mode 100644 index cfaf983ce..000000000 --- a/restx-build/src/main/resources/restx/build/fragments/maven/uber-jar.xml +++ /dev/null @@ -1,36 +0,0 @@ - - org.apache.maven.plugins - maven-shade-plugin - - - - - ${project.main.classname} - - - - META-INF/services/restx.factory.FactoryMachine - - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - package - - shade - - - - diff --git a/restx-build/src/main/resources/restx/build/fragments/maven/war-overlay-resources.xml b/restx-build/src/main/resources/restx/build/fragments/maven/war-overlay-resources.xml deleted file mode 100644 index 0e73fa303..000000000 --- a/restx-build/src/main/resources/restx/build/fragments/maven/war-overlay-resources.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - release - - - - org.apache.maven.plugins - maven-war-plugin - 2.6 - - ${project.war.overlay.artifactId}-full - - - ${project.war.overlay.groupId} - ${project.war.overlay.artifactId}-ui - zip - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.9.1 - - - attach-full-war - - attach-artifact - - - - - ${project.build.directory}${file.separator}${project.war.overlay.artifactId}-full.war - war - full - - - - - - - - - - - ${project.war.overlay.groupId} - ${project.war.overlay.artifactId}-ui - ${project.version} - zip - - - - diff --git a/restx-build/src/test/java/restx/build/GAVTest.java b/restx-build/src/test/java/restx/build/GAVTest.java deleted file mode 100644 index fb7aabbb3..000000000 --- a/restx-build/src/test/java/restx/build/GAVTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package restx.build; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * User: xavierhanin - * Date: 4/14/13 - * Time: 2:26 PM - */ -public class GAVTest { - @Test - public void should_parse_and_to_string_be_consistent() throws Exception { - shouldBeConsistent("fr.4sh.pom-parents:4sh-uberpom:0.8"); - shouldBeConsistent("restx:restx-common:0.2-SNAPSHOT"); - shouldBeConsistent("joda-time:joda-time:${joda-time.version}"); - } - - @Test - public void should_parse_classifier_artifact(){ - shouldBeConsistent("restx:restx-ui:0.2:zip:jdk8"); - shouldBeConsistent("restx:restx-ui:0.2:jar:jdk8"); - } - - @Test - public void should_parse_optional_artifact(){ - shouldBeConsistent("restx:restx-ui:0.2!optional"); - shouldBeConsistent("restx:restx-ui:0.2:zip!optional"); - shouldBeConsistent("restx:restx-ui:0.2:jar:jdk8!optional"); - } - - @Test - public void should_parse_artifact_with_type() throws Exception { - shouldBeConsistent("restx:restx-ui:0.2:zip"); - } - - private void shouldBeConsistent(String gav) { - assertThat(GAV.parse(gav).toParseableString()).isEqualTo(gav); - } -} diff --git a/restx-build/src/test/java/restx/build/RestxBuildTest.java b/restx-build/src/test/java/restx/build/RestxBuildTest.java deleted file mode 100644 index 364697fab..000000000 --- a/restx-build/src/test/java/restx/build/RestxBuildTest.java +++ /dev/null @@ -1,120 +0,0 @@ -package restx.build; - -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.net.URISyntaxException; -import java.net.URL; - -import static org.assertj.core.api.Assertions.*; - -/** - * User: xavierhanin - * Date: 4/14/13 - * Time: 1:57 PM - */ -public class RestxBuildTest { - private RestxJsonSupport json = new RestxJsonSupport(); - private MavenSupport maven = new MavenSupport(); - private IvySupport ivy = new IvySupport(); - - @Test - public void should_generate_simple_pom() throws Exception { - shouldGenerate(json, "Module1.restx.json", maven, "Module1.pom.xml"); - } - - @Test - public void should_generate_simple_pom_with_external_properties() throws Exception { - shouldGenerate(json, "Module5.restx.json", maven, "Module5.pom.xml"); - } - - @Test - public void should_generate_pom_with_fragment() throws Exception { - shouldGenerate(json, "Module3.restx.json", maven, "Module3.pom.xml"); - } - - @Test - public void should_generate_pom_with_war() throws Exception { - shouldGenerate(json, "Module4.restx.json", maven, "Module4.pom.xml"); - } - - @Test - public void should_parse_simple_pom() throws Exception { - shouldGenerate(maven, "Module1.pom.xml", json, "Module1.restx.json"); - } - - @Test - public void should_parse_simple_pom_with_war() throws Exception { - shouldGenerate(maven, "Module4.pom.xml", json, "Module4.restx.json"); - } - - @Test - public void should_generate_simple_ivy() throws Exception { - shouldGenerate(json, "Module1.restx.json", ivy, "Module1.ivy"); - } - - @Test - public void should_generate_simple_ivy_with_external_properties() throws Exception { - shouldGenerate(json, "Module5.restx.json", ivy, "Module5.ivy"); - } - - @Test - public void should_generate_simple_ivy_war() throws Exception { - shouldGenerate(json, "Module4.restx.json", ivy, "Module4.ivy"); - } - - @Test - public void should_generate_ivy_with_internal_dep() throws Exception { - shouldGenerate(json, "Module2.restx.json", ivy, "Module2.ivy"); - } - - @Test - public void should_generate_pom_with_type() throws Exception { - shouldGenerate(json, "Module6.restx.json", maven, "Module6.pom.xml"); - } - - @Test - public void should_generate_pom_with_merged_fragments() throws Exception { - shouldGenerate(json, "Module7.restx.json", maven, "Module7.pom.xml"); - } - - @Test - public void should_generate_pom_with_tools_dependency() throws Exception { - shouldGenerate(json, "Module8.restx.json", maven, "Module8.pom.xml"); - } - - @Test - public void should_generate_pom_with_optional_dependency() throws Exception { - shouldGenerate(json, "Module9.restx.json", maven, "Module9.pom.xml"); - } - - @Test - public void should_parse_simple_pom_with_optional_dependency() throws Exception { - shouldGenerate(maven, "Module9.pom.xml", json, "Module9.restx.json"); - } - - private void shouldGenerate(RestxBuild.Parser parser, String module, RestxBuild.Generator generator, String expected) throws IOException { - URL resource = getClass().getResource(module); - ModuleDescriptor md; - if (resource.getProtocol().equals("file")) { - File f; - try { - f = new File(resource.toURI()); - } catch(URISyntaxException e) { - f = new File(resource.getPath()); - } - md = parser.parse(f.toPath()); - } else { - try (InputStream stream = resource.openStream()) { - md = parser.parse(stream); - } - } - StringWriter w = new StringWriter(); - generator.generate(md, w); - assertThat(w.toString()).isEqualTo(RestxBuildHelper.toString(getClass().getResourceAsStream(expected))); - } - -} diff --git a/restx-build/src/test/resources/restx/build/Module1.ivy b/restx-build/src/test/resources/restx/build/Module1.ivy deleted file mode 100644 index 72c4a89f1..000000000 --- a/restx-build/src/test/resources/restx/build/Module1.ivy +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/restx-build/src/test/resources/restx/build/Module1.pom.xml b/restx-build/src/test/resources/restx/build/Module1.pom.xml deleted file mode 100644 index 6a52910af..000000000 --- a/restx-build/src/test/resources/restx/build/Module1.pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - 4.0.0 - - - com.example - example-parent - 0.8 - - - com.example - example-common - 0.2-SNAPSHOT - jar - example-common - - - 1.7 - 1.7 - 2.0 - 4.11 - - - - - com.google.guava - guava - 14.0-rc2 - - - joda-time - joda-time - ${joda-time.version} - - - com.github.spullara.mustache.java - compiler - 0.8.10 - - - junit - junit - ${junit.version} - test - - - org.easytesting - fest-assert-core - 2.0M8 - test - - - \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module1.restx.json b/restx-build/src/test/resources/restx/build/Module1.restx.json deleted file mode 100644 index 9b7d4b394..000000000 --- a/restx-build/src/test/resources/restx/build/Module1.restx.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "parent": "com.example:example-parent:0.8", - "module": "com.example:example-common:0.2-SNAPSHOT", - - "properties": { - "java.version": "1.7", - "joda-time.version": "2.0", - "junit.version": "4.11" - }, - - "dependencies": { - "compile": [ - "com.google.guava:guava:14.0-rc2", - "joda-time:joda-time:${joda-time.version}", - "com.github.spullara.mustache.java:compiler:0.8.10" - ], - "test": [ - "junit:junit:${junit.version}", - "org.easytesting:fest-assert-core:2.0M8" - ] - } -} \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module2.ivy b/restx-build/src/test/resources/restx/build/Module2.ivy deleted file mode 100644 index b6c841cb5..000000000 --- a/restx-build/src/test/resources/restx/build/Module2.ivy +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/restx-build/src/test/resources/restx/build/Module2.restx.json b/restx-build/src/test/resources/restx/build/Module2.restx.json deleted file mode 100644 index 65184acb4..000000000 --- a/restx-build/src/test/resources/restx/build/Module2.restx.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "parent": "com.example:example-parent:0.8", - "module": "com.example:example-core:0.2-SNAPSHOT", - - "properties": { - "java.version": "1.7", - "slf4j-api.version": "1.7.2", - "jackson.version": "2.1.2" - }, - - "dependencies": { - "compile": [ - "com.fasterxml.jackson.core:jackson-core:${jackson.version}", - "com.fasterxml.jackson.core:jackson-annotations:${jackson.version}", - "com.fasterxml.jackson.core:jackson-databind:${jackson.version}", - "com.fasterxml.jackson.datatype:jackson-datatype-joda:${jackson.version}", - "com.example:example-factory:${module.version}", - "javax.inject:javax.inject:1", - "com.google.guava:guava:14.0-rc2", - "joda-time:joda-time:2.0", - "org.slf4j:slf4j-api:${slf4j-api.version}", - "com.google.code.maven-play-plugin.com.jamonapi:jamon:2.7", - "org.hibernate:hibernate-validator:5.0.0.Alpha2", - "org.reflections:reflections:0.9.9-RC1", - "junit:junit:4.11", - "org.hamcrest:hamcrest-core:1.3", - "org.hamcrest:hamcrest-library:1.3", - "uk.co.datumedge:hamcrest-json:0.2", - "org.easytesting:fest-assert-core:2.0M8", - "org.yaml:snakeyaml:1.12", - "com.github.kevinsawicki:http-request:4.1" - ] - } -} diff --git a/restx-build/src/test/resources/restx/build/Module3.pom.xml b/restx-build/src/test/resources/restx/build/Module3.pom.xml deleted file mode 100644 index 2774d80ad..000000000 --- a/restx-build/src/test/resources/restx/build/Module3.pom.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - 4.0.0 - - - com.example - example-parent - 0.8 - - - com.example - example-common - 0.2-SNAPSHOT - jar - example-common - - - 1.7 - 1.7 - 2.0 - 4.11 - - - - - com.google.guava - guava - 14.0-rc2 - - - joda-time - joda-time - ${joda-time.version} - - - com.github.spullara.mustache.java - compiler - 0.8.10 - - - junit - junit - ${junit.version} - test - - - org.easytesting - fest-assert-core - 2.0M8 - test - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - -proc:none - - - - - \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module3.restx.json b/restx-build/src/test/resources/restx/build/Module3.restx.json deleted file mode 100644 index eb6561e71..000000000 --- a/restx-build/src/test/resources/restx/build/Module3.restx.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "parent": "com.example:example-parent:0.8", - "module": "com.example:example-common:0.2-SNAPSHOT", - - "properties": { - "java.version": "1.7", - "joda-time.version": "2.0", - "junit.version": "4.11" - }, - - "fragments": { - "maven": [ - "classpath:///restx/build/fragments/maven/annotation-processing-disable.xml" - ] - }, - - "dependencies": { - "compile": [ - "com.google.guava:guava:14.0-rc2", - "joda-time:joda-time:${joda-time.version}", - "com.github.spullara.mustache.java:compiler:0.8.10" - ], - "test": [ - "junit:junit:${junit.version}", - "org.easytesting:fest-assert-core:2.0M8" - ] - } -} \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module4.ivy b/restx-build/src/test/resources/restx/build/Module4.ivy deleted file mode 100644 index 950e9aef9..000000000 --- a/restx-build/src/test/resources/restx/build/Module4.ivy +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/restx-build/src/test/resources/restx/build/Module4.pom.xml b/restx-build/src/test/resources/restx/build/Module4.pom.xml deleted file mode 100644 index 3f6b83fa0..000000000 --- a/restx-build/src/test/resources/restx/build/Module4.pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - 4.0.0 - - - com.example - example-parent - 0.8 - - - com.example - example-common - 0.2-SNAPSHOT - war - example-common - - - 1.7 - 1.7 - 2.0 - 4.11 - - - - - com.google.guava - guava - 14.0-rc2 - - - joda-time - joda-time - ${joda-time.version} - - - com.github.spullara.mustache.java - compiler - 0.8.10 - - - junit - junit - ${junit.version} - test - - - org.easytesting - fest-assert-core - 2.0M8 - test - - - \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module4.restx.json b/restx-build/src/test/resources/restx/build/Module4.restx.json deleted file mode 100644 index b19262a44..000000000 --- a/restx-build/src/test/resources/restx/build/Module4.restx.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "parent": "com.example:example-parent:0.8", - "module": "com.example:example-common:0.2-SNAPSHOT", - "packaging": "war", - - "properties": { - "java.version": "1.7", - "joda-time.version": "2.0", - "junit.version": "4.11" - }, - - "dependencies": { - "compile": [ - "com.google.guava:guava:14.0-rc2", - "joda-time:joda-time:${joda-time.version}", - "com.github.spullara.mustache.java:compiler:0.8.10" - ], - "test": [ - "junit:junit:${junit.version}", - "org.easytesting:fest-assert-core:2.0M8" - ] - } -} \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module5.ivy b/restx-build/src/test/resources/restx/build/Module5.ivy deleted file mode 100644 index 80a7c4cdb..000000000 --- a/restx-build/src/test/resources/restx/build/Module5.ivy +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/restx-build/src/test/resources/restx/build/Module5.pom.xml b/restx-build/src/test/resources/restx/build/Module5.pom.xml deleted file mode 100644 index 8992b583c..000000000 --- a/restx-build/src/test/resources/restx/build/Module5.pom.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - 4.0.0 - - - com.example - example-parent - 0.8 - - - com.example - example-common - 0.2-SNAPSHOT - jar - example-common - - - 1.7 - 1.7 - 0.2-SNAPSHOT - 2.0 - 4.11 - - - - - com.example - example-dummy - ${restx.version} - - - com.google.guava - guava - 14.0-rc2 - - - joda-time - joda-time - ${joda-time.version} - - - com.github.spullara.mustache.java - compiler - 0.8.10 - - - junit - junit - ${junit.version} - test - - - org.easytesting - fest-assert-core - 2.0M8 - test - - - \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module5.properties.json b/restx-build/src/test/resources/restx/build/Module5.properties.json deleted file mode 100644 index 3342df650..000000000 --- a/restx-build/src/test/resources/restx/build/Module5.properties.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "java.version": "1.7", - "restx.version": "0.2-SNAPSHOT", - "guava.version": "1.0", - "joda-time.version": "2.0", - "junit.version": "4.11" -} diff --git a/restx-build/src/test/resources/restx/build/Module5.restx.json b/restx-build/src/test/resources/restx/build/Module5.restx.json deleted file mode 100644 index aa990aa76..000000000 --- a/restx-build/src/test/resources/restx/build/Module5.restx.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "parent": "com.example:example-parent:0.8", - "module": "com.example:example-common:${restx.version}", - - "properties": { - "@files": ["Module5.properties.json"] - }, - - "dependencies": { - "compile": [ - "com.example:example-dummy:${restx.version}", - "com.google.guava:guava:14.0-rc2", - "joda-time:joda-time:${joda-time.version}", - "com.github.spullara.mustache.java:compiler:0.8.10" - ], - "test": [ - "junit:junit:${junit.version}", - "org.easytesting:fest-assert-core:2.0M8" - ] - } -} \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module6.pom.xml b/restx-build/src/test/resources/restx/build/Module6.pom.xml deleted file mode 100644 index 252a5822c..000000000 --- a/restx-build/src/test/resources/restx/build/Module6.pom.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - 4.0.0 - - - com.example - example-parent - 0.8 - - - com.example - example-common - 0.2-SNAPSHOT - jar - example-common - - - 1.7 - 1.7 - 0.2-SNAPSHOT - 2.0 - 4.11 - - - - - com.example - example-dummy - ${restx.version} - zip - - - com.google.guava - guava - 14.0-rc2 - - - joda-time - joda-time - ${joda-time.version} - - - com.github.spullara.mustache.java - compiler - 0.8.10 - - - junit - junit - ${junit.version} - test - - - org.easytesting - fest-assert-core - 2.0M8 - test - - - \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module6.restx.json b/restx-build/src/test/resources/restx/build/Module6.restx.json deleted file mode 100644 index 0a0df101d..000000000 --- a/restx-build/src/test/resources/restx/build/Module6.restx.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "parent": "com.example:example-parent:0.8", - "module": "com.example:example-common:${restx.version}", - - "properties": { - "@files": ["Module5.properties.json"] - }, - - "dependencies": { - "compile": [ - "com.example:example-dummy:${restx.version}:zip", - "com.google.guava:guava:14.0-rc2", - "joda-time:joda-time:${joda-time.version}", - "com.github.spullara.mustache.java:compiler:0.8.10" - ], - "test": [ - "junit:junit:${junit.version}", - "org.easytesting:fest-assert-core:2.0M8" - ] - } -} \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module7.pom.xml b/restx-build/src/test/resources/restx/build/Module7.pom.xml deleted file mode 100644 index 9b6b292c2..000000000 --- a/restx-build/src/test/resources/restx/build/Module7.pom.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - 4.0.0 - - - com.example - example-parent - 0.8 - - - com.example - example-common - 0.2-SNAPSHOT - jar - example-common - - - 1.7 - 1.7 - 2.0 - 4.11 - - - - - com.google.guava - guava - 14.0-rc2 - - - joda-time - joda-time - ${joda-time.version} - - - com.github.spullara.mustache.java - compiler - 0.8.10 - - - junit - junit - ${junit.version} - test - - - - - - maven-dependency-plugin - - - copy-dependencies - install - - copy-dependencies - - - compile - runtime - test - - - - - - org.apache.maven.plugins - maven-war-plugin - - - - - ${project.war.resources.directory} - - - - - - - \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module7.restx.json b/restx-build/src/test/resources/restx/build/Module7.restx.json deleted file mode 100644 index bc2065340..000000000 --- a/restx-build/src/test/resources/restx/build/Module7.restx.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "parent": "com.example:example-parent:0.8", - "module": "com.example:example-common:0.2-SNAPSHOT", - - "properties": { - "java.version": "1.7", - "joda-time.version": "2.0", - "junit.version": "4.11" - }, - - "fragments": { - "maven": [ - "classpath:///restx/build/fragments/maven/copy-dependencies.xml", - "classpath:///restx/build/fragments/maven/custom-war-resources.xml" - ] - }, - - "dependencies": { - "compile": [ - "com.google.guava:guava:14.0-rc2", - "joda-time:joda-time:${joda-time.version}", - "com.github.spullara.mustache.java:compiler:0.8.10" - ], - "test": [ - "junit:junit:${junit.version}" - ] - } -} \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module8.pom.xml b/restx-build/src/test/resources/restx/build/Module8.pom.xml deleted file mode 100644 index 314becc89..000000000 --- a/restx-build/src/test/resources/restx/build/Module8.pom.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - 4.0.0 - - - com.example - example-parent - 0.8 - - - com.example - example-common - 0.2-SNAPSHOT - jar - example-common - - - 1.7 - 1.7 - 2.0 - 4.11 - - - - - com.sun.tools - tools - ${java.version} - system - ${java.home}/../lib/tools.jar - - - com.google.guava - guava - 14.0-rc2 - - - joda-time - joda-time - ${joda-time.version} - - - com.github.spullara.mustache.java - compiler - 0.8.10 - - - junit - junit - ${junit.version} - test - - - org.easytesting - fest-assert-core - 2.0M8 - test - - - \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module8.restx.json b/restx-build/src/test/resources/restx/build/Module8.restx.json deleted file mode 100644 index fd10489c0..000000000 --- a/restx-build/src/test/resources/restx/build/Module8.restx.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "parent": "com.example:example-parent:0.8", - "module": "com.example:example-common:0.2-SNAPSHOT", - - "properties": { - "java.version": "1.7", - "joda-time.version": "2.0", - "junit.version": "4.11" - }, - - "dependencies": { - "system": [ - "com.sun.tools:tools:${java.version}" - ], - "compile": [ - "com.google.guava:guava:14.0-rc2", - "joda-time:joda-time:${joda-time.version}", - "com.github.spullara.mustache.java:compiler:0.8.10" - ], - "test": [ - "junit:junit:${junit.version}", - "org.easytesting:fest-assert-core:2.0M8" - ] - } -} \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module9.pom.xml b/restx-build/src/test/resources/restx/build/Module9.pom.xml deleted file mode 100644 index ec4436a90..000000000 --- a/restx-build/src/test/resources/restx/build/Module9.pom.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - 4.0.0 - - - com.example - example-parent - 0.8 - - - com.example - example-common - 0.2-SNAPSHOT - jar - example-common - - - 1.7 - 1.7 - 2.0 - 4.11 - - - - - com.google.guava - guava - 14.0-rc2 - - - joda-time - joda-time - ${joda-time.version} - - - com.github.spullara.mustache.java - compiler - 0.8.10 - true - - - junit - junit - ${junit.version} - test - - - org.easytesting - fest-assert-core - 2.0M8 - test - - - \ No newline at end of file diff --git a/restx-build/src/test/resources/restx/build/Module9.restx.json b/restx-build/src/test/resources/restx/build/Module9.restx.json deleted file mode 100644 index 8480b8b4a..000000000 --- a/restx-build/src/test/resources/restx/build/Module9.restx.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "parent": "com.example:example-parent:0.8", - "module": "com.example:example-common:0.2-SNAPSHOT", - - "properties": { - "java.version": "1.7", - "joda-time.version": "2.0", - "junit.version": "4.11" - }, - - "dependencies": { - "compile": [ - "com.google.guava:guava:14.0-rc2", - "joda-time:joda-time:${joda-time.version}", - "com.github.spullara.mustache.java:compiler:0.8.10!optional" - ], - "test": [ - "junit:junit:${junit.version}", - "org.easytesting:fest-assert-core:2.0M8" - ] - } -} \ No newline at end of file diff --git a/restx-core-shell/md.restx.json b/restx-core-shell/md.restx.json deleted file mode 100644 index 877f5f78f..000000000 --- a/restx-core-shell/md.restx.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "parent": "io.restx:restx-parent:${restx.version}", - "module": "io.restx:restx-core-shell:${restx.version}", - - "properties": { - "@files": ["../restx.build.properties.json"] - }, - - "dependencies": { - "compile": [ - "io.restx:restx-factory:${restx.version}", - "io.restx:restx-core:${restx.version}", - "io.restx:restx-shell:${restx.version}", - "io.restx:restx-shell-manager:${restx.version}", - "io.restx:restx-build:${restx.version}", - "org.apache.ivy:ivy:${ivy.version}", - "org.mindrot:jbcrypt:0.3m" - ], - "test": [ - "junit:junit:${junit.version}", - "org.apache.maven.shared:maven-verifier:${maven-verifier.version}", - "org.mockito:mockito-all:${mockito.version}" - ] - } -} diff --git a/restx-core-shell/module.ivy b/restx-core-shell/module.ivy deleted file mode 100644 index 51f294e5b..000000000 --- a/restx-core-shell/module.ivy +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/restx-core-shell/pom.xml b/restx-core-shell/pom.xml deleted file mode 100644 index b990ccc53..000000000 --- a/restx-core-shell/pom.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - 4.0.0 - - - io.restx - restx-parent - 0.35-SNAPSHOT - - - restx-core-shell - restx-core-shell - - - - io.restx - restx-factory - - - io.restx - restx-core - - - io.restx - restx-shell - - - io.restx - restx-shell-manager - - - io.restx - restx-build - - - org.apache.ivy - ivy - - - org.mindrot - jbcrypt - - - junit - junit - test - - - org.apache.maven.shared - maven-verifier - test - - - org.mockito - mockito-all - test - - - diff --git a/restx-core-shell/src/main/java/restx/core/shell/AppShellCommand.java b/restx-core-shell/src/main/java/restx/core/shell/AppShellCommand.java deleted file mode 100644 index a13e5da42..000000000 --- a/restx-core-shell/src/main/java/restx/core/shell/AppShellCommand.java +++ /dev/null @@ -1,902 +0,0 @@ -package restx.core.shell; - -import com.google.common.base.*; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import com.google.common.io.ByteStreams; -import com.google.common.io.Files; -import jline.console.completer.ArgumentCompleter; -import jline.console.completer.Completer; -import jline.console.completer.StringsCompleter; -import restx.AppSettings; -import restx.Apps; -import restx.RestxContext; -import restx.build.ModuleDescriptor; -import restx.build.RestxBuild; -import restx.build.RestxJsonSupport; -import restx.common.Archetype; -import restx.common.UUIDGenerator; -import restx.common.Version; -import restx.factory.Component; -import restx.factory.NamedComponent; -import restx.factory.SingletonFactoryMachine; -import restx.plugins.ModulesManager; -import restx.shell.RestxShell; -import restx.shell.ShellCommandRunner; -import restx.shell.ShellIvy; -import restx.shell.StdShellCommand; - -import java.io.*; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Random; - -import static java.nio.file.Files.newOutputStream; -import static restx.common.MoreFiles.extractZip; -import static restx.common.MorePreconditions.checkPresent; - -/** - * User: xavierhanin - * Date: 4/10/13 - * Time: 8:53 PM - */ -@Component -public class AppShellCommand extends StdShellCommand { - private final UUIDGenerator uuidGenerator; - - public AppShellCommand(UUIDGenerator uuidGenerator) { - super(ImmutableList.of("app"), "app related commands: creates a new app, run your app, ..."); - this.uuidGenerator = uuidGenerator; - } - - @Override - protected Optional doMatch(String line) { - List args = splitArgs(line); - - if (args.size() < 2) { - return Optional.absent(); - } - - switch (args.get(1)) { - case "new": - return Optional.of(new NewAppCommandRunner()); - case "compile": - return Optional.of(new CompileAppCommandRunner(args)); - case "generate-start-script": - return Optional.of(new GenerateStartCommandRunner(args)); - case "run": - return Optional.of(new RunAppCommandRunner(args)); - case "grab": - return Optional.of(new GrabAppCommandRunner(args)); - case "archive": - return Optional.of(new ArchiveAppCommandRunner(args)); - } - - return Optional.absent(); - } - - public static Path standardCachedAppPath(String appname) { - return Paths.get(System.getProperty("restx.shell.home"), "apps/"+appname); - } - - @Override - public void man(Appendable appendable) throws IOException { - super.man(appendable); - } - - protected String resourceMan() { - return "restx/core/shell/app.man"; - } - - @Override - public Iterable getCompleters() { - return ImmutableList.of(new ArgumentCompleter( - new StringsCompleter("app"), new StringsCompleter("new", "run", "compile", "generate-start-script"))); - } - - static class NewAppDescriptor { - String appName; - String targetPath; - String groupId; - String artifactId; - String mainPackage; - String version; - List buildFiles; - String signatureKey; - String adminPassword; - String defaultPort; - String baseAPIPath; - String javaVersion; - String restxVersion; - boolean generateHelloResource; - boolean includeStatsModule; - boolean useSrvuiLayout; - String boostrapUIOption; - String boostrapUITemplate; - } - - class NewAppCommandRunner implements ShellCommandRunner { - - private Archetype srvMainTemplates = Archetype.buildArchetype("templates.srv.main"); - private Archetype srvHelloResourceTemplates = Archetype.buildArchetype("templates.srv.helloResource"); - private Archetype rootMainTemplates = Archetype.buildArchetype("templates.root.main"); - private Archetype rootNoNodeTemplates = Archetype.buildArchetype("templates.root.no-node"); - private Archetype rootGruntBowerTemplates = Archetype.buildArchetype("templates.root.grunt-bower"); - - private final ImmutableMap uiTemplatesPackageLocations = ImmutableMap.of( - "html5", "https://github.com/restx/html5/archive/restx.zip", - "angular-bootstrap", "https://github.com/restx/angular-bootstrap/archive/restx.zip", - "angular-bootstrap-grunt-bower", "https://github.com/restx/angular-bootstrap-grunt-bower/archive/restx.zip" - ); - - @Override - public void run(RestxShell shell) throws Exception { - shell.printIn("Welcome to RESTX APP bootstrap!", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(""); - shell.println("This command will ask you a few questions to generate your brand new RESTX app."); - shell.println("For any question you can get help by answering '??' (without the quotes)."); - shell.println(""); - - NewAppDescriptor descriptor = new NewAppDescriptor(); - descriptor.appName = ""; - while (Strings.isNullOrEmpty(descriptor.appName)) { - descriptor.appName = shell.ask("App name? ", "", - "This is the name of the application you are creating.\n" + - "It can contain spaces, it's used mainly for documentation and to provide default for other values.\n" + - "Examples: Todo, Foo Bar, ..."); - } - - descriptor.targetPath = shell.ask("target directory [%s]? ", - descriptor.appName.replaceAll("\\s+", "-").toLowerCase(Locale.ENGLISH), - "This is the location where the app will be generated.\n" + - "You can use . if you want to generate in current directory.\n" + - "Note that restx will create the directory if it doesn't exist."); - descriptor.groupId = shell.ask("group id [%s]? ", - descriptor.appName.replaceAll("\\s+", "-").toLowerCase(Locale.ENGLISH), - "This is the identifier of the group or organization producing the application.\n" + - "In the Maven world this is called a groupId, in Ivy it's called organization.\n" + - "It MUST NOT contain spaces nor columns (':'), and is usually a reversed domain name.\n" + - "Examples: io.restx, com.example, ..."); - descriptor.artifactId = shell.ask("artifact id [%s]? ", - descriptor.appName.replaceAll("\\s+", "-").toLowerCase(Locale.ENGLISH), - "This is the identifier of the app module.\n" + - "In the Maven world this is called an artifactId, in Ivy it's called module.\n" + - "It MUST NOT contain spaces nor columns (':'), and is usually a dash separated lower case word.\n" + - "Examples: myapp, todo, foo-app, ...") - .replaceAll("\\s+", "-"); - descriptor.mainPackage = shell.ask("main package [%s]? ", - descriptor.groupId.replaceAll("\\-", ".").toLowerCase(Locale.ENGLISH), - "This is the main package in which you will develop your application.\n" + - "In Java convention it should start with a reversed domain name followed by the app name\n" + - "but for applications (as opposed to APIs) we prefer to use a short name, like that app name.\n" + - "It MUST follow Java package names restrictions, so MUST NOT contain spaces\n" + - "Examples: myapp, com.example.todoapp, ..."); - descriptor.version = shell.ask("version [%s]? ", "0.1-SNAPSHOT", - "This is the name of the first version of the app you are targetting.\n" + - "It's recommended to use Maven convention to suffix it with -SNAPSHOT if you plan to use Maven for your app\n" + - "Examples: 0.1-SNAPSHOT, 1.0, ..."); - - while (descriptor.buildFiles == null) { - String option = shell.ask("Select module descriptor(s) you want to generate :\n" + - " [ 1] md.restx.json only.\n" + - " [ 2] module.ivy only.\n" + - " [ 3] pom.xml only.\n" + - " [ 4] md.restx.json + module.ivy.\n" + - " [ 5] md.restx.json + pom.xml.\n" + - " [ all] md.restx.json + pom.xml + module.ivy.\n" + - " [none] no module descriptor. WARNING: this will make it harder to build your app.\n" + - "\n" + - " Which option [%s]? ", - "all", - "This allows to generate module descriptor(s) for your app.\n" + - "Module descriptor types:\n" + - "\t- 'md.restx.json': get a RestX module descriptor generated for you.\n" + - "\t- 'module.ivy': get an Easyant compatible Ivy file generated for you.\n" + - "\t- 'pom.xml': get a Maven POM generated for you.\n" + - "If you don't know these tools, use default answer.\n"); - switch (option.trim()) { - case "1": descriptor.buildFiles = Arrays.asList(ModuleDescriptorType.RESTX); break; - case "2": descriptor.buildFiles = Arrays.asList(ModuleDescriptorType.IVY); break; - case "3": descriptor.buildFiles = Arrays.asList(ModuleDescriptorType.MAVEN); break; - case "4": descriptor.buildFiles = Arrays.asList(ModuleDescriptorType.RESTX, ModuleDescriptorType.IVY); break; - case "5": descriptor.buildFiles = Arrays.asList(ModuleDescriptorType.RESTX, ModuleDescriptorType.MAVEN); break; - case "all": descriptor.buildFiles = Arrays.asList(ModuleDescriptorType.values()); break; - case "none": descriptor.buildFiles = Collections.emptyList(); break; - default: descriptor.buildFiles = null; - } - } - - descriptor.javaVersion = shell.ask("java version [%s]? ", - System.getProperty("java.version").replaceAll("^(\\d+\\.\\d+).*$", "$1"), - "The version of Java you want to use in your application.\n" + - "RESTX supports Java 7 (1.7) and Java 8 (1.8)\n" + - "Example: 1.7, 1.8"); - - descriptor.restxVersion = shell.ask("restx version [%s]? ", Version.getVersion("io.restx", "restx-core")); - - List list = Lists.newArrayList(uuidGenerator.doGenerate(), - String.valueOf(new Random().nextLong()), descriptor.appName, descriptor.artifactId); - Collections.shuffle(list); - descriptor.signatureKey = shell.ask("signature key (to sign cookies) [%s]? ", - Joiner.on(" ").join(list), - "This is used as salt for signing stuff exchanged with the client.\n" + - "Use something fancy or keep what is proposed by default, but make sure to not share that publicly."); - - descriptor.adminPassword = shell.ask("admin password (to authenticate on restx console) [%s]? ", - String.valueOf(new Random().nextInt(10000)), - "This is used as password for the admin user to authenticate on restx console.\n" + - "This is only a default way to authenticate out of the box, restx security is very flexible."); - - descriptor.defaultPort = shell.ask("default port [%s]? ", "8080", - "This is the default port used when using embedded version.\n" + - "Usually Java web containers use 8080, it may be a good idea to use a different port to avoid \n" + - "conflicts with another servlet container.\n" + - "You can also use port 80 if you want to serve your API directly with the embedded server\n" + - "and no reverse proxy in front of it. But beware that you may need admin privileges for that.\n" + - "Examples: 8080, 8086, 8000, 80"); - descriptor.baseAPIPath = shell.ask("base API path [%s]? ", "/api", - "This is the base API path on which RESTX will handle requests.\n" + - "Being focused on REST API only, RESTX is usually shared with either static or dynamic \n" + - "resources serving (HTML, CSS, JS, images, ...) and therefore is used to handle requests on\n" + - "only a sub path of the web app.\n" + - "If you plan to use it to serve requests from an API only domain (eg api.example.com)\n" + - "you can use '' (empty string) for this path.\n" + - "Examples: /api, /api/v2, /restx, ..."); - - descriptor.generateHelloResource = shell.askBoolean("generate hello resource example [Y/n]? ", "y", - "This will generate an example resource with an associated spec test so that your boostrapped\n" + - "application can be used as soon as it has been generated.\n" + - "If this is the first app you generate with RESTX, it's probably a good idea to generate\n" + - "this example resource.\n" + - "If you already know RESTX by heart you shouldn't be reading this message anyway :)"); - - descriptor.includeStatsModule = shell.askBoolean("include stats module and share anonymous stats on your app [Y/n]? ", "y", - "This will include the restx-stats-admin module which collects anonymous stats on your app\n" + - "and share them with the community.\n" + - "See http://restx.io/stats.html for more details."); - - descriptor.useSrvuiLayout = shell.askBoolean("do you want to use srv/ui layout [y/N]?", "n", - "This will organize your app in 2 modules:\n" + - " - `srv`: for the server part, using RESTX to serve the REST API.\n" + - " - `ui`: for the front part, using your front end framework of choice (Angular, Ember, ...)\n" + - "If you prefer a different code organization between your front end and back end,\n" + - "like putting your front end resources in `src/main/webapp` as is usual for Java Web Development,\n" + - "don't use this option and organize your frontent as you like."); - - if (descriptor.useSrvuiLayout) { - descriptor.boostrapUIOption = shell.ask("How do you want to bootstrap your UI (yo/restx/none) [restx]?", "restx", - "Select how to boostrap your UI:\n" + - " - `yo`: use yeoman (you need to have yeoman installed).\n" + - " - `restx`: RESTX has basic UI generation support.\n" + - " select this option if you don't have yeoman installed but still want to have\n" + - " basic UI boostrapped.\n" + - " - `none`: don't bootstrap the UI, leave it empty." + - " you can use this option if you want to bootstrap it yourself.\n"); - if ("yo".equalsIgnoreCase(descriptor.boostrapUIOption)) { - while (Strings.isNullOrEmpty(descriptor.boostrapUITemplate)) { - descriptor.boostrapUITemplate = shell.ask("Which generator do you want to use?:", - "", - "Select the yeoman generator you want to use.\n" + - "Check http://yeoman.io/community-generators.html to get the list of generators.\n" + - "Examples: angular, ember, mobile, ..."); - } - } else if ("restx".equalsIgnoreCase(descriptor.boostrapUIOption)) { - while (descriptor.boostrapUITemplate == null) { - String option = shell.ask("Select the template you want to use:\n" + - " [ 1] HTML5 Boilerplate\n" + - " Use this if you want a very basic HTML5 bootstrap, with no additional tool required.\n" + - " [ 2] Angular, Twitter Bootstrap\n" + - " Use this if you want a more convenient bootstrap, with no additional tool required.\n" + - " [ 3] Angular, Twitter Bootstrap. Use grunt for building and bower to manage dependencies.\n" + - " Use this if you want a convenient bootstrap using the very popular frontend tools.\n" + - " You will need:\n" + - " - nodejs: http://nodejs.org/download/\n" + - " - grunt: http://gruntjs.com/getting-started\n" + - " - bower: http://bower.io/\n" + - "\n" + - " Which template do you want [1]? ", - "1", - "Select the template to use depending on your preferences and tools installed.\n" + - "If you want more choices, you can either contribute to RESTX or use yeoman"); - switch (option.trim()) { - case "1": descriptor.boostrapUITemplate = "html5"; break; - case "2": descriptor.boostrapUITemplate = "angular-bootstrap"; break; - case "3": descriptor.boostrapUITemplate = "angular-bootstrap-grunt-bower"; break; - default: descriptor.boostrapUITemplate = null; - } - } - } - } - - Path appPath = generateApp(descriptor, shell); - - shell.cd(appPath); - - if (shell.askBoolean("Do you want to install its deps and run it now? [y/N]", "n", - "By answering yes restx will resolve and install the dependencies of the app and run it.\n" + - "You can always install the deps later by using the `deps install` command\n" + - "and run the app with the `app run` command")) { - shell.println("restx> deps install"); - new DepsShellCommand.InstallDepsCommandRunner().run(shell); - shell.println("restx> app run"); - new RunAppCommandRunner(Collections.emptyList()).run(shell); - } - } - - public Path generateApp(NewAppDescriptor descriptor, RestxShell shell) throws IOException { - - ImmutableMap scope = ImmutableMap.builder() - .put("appName", descriptor.appName) - .put("groupId", descriptor.groupId) - .put("artifactId", descriptor.artifactId) - .put("mainPackage", descriptor.mainPackage) - .put("packagePath", descriptor.mainPackage.replace('.', '/')) - .put("version", descriptor.version) - .put("signatureKey", descriptor.signatureKey) - .put("adminPassword", descriptor.adminPassword) - .put("defaultPort", descriptor.defaultPort) - .put("baseAPIPath", descriptor.baseAPIPath) - .put("javaVersion", descriptor.javaVersion) - .put("restxVersion", descriptor.restxVersion) - .put("includeStatsModule", descriptor.includeStatsModule) - .put("useSrvuiLayout", descriptor.useSrvuiLayout) - .build(); - - Path appPath = shell.currentLocation().resolve(descriptor.targetPath); - shell.println("scaffolding app to `" + appPath.toAbsolutePath() + "` ..."); - - - boolean useGruntBower = false; - Path srvModulePath; - if (descriptor.useSrvuiLayout) { - Path uiModulePath = appPath.resolve("ui"); - rootMainTemplates.generate(appPath, scope); - - if ("yo".equalsIgnoreCase(descriptor.boostrapUIOption)) { - shell.println("you can scaffold ui with yeoman in `" + uiModulePath - + "` using `yo " + descriptor.boostrapUITemplate + "`"); - // calling yo directly would be better, but yo is interactive, so we need to use INHERIT redirect - // input which closes stdin at the end of the process :( - - useGruntBower = true; // assume users with yo will use grunt and bower - } else if ("restx".equalsIgnoreCase(descriptor.boostrapUIOption)) { - shell.println("scaffolding ui with restx in `" + uiModulePath + "` ..."); - - Path uitplsPath = shell.installLocation().resolve("plugins/templates/ui"); - File tplDir = uitplsPath.resolve(descriptor.boostrapUITemplate).toFile(); - if (!tplDir.exists()) { - URL tplZipURL = new URL(uiTemplatesPackageLocations.get(descriptor.boostrapUITemplate)); - uitplsPath.toFile().mkdirs(); - shell.println("downloading UI template"); - File zipFile = uitplsPath.resolve(descriptor.boostrapUITemplate + ".zip").toFile(); - shell.download(tplZipURL, zipFile); - - extractZip(zipFile, tplDir); - if (tplDir.list().length == 1 && tplDir.listFiles()[0].isDirectory()) { - // zip has a single root directory, we remove it - File dir = tplDir.listFiles()[0]; - File[] files = dir.listFiles(); - for (int i = 0; i < files.length; i++) { - File file = files[i]; - Files.move(file, new File(tplDir, file.getName())); - } - dir.delete(); - } - } - - Archetype.buildArchetype(tplDir.toPath()).generate(uiModulePath, scope); - useGruntBower = uiModulePath.resolve("bower.json").toFile().exists(); - } - - if (useGruntBower) { - rootGruntBowerTemplates.generate(appPath, scope); - } else { - rootNoNodeTemplates.generate(appPath, scope); - } - - srvModulePath = appPath.resolve("srv"); - shell.println("scaffolding srv with restx in `" + srvModulePath + "` ..."); - } else { - srvModulePath = appPath; - } - - srvMainTemplates.generate(srvModulePath, scope); - if (descriptor.buildFiles.contains(ModuleDescriptorType.IVY)) { - shell.println("generating module.ivy ..."); - RestxBuild.convert(srvModulePath.toAbsolutePath() + "/md.restx.json", srvModulePath.toAbsolutePath() + "/module.ivy"); - } - if (descriptor.buildFiles.contains(ModuleDescriptorType.MAVEN)) { - shell.println("generating pom.xml ..."); - RestxBuild.convert(srvModulePath.toAbsolutePath() + "/md.restx.json", srvModulePath.toAbsolutePath() + "/pom.xml"); - } - // We remove md.restx.json file *after* having generated pom and/or ivy file as it is needed for their generation - if (!descriptor.buildFiles.contains(ModuleDescriptorType.RESTX)) { - shell.println("removing md.restx.json ..."); - srvModulePath.resolve(ModuleDescriptorType.RESTX.getDescriptorFileName()).toFile().delete(); - } - - if (descriptor.generateHelloResource) { - shell.println("generating hello resource ..."); - srvHelloResourceTemplates.generate(srvModulePath, scope); - } - - shell.printIn("Congratulations! - Your app is now ready in " + appPath.toAbsolutePath(), RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(""); - shell.println(""); - - if (descriptor.useSrvuiLayout) { - shell.println("Your app has 2 modules: ui and srv\n" + - "In srv, you can:\n" + - " - open the module in your IDE by importing the Maven pom, and run the \n" + - " `" + descriptor.mainPackage + ".AppServer` class to launch\n" + - " - run it from restx shell, using:\n" + - " deps install\n" + - " to install its dependencies\n" + - " app run\n" + - " to run it\n"); - if (useGruntBower) { - shell.println( - "In ui you can:\n" + - " - open and edit your front end source files with your favorite editor\n" + - " - install local grunt with\n" + - " npm install\n" + - " - install app frontend dependencies listed in bower.json with\n" + - " bower install\n" + - " - run development server with:\n" + - " grunt server\n" - ); - } else { - shell.println( - "In ui you can:\n" + - " - open and edit your front end source files with your favorite editor\n" + - " - copy files to `dist` directory to make them available to RESTX web server\n" + - " hint: you can use the build.sh for that\n"); - } - shell.println( - "At root level you can:\n" + - " - build a production ready war using Maven (Linux/MacOS only):\n" + - " mvn package"); - } else { - shell.println("You can now:\n" + - " - open the app in your IDE by importing the Maven pom, and run the \n" + - " `" + descriptor.mainPackage + ".AppServer` class to launch\n" + - " - run it from restx shell, using:\n" + - " deps install\n" + - " to install its dependencies\n" + - " app run\n" + - " to run it\n" + - " - build a war using the selected build tool, eg\n" + - " mvn package"); - } - - shell.printIn("Enjoy!", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(""); - - return srvModulePath; - } - } - - private class CompileAppCommandRunner implements ShellCommandRunner { - private ShellAppRunner.CompileMode compileMode = ShellAppRunner.CompileMode.ALL; - - public CompileAppCommandRunner(List args) { - } - - @Override - public void run(RestxShell shell) throws Exception { - AppSettings appSettings = shell.getFactory() - .getComponent(AppSettings.class); - compileMode.compile( - shell, - Paths.get(appSettings.targetClasses()), - Paths.get(appSettings.targetDependency()), - Paths.get(appSettings.mainSources()), - Paths.get(appSettings.mainResources()), - null); - } - } - - private class GenerateStartCommandRunner implements ShellCommandRunner { - private String appClassName; - - public GenerateStartCommandRunner(List args) { - if (args.size() > 2) { - appClassName = args.get(2); - } - } - - @Override - public void run(RestxShell shell) throws Exception { - AppSettings appSettings = shell.getFactory() - .getComponent(AppSettings.class); - Optional pack = Optional.absent(); - if (appClassName == null) { - pack = Apps.with(appSettings) - .guessAppBasePackage(shell.currentLocation()); - if (!pack.isPresent()) { - shell.printIn("can't find base app package, src/main/java should contain a AppServer.java source file somewhere", - RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - shell.println("alternatively you can provide the class to run with `app generate-start-script `"); - return; - } - appClassName = pack.get() + ".AppServer"; - } else { - pack = Optional.of(appClassName.substring(0, appClassName.lastIndexOf('.'))); - } - - - File startSh = shell.currentLocation().resolve("start.sh").toFile(); - Files.write( - "#!/bin/sh\n\n" + - getCommand(appSettings, pack, ":") + " $VM_OPTIONS " + - " " + appClassName + "\n", - startSh, Charsets.UTF_8); - startSh.setExecutable(true); - - File startBat = shell.currentLocation().resolve("start.bat").toFile(); - Files.write( - getCommand(appSettings, pack, ";") + " %VM_OPTIONS% " + - " " + appClassName + "\r\n", - startBat, Charsets.ISO_8859_1); - - shell.printIn("generated start scripts:\n" + - "\t" + startSh.getAbsolutePath() + "\n" + - "\t" + startBat.getAbsolutePath() + "\n", - RestxShell.AnsiCodes.ANSI_GREEN); - } - - protected String getCommand(AppSettings appSettings, Optional pack, String pathSeparator) { - return "java" + - " -cp \"" + appSettings.targetClasses() + pathSeparator + appSettings.targetDependency() + "/*\"" + - " -Drestx.app.package=" + pack.get() + - " -Drestx.mode=prod"; - } - } - - private class RunAppCommandRunner implements ShellCommandRunner { - private Optional appClassNameArg; - private Optional appNameArg; - private boolean quiet; - private boolean daemon; - private Optional restxMode; - private List vmOptions = new ArrayList<>(); - - public RunAppCommandRunner(List args) { - args = new ArrayList<>(args); - quiet = false; - daemon = true; - appClassNameArg = Optional.absent(); - appNameArg = Optional.absent(); - restxMode = Optional.absent(); - - while (args.size() > 2) { - String arg = args.get(2); - if (arg.equalsIgnoreCase("--quiet")) { - quiet = true; - } else if (arg.startsWith("--fg")) { - daemon = false; - } else if (arg.startsWith("--mode=") || arg.startsWith("-Drestx.mode=")) { - String mode = arg.startsWith("--mode=")?arg.substring("--mode=".length()):arg.substring("-Drestx.mode=".length()); - restxMode = Optional.of(mode); - } else if (arg.startsWith("-D") || arg.startsWith("-X")) { - vmOptions.add(arg); - } else if (!appClassNameArg.isPresent() && !appNameArg.isPresent()) { - // If an existing restx app folder stands for given arg, considering it as the appName - // otherwise, arg will stand for a classname to execute - if(java.nio.file.Files.exists(standardCachedAppPath(arg))) { - appNameArg = Optional.of(arg); - restxMode = Optional.of(restxMode.or(RestxContext.Modes.PROD)); - } else { - appClassNameArg = Optional.of(arg); - } - } else { - throw new IllegalArgumentException("app run argument not recognized: " + arg); - } - args.remove(2); - } - } - - @Override - public void run(final RestxShell shell) throws Exception { - Path shellInitialLocation = shell.currentLocation(); - if(appNameArg.isPresent()) { - shell.cd(standardCachedAppPath(appNameArg.get())); - } - - if(!ModuleDescriptorType.RESTX.resolveDescriptorFile(shell.currentLocation()).exists()) { - - Path srvDir = shell.currentLocation().resolve("srv"); - if(srvDir.toFile().exists()) { - shell.cd(srvDir); - if(!ModuleDescriptorType.RESTX.resolveDescriptorFile(shell.currentLocation()).exists()) { - shell.println(String.format("Cannot find %s in both %s and %s", - ModuleDescriptorType.RESTX.getDescriptorFileName(), - shell.currentLocation().getParent().toAbsolutePath(), - shell.currentLocation().toAbsolutePath())); - shell.println("=> Cannot run application"); - return; - } - } else { - shell.println(String.format("Cannot find %s in %s", - ModuleDescriptorType.RESTX.getDescriptorFileName(), - shell.currentLocation().toAbsolutePath())); - shell.println("=> Cannot run application"); - return; - } - } - - boolean sourcesAvailable = Apps.with(shell.getFactory().getComponent(AppSettings.class)).sourcesAvailableIn(shell.currentLocation()); - - String appClassName; - ShellAppRunner.CompileMode compileMode; - if(sourcesAvailable) { - if(appClassNameArg.isPresent()) { - appClassName = appClassNameArg.get(); - } else { - Optional appClassNameGuessedFromRestxModule = guessAppClassnameFromRestxModule(shell); - if(appClassNameGuessedFromRestxModule.isPresent()) { - appClassName = appClassNameGuessedFromRestxModule.get(); - } else { - appClassName = guessAppClassnameFromSources(shell); - } - } - - compileMode = (restxMode.isPresent() && RestxContext.Modes.PROD.equals(restxMode.get()))? ShellAppRunner.CompileMode.ALL: ShellAppRunner.CompileMode.MAIN_CLASS; - - if(appClassName == null) { - shell.printIn("can't find base app package, src/main/java should contain a AppServer.java source file somewhere", - RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - shell.println("alternatively you can provide the class to run with `app run `"); - return; - } - } else { - appClassName = appClassNameArg - .or(guessAppClassnameFromRestxModule(shell)) - .orNull(); - - // Consider we're in prod mode, without any auto compilation feature (since we don't have any source folder) - compileMode = ShellAppRunner.CompileMode.NO; - restxMode = Optional.of(RestxContext.Modes.PROD); - - if(appClassName == null){ - shell.printIn("can't find manifest.main.classname property in md.restx.json", RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - shell.println("alternatively you can provide the class to run with `app run `"); - return; - } - } - - if (!DepsShellCommand.depsUpToDate(shell)) { - shell.println("restx> deps install"); - new DepsShellCommand.InstallDepsCommandRunner().run(shell); - } - - List vmOptions = new ArrayList<>(this.vmOptions); - if(restxMode.isPresent()) { - vmOptions.add("-Drestx.mode="+restxMode.get()); - } - - String basePack = appClassName.substring(0, appClassName.lastIndexOf('.')); - AppSettings appSettings = shell.getFactory() - .concat(new SingletonFactoryMachine<>(-10000, NamedComponent.of(String.class, "restx.app.package", basePack))) - .getComponent(AppSettings.class); - new ShellAppRunner(appSettings, appClassName, compileMode, quiet, daemon, vmOptions) - .run(shell); - - // Moving back to initial location in case we either moved in cached apps or srv directory - shell.cd(shellInitialLocation); - } - - private Optional guessAppClassnameFromRestxModule(RestxShell shell) throws IOException { - - RestxJsonSupport restxJsonSupport = new RestxJsonSupport(); - - Path restxJsonFile = shell.currentLocation().resolve(restxJsonSupport.getDefaultFileName()); - if(java.nio.file.Files.notExists(restxJsonFile)){ - return Optional.absent(); - } - - ModuleDescriptor moduleDescriptor = restxJsonSupport.parse(restxJsonFile); - return Optional.fromNullable(moduleDescriptor.getProperties().get("manifest.main.classname")); - } - - private String guessAppClassnameFromSources(RestxShell shell) { - Optional pack = Apps.with(shell.getFactory().getComponent(AppSettings.class)) - .guessAppBasePackage(shell.currentLocation()); - if (!pack.isPresent()) { - return null; - } - return pack.get() + ".AppServer"; - } - } - - private static enum GrabbingStrategy { - FROM_GIT(){ - @Override - protected boolean accept(String coordinates) { - return coordinates.endsWith(".git"); - } - - @Override - public String extractProjectNameFrom(String coordinates) { - return extractExtensionlessFilenameFromUrl(coordinates.split("#")[0]); - } - - @Override - public void unpackCoordinatesTo(String coordinates, Path destinationDir, String projectName, RestxShell shell) throws IOException { - String url = coordinates; - Optional ref = Optional.absent(); - if(url.contains("#")) { - url = coordinates.split("#")[0]; - ref = Optional.of(coordinates.split("#")[1]); - } - - try { - shell.println("Cloning "+url+"..."); - Runtime.getRuntime().exec(new String[]{"git", "clone", url, "."}, new String[0], destinationDir.toFile()).waitFor(); - - if(ref.isPresent()) { - Runtime.getRuntime().exec(new String[]{"git", "checkout", ref.get()}, new String[0], destinationDir.toFile()).waitFor(); - } - } catch(InterruptedException e) { - throw Throwables.propagate(e); - } - } - }, FROM_URL(){ - @Override - protected boolean accept(String coordinates) { - return coordinates.startsWith("file://") - || coordinates.startsWith("http://") - || coordinates.startsWith("https://"); - } - @Override - public String extractProjectNameFrom(String coordinates) { - return extractExtensionlessFilenameFromUrl(coordinates); - } - @Override - public void unpackCoordinatesTo(String coordinates, Path destinationDir, String projectName, RestxShell shell) throws IOException { - handleSingleFileGrabbing(coordinates, destinationDir, projectName, shell, new SingleFileGrabber() { - @Override - public void grabSingleFileTo(String coordinates, Path destinationFile, RestxShell shell) throws IOException { - try { - URL url = new URL(coordinates); - try (InputStream urlStream = url.openStream(); - OutputStream destFileOS = newOutputStream(destinationFile)) { - ByteStreams.copy(urlStream, destFileOS); - } - } catch (MalformedURLException e) { - throw Throwables.propagate(e); - } - } - }); - } - }, FROM_GAV(){ - @Override - protected boolean accept(String coordinates) { - return ModulesManager.isMrid(coordinates); - } - @Override - public String extractProjectNameFrom(String coordinates) { - return ModulesManager.toMrid(coordinates).getName(); - } - @Override - public void unpackCoordinatesTo(String coordinates, final Path destinationDir, String projectName, RestxShell shell) throws IOException { - handleSingleFileGrabbing(coordinates, destinationDir, projectName, shell, new SingleFileGrabber() { - @Override - public void grabSingleFileTo(String coordinates, Path destinationFile, RestxShell shell) throws IOException { - restx.plugins.ModuleDescriptor moduleDescriptor = new restx.plugins.ModuleDescriptor(coordinates, "app", ""); - ModulesManager modulesManager = new ModulesManager(null, ShellIvy.loadIvy(shell)); - - List files = modulesManager.download( - ImmutableList.of(moduleDescriptor), - destinationDir.toFile(), - new ModulesManager.DownloadOptions.Builder().transitive(false).build() - ); - if(!files.get(0).equals(destinationFile.toFile())) { - Files.move(files.get(0), destinationFile.toFile()); - } - } - }); - } - }; - - public static Optional fromCoordinates(String coordinates) { - for(GrabbingStrategy grabbingStrategy : values()){ - if(grabbingStrategy.accept(coordinates)) { - return Optional.of(grabbingStrategy); - } - } - return Optional.absent(); - } - - private static interface SingleFileGrabber { - void grabSingleFileTo(String coordinates, Path destinationFile, RestxShell shell) throws IOException; - } - - protected void handleSingleFileGrabbing(String coordinates, Path destinationDir, String projectName, RestxShell shell, SingleFileGrabber singleFileGrabber) throws IOException { - Path jarFile = destinationDir.resolve(projectName+".jar"); - Files.createParentDirs(jarFile.toFile()); - - singleFileGrabber.grabSingleFileTo(coordinates, jarFile, shell); - - AppSettings appSettings = shell.getFactory().getComponent(AppSettings.class); - new RestxArchive(jarFile).unpack(destinationDir, appSettings); - jarFile.toFile().delete(); - } - - protected static String extractExtensionlessFilenameFromUrl(String coordinates) { - String filename = coordinates.substring(coordinates.lastIndexOf("/")+1); - filename = filename.contains("?")?filename.substring(0, filename.indexOf("?")):filename; - filename = filename.contains(".")?filename.substring(0, filename.lastIndexOf(".")):filename; - return filename; - } - - protected abstract boolean accept(String coordinates); - public abstract String extractProjectNameFrom(String coordinates); - public abstract void unpackCoordinatesTo(String coordinates, Path destinationDir, String projectName, RestxShell shell) throws IOException; - } - - private class GrabAppCommandRunner implements ShellCommandRunner { - - private final String projectName; - private final String coordinates; - private final GrabbingStrategy grabbingStrategy; - private final Path destinationDirectoy; - - public GrabAppCommandRunner(List args) { - args = new ArrayList<>(args); - - if(args.size() < 3) { - throw new IllegalArgumentException("app grab : missing coordinates argument"); - } - - this.coordinates = args.get(2); - this.grabbingStrategy = checkPresent(GrabbingStrategy.fromCoordinates(this.coordinates), - "app grab : cannot found a grabbing strategy for coordinates: " + this.coordinates); - - this.projectName = this.grabbingStrategy.extractProjectNameFrom(this.coordinates); - this.destinationDirectoy = args.size() >= 4 ? Paths.get(args.get(3)) : standardCachedAppPath(projectName); - } - - @Override - public void run(RestxShell shell) throws Exception { - Files.createParentDirs(destinationDirectoy.resolve("uselessUnexistingFile").toFile()); - - this.grabbingStrategy.unpackCoordinatesTo(this.coordinates, this.destinationDirectoy, this.projectName, shell); - - shell.cd(destinationDirectoy); - } - } - - private class ArchiveAppCommandRunner implements ShellCommandRunner { - private final Path jarFile; - - public ArchiveAppCommandRunner(List args) { - if(args.size() < 3) { - throw new IllegalArgumentException("app archive : missing jarFile argument"); - } - - this.jarFile = Paths.get(args.get(2)); - } - - @Override - public void run(RestxShell shell) throws Exception { - AppSettings appSettings = shell.getFactory().getComponent(AppSettings.class); - new RestxArchive(jarFile).pack( - shell.currentLocation(), - shell.currentLocation().resolve(appSettings.targetClasses()), - Arrays.asList("target", "tmp", "logs") - ); - } - } -} diff --git a/restx-core-shell/src/main/java/restx/core/shell/DepsShellCommand.java b/restx-core-shell/src/main/java/restx/core/shell/DepsShellCommand.java deleted file mode 100644 index eaeecf2bd..000000000 --- a/restx-core-shell/src/main/java/restx/core/shell/DepsShellCommand.java +++ /dev/null @@ -1,293 +0,0 @@ -package restx.core.shell; - -import com.google.common.base.*; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableList; -import com.google.common.hash.Hashing; -import com.google.common.io.Files; -import jline.console.completer.ArgumentCompleter; -import jline.console.completer.Completer; -import jline.console.completer.StringsCompleter; -import org.apache.ivy.Ivy; -import org.apache.ivy.core.report.ResolveReport; -import org.apache.ivy.core.retrieve.RetrieveOptions; -import restx.AppSettings; -import restx.build.*; -import restx.build.ModuleDescriptor; -import restx.factory.Component; -import restx.plugins.*; -import restx.shell.*; - -import java.io.*; -import java.net.URL; -import java.nio.file.FileVisitResult; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.List; - -import static java.util.Arrays.asList; - -/** - * User: xavierhanin - * Date: 4/10/13 - * Time: 8:53 PM - */ -@Component -public class DepsShellCommand extends StdShellCommand { - private static final String MVN_COMMAND = "mvn"; - - public DepsShellCommand() { - super(ImmutableList.of("deps"), "deps related commands: install / update / manage app dependencies"); - } - - @Override - protected String resourceMan() { - return "restx/core/shell/deps.man"; - } - - @Override - protected Optional doMatch(String line) { - List args = splitArgs(line); - - if (args.size() < 2) { - return Optional.absent(); - } - - switch (args.get(1)) { - case "install": - return Optional.of(new InstallDepsCommandRunner()); - case "add": - return Optional.of(new AddDepsCommandRunner(args)); - } - - return Optional.absent(); - } - - @Override - public Iterable getCompleters() { - return ImmutableList.of(new ArgumentCompleter( - new StringsCompleter("deps"), new StringsCompleter("install", "add"))); - } - - public static class InstallDepsCommandRunner implements ShellCommandRunner { - - @Override - public void run(RestxShell shell) throws Exception { - Optional moduleDescriptorTypeWithExistingFileOpt = ModuleDescriptorType.firstModuleDescriptorTypeWithExistingFile(shell.currentLocation()); - if(!moduleDescriptorTypeWithExistingFileOpt.isPresent()) { - throw new IllegalStateException( - "md.restx.json file not found in " + shell.currentLocation() + "." + - " It is required to perform deps management"); - } - - ModuleDescriptorType moduleDescriptorTypeWithExistingFile = moduleDescriptorTypeWithExistingFileOpt.get(); - if(ModuleDescriptorType.RESTX.equals(moduleDescriptorTypeWithExistingFile)) { - shell.println("installing deps using restx module descriptor..."); - installDepsFromModuleDescriptor(shell, ModuleDescriptorType.RESTX.resolveDescriptorFile(shell.currentLocation())); - } else if(ModuleDescriptorType.MAVEN.equals(moduleDescriptorTypeWithExistingFile)) { - shell.println("installing deps using maven descriptor..."); - installDepsFromMavenDescriptor(shell, ModuleDescriptorType.MAVEN.resolveDescriptorFile(shell.currentLocation())); - } else if(ModuleDescriptorType.IVY.equals(moduleDescriptorTypeWithExistingFile)) { - shell.println("installing deps using ivy descriptor..."); - installDepsFromIvyDescriptor(shell, ModuleDescriptorType.IVY.resolveDescriptorFile(shell.currentLocation())); - } else { - throw new IllegalArgumentException("Unsupported deps install for module type "+moduleDescriptorTypeWithExistingFile); - } - - storeModuleDescriptorMD5File(shell, moduleDescriptorTypeWithExistingFile); - - shell.println("DONE"); - } - - private void installDepsFromModuleDescriptor(RestxShell shell, File mdFile) throws Exception { - File tempFile = File.createTempFile("restx-md", ".ivy"); - try (FileInputStream is = new FileInputStream(mdFile)) { - ModuleDescriptor descriptor = new RestxJsonSupport().parse(is); - try (BufferedWriter w = Files.newWriter(tempFile,Charsets.UTF_8)) { - new IvySupport().generate(descriptor, w); - } - - installDepsFromIvyDescriptor(shell, tempFile); - } finally { - tempFile.delete(); - } - } - - private void installDepsFromIvyDescriptor(RestxShell shell, File ivyFile) throws Exception { - Ivy ivy = ShellIvy.loadIvy(shell); - - shell.println("resolving dependencies..."); - ResolveReport resolveReport = ivy.resolve(ivyFile); - - shell.println("synchronizing dependencies in " + shell.currentLocation().resolve("target/dependency") + " ..."); - ivy.retrieve(resolveReport.getModuleDescriptor().getModuleRevisionId(), - new RetrieveOptions() - .setDestArtifactPattern( - shell.currentLocation().toAbsolutePath() + "/target/dependency/[artifact]-[revision](-[classifier]).[ext]") - .setSync(true) - ); - } - - private void installDepsFromMavenDescriptor(RestxShell shell, File pomFile) throws Exception { - AppSettings appSettings = shell.getFactory().getComponent(AppSettings.class); - - Path dependenciesDir = Paths.get(appSettings.targetDependency()); - - // Emptying target dependencies directory first - if(dependenciesDir.toFile().exists()) { - java.nio.file.Files.walkFileTree(dependenciesDir, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - java.nio.file.Files.delete(file); - return FileVisitResult.CONTINUE; - } - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - java.nio.file.Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }); - } - - dependenciesDir.toFile().mkdirs(); - - // Then copying dependencies through copy-dependencies plugin - ProcessBuilder mavenCmd = new ProcessBuilder( - MVN_COMMAND, "org.apache.maven.plugins:maven-dependency-plugin:3.0.1:copy-dependencies", - "-DoutputDirectory=" + dependenciesDir.toAbsolutePath(), "-DincludeScope=runtime" - ); - - shell.println("Executing `"+mavenCmd+"` ..."); - try { - mavenCmd.redirectErrorStream(true) - .redirectOutput(ProcessBuilder.Redirect.INHERIT) - .directory(shell.currentLocation().toFile().getAbsoluteFile()) - .start() - .waitFor(); - } catch(IOException e) { - if(e.getMessage().startsWith(String.format("Cannot run program \"%s\"", MVN_COMMAND))) { - shell.println("Looks like mvn is not installed here ... trying to fallback installing pom.xml file with Ivy..."); - installDepsFromIvyDescriptor(shell, pomFile); - } else { - Throwables.propagate(e); - } - } - } - - private static void storeModuleDescriptorMD5File(RestxShell shell, ModuleDescriptorType mdType) throws IOException { - File mdFile = mdType.resolveDescriptorFile(shell.currentLocation()); - File md5File = ModuleDescriptorType.MAVEN.resolveDescriptorMd5File(shell.currentLocation()); - - shell.println(String.format("Storing md5 file %s for module descriptor %s...", md5File.getAbsolutePath(), mdFile.getAbsolutePath())); - Files.write(Files.hash(mdFile, Hashing.md5()).toString(), md5File, Charsets.UTF_8); - } - } - - static class AddDepsCommandRunner implements ShellCommandRunner { - private final String scope; - private Optional> pluginIds; - - public AddDepsCommandRunner(List args) { - args = new ArrayList<>(args); - if (args.size() > 2 - && args.get(2).startsWith("scope:")) { - scope = args.get(2).substring("scope:".length()); - args.remove(2); - } else { - scope = "compile"; - } - - if (args.size() > 2) { - pluginIds = Optional.>of(new ArrayList<>(args.subList(2, args.size()))); - } else { - pluginIds = Optional.absent(); - } - } - - @Override - public void run(RestxShell shell) throws Exception { - File mdFile = ModuleDescriptorType.RESTX.resolveDescriptorFile(shell.currentLocation()); - if (!mdFile.exists()) { - throw new IllegalStateException( - "md.restx.json file not found in " + shell.currentLocation() + "." + - " It is required to perform deps management"); - } - - if (!pluginIds.isPresent()) { - ModulesManager modulesManager = new ModulesManager( - new URL("http://restx.io/modules"), ShellIvy.loadIvy(shell)); - - shell.println("looking for plugins..."); - List plugins = modulesManager.searchModules("category=app"); - - shell.printIn("found " + plugins.size() + " available plugins", RestxShell.AnsiCodes.ANSI_CYAN); - shell.println(""); - - for (int i = 0; i < plugins.size(); i++) { - restx.plugins.ModuleDescriptor plugin = plugins.get(i); - shell.printIn(String.format(" [%3d] %s%n", i + 1, plugin.getId()), RestxShell.AnsiCodes.ANSI_PURPLE); - shell.println("\t\t" + plugin.getDescription()); - } - - String sel = shell.ask("Which plugin would you like to add (eg '1 3 5')? \n" + - "You can also provide a plugin id in the form ::\n" + - " plugin to install: ", ""); - Iterable selected = Splitter.on(" ").trimResults().omitEmptyStrings().split(sel); - List ids = new ArrayList<>(); - for (String s : selected) { - if (CharMatcher.DIGIT.matchesAllOf(s)) { - ids.add(plugins.get(Integer.parseInt(s)).getId()); - } else { - ids.add(s); - } - } - - pluginIds = Optional.of(ids); - } - - ModuleDescriptor descriptor; - try (FileInputStream is = new FileInputStream(mdFile)) { - descriptor = new RestxJsonSupport().parse(is).getParsedModuleDescriptor(); - - for (String s : pluginIds.get()) { - descriptor = descriptor.concatDependency(scope, new ModuleDependency(GAV.parse(s))); - } - } - try (Writer w = Files.newWriter(mdFile, Charsets.UTF_8)) { - shell.println("updating " + mdFile); - new RestxJsonSupport().generate(descriptor, w); - } - - for (Path mod : RestxBuild.resolveForeignModuleDescriptorsIn(shell.currentLocation())) { - shell.printIn("updating " + mod, RestxShell.AnsiCodes.ANSI_PURPLE); - shell.println(""); - RestxBuild.convert(mdFile.toPath(), mod); - } - } - } - - public static boolean depsUpToDate(RestxShell shell) { - Optional moduleDescriptorTypeWithExistingFileOpt = ModuleDescriptorType.firstModuleDescriptorTypeWithExistingFile(shell.currentLocation()); - if(!moduleDescriptorTypeWithExistingFileOpt.isPresent()) { - // no dependency management at all - return true; - } - - ModuleDescriptorType moduleDescriptorTypeWithExistingFile = moduleDescriptorTypeWithExistingFileOpt.get(); - File descriptorFile = moduleDescriptorTypeWithExistingFile.resolveDescriptorFile(shell.currentLocation()); - File moduleDescriptorMd5 = moduleDescriptorTypeWithExistingFile.resolveDescriptorMd5File(shell.currentLocation()); - if(!moduleDescriptorMd5.exists()) { - return false; - } - - try { - String md5 = Files.hash(descriptorFile, Hashing.md5()).toString(); - return md5.equals(Files.toString(moduleDescriptorMd5, Charsets.UTF_8)); - } catch (IOException e) { - return false; - } - } -} diff --git a/restx-core-shell/src/main/java/restx/core/shell/HashShellCommand.java b/restx-core-shell/src/main/java/restx/core/shell/HashShellCommand.java deleted file mode 100644 index fd9a0382f..000000000 --- a/restx-core-shell/src/main/java/restx/core/shell/HashShellCommand.java +++ /dev/null @@ -1,100 +0,0 @@ -package restx.core.shell; - -import com.google.common.base.CharMatcher; -import com.google.common.base.Charsets; -import com.google.common.base.Optional; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableList; -import com.google.common.hash.Hashing; -import com.google.common.io.Files; -import jline.console.completer.ArgumentCompleter; -import jline.console.completer.Completer; -import jline.console.completer.StringsCompleter; -import org.apache.ivy.Ivy; -import org.apache.ivy.core.report.ResolveReport; -import org.apache.ivy.core.retrieve.RetrieveOptions; -import org.mindrot.jbcrypt.BCrypt; -import restx.build.*; -import restx.factory.Component; -import restx.plugins.ModulesManager; -import restx.shell.RestxShell; -import restx.shell.ShellCommandRunner; -import restx.shell.ShellIvy; -import restx.shell.StdShellCommand; - -import java.io.*; -import java.net.URL; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import static java.util.Arrays.asList; - -/** - * User: xavierhanin - * Date: 4/10/13 - * Time: 8:53 PM - */ -@Component -public class HashShellCommand extends StdShellCommand { - public HashShellCommand() { - super(ImmutableList.of("hash"), "hash commands, to easily generate password hashes"); - } - - @Override - protected String resourceMan() { - return "restx/core/shell/hash.man"; - } - - @Override - protected Optional doMatch(String line) { - List args = splitArgs(line); - - if (args.size() < 3) { - return Optional.absent(); - } - - return Optional.of(new HashCommandRunner(args.get(1), args.get(2))); - } - - @Override - public Iterable getCompleters() { - return ImmutableList.of(new ArgumentCompleter( - new StringsCompleter("hash"), - new StringsCompleter("md5", "sha1", "bcrypt", "md5+bcrypt", "sha1+bcrypt"))); - } - - private class HashCommandRunner implements ShellCommandRunner { - private final String hash; - private final String plaintext; - - public HashCommandRunner(String hash, String plaintext) { - this.hash = hash; - this.plaintext = plaintext; - } - - @Override - public void run(RestxShell shell) throws Exception { - switch (hash) { - case "md5": - shell.println(Hashing.md5().hashString(plaintext, Charsets.UTF_8).toString()); - break; - case "sha1": - shell.println(Hashing.sha1().hashString(plaintext, Charsets.UTF_8).toString()); - break; - case "bcrypt": - shell.println(BCrypt.hashpw(plaintext, BCrypt.gensalt())); - break; - case "md5+bcrypt": - shell.println(BCrypt.hashpw(Hashing.md5().hashString(plaintext, Charsets.UTF_8).toString(), BCrypt.gensalt())); - break; - case "sha1+bcrypt": - shell.println(BCrypt.hashpw(Hashing.sha1().hashString(plaintext, Charsets.UTF_8).toString(), BCrypt.gensalt())); - break; - default: - shell.printIn("unknown hash function: " + hash, RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - } - } - } -} diff --git a/restx-core-shell/src/main/java/restx/core/shell/ModuleDescriptorType.java b/restx-core-shell/src/main/java/restx/core/shell/ModuleDescriptorType.java deleted file mode 100644 index e33c04d46..000000000 --- a/restx-core-shell/src/main/java/restx/core/shell/ModuleDescriptorType.java +++ /dev/null @@ -1,43 +0,0 @@ -package restx.core.shell; - -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.collect.FluentIterable; - -import java.io.File; -import java.nio.file.Path; -import java.util.Arrays; - -public enum ModuleDescriptorType { - RESTX("md.restx.json"), MAVEN("pom.xml"), IVY("module.ivy"); - - private String descriptorFileName; - - ModuleDescriptorType(String descriptorFileName) { - this.descriptorFileName = descriptorFileName; - } - - public String getDescriptorFileName() { - return descriptorFileName; - } - - public File resolveDescriptorFile(Path inDirectory) { - return inDirectory.resolve(this.getDescriptorFileName()).toFile(); - } - - public File resolveDescriptorMd5File(Path inDirectory) { - return inDirectory.resolve(String.format("target/dependency/%s.md5", this.getDescriptorFileName())).toFile(); - } - - public static Optional firstModuleDescriptorTypeWithExistingFile(final Path inDirectory) { - return FluentIterable - .from(Arrays.asList(ModuleDescriptorType.RESTX, ModuleDescriptorType.MAVEN)) - .filter(new Predicate() { - @Override - public boolean apply(ModuleDescriptorType mdType) { - return mdType.resolveDescriptorFile(inDirectory).exists(); - } - }).first(); - } - -} diff --git a/restx-core-shell/src/main/java/restx/core/shell/RestxArchive.java b/restx-core-shell/src/main/java/restx/core/shell/RestxArchive.java deleted file mode 100644 index 242b782c9..000000000 --- a/restx-core-shell/src/main/java/restx/core/shell/RestxArchive.java +++ /dev/null @@ -1,171 +0,0 @@ -package restx.core.shell; - -import com.google.common.base.Splitter; -import com.google.common.base.Throwables; -import com.google.common.collect.Iterables; -import restx.AppSettings; -import restx.build.RestxBuild; - -import java.io.*; -import java.nio.file.*; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.*; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.JarOutputStream; - -/** - * @author fcamblor - */ -public class RestxArchive { - - private static final String CHROOT = "META-INF/restx/app/"; - private Path jarFile; - - public RestxArchive(Path jarFile) { - this.jarFile = jarFile; - } - - private static class JarCopierFileVisitor extends SimpleFileVisitor { - private final Path startingDirectory; - private final String targetDirPrefix; - private List excludes; - private final JarOutputStream jarOS; - - private JarCopierFileVisitor(Path startingDirectory, JarOutputStream jarOS, String targetDirPrefix, List excludes) { - this.startingDirectory = startingDirectory; - this.jarOS = jarOS; - this.targetDirPrefix = targetDirPrefix; - this.excludes = excludes; - } - - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - super.preVisitDirectory(dir, attrs); - - String directoryRelativizedName = startingDirectory.relativize(dir).toString().replace("\\", "/"); - if(!directoryRelativizedName.isEmpty()) { - if(!directoryRelativizedName.endsWith("/")) { - directoryRelativizedName += "/"; - } - - for(String exclude : excludes){ - if(directoryRelativizedName.startsWith(exclude)){ - return FileVisitResult.SKIP_SUBTREE; - } - } - - String targetDirectoryPath = targetDirPrefix + directoryRelativizedName; - - JarEntry dirEntry = new JarEntry(targetDirectoryPath); - dirEntry.setTime(Files.getLastModifiedTime(dir).toMillis()); - jarOS.putNextEntry(dirEntry); - jarOS.closeEntry(); - } - - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - super.visitFile(file, attrs); - - copyFileToJar(jarOS, startingDirectory, targetDirPrefix, file); - - return FileVisitResult.CONTINUE; - } - } - - private static void createJarDirIfNotExists(JarOutputStream jarOS, Path rootDir, String path) throws IOException { - if(!Files.exists(rootDir.resolve(path))){ - JarEntry dirEntry = new JarEntry(path+"/"); - jarOS.putNextEntry(dirEntry); - jarOS.closeEntry(); - } - } - - private static void copyFileToJar(JarOutputStream jarOS, Path rootDir, String targetDirPrefix, Path file) throws IOException { - JarEntry fileEntry = new JarEntry(targetDirPrefix + rootDir.relativize(file).toString()); - - try { fileEntry.setTime(Files.getLastModifiedTime(file).toMillis()); } - catch (IOException e) {} - - jarOS.putNextEntry(fileEntry); - Files.copy(file, jarOS); - jarOS.closeEntry(); - } - - public void pack(Path workingDirectory, final Path targetClassesDirectory, List packagingExcludes) { - try(final JarOutputStream jarOS = new JarOutputStream(new FileOutputStream(jarFile.toFile()))) { - - // Generating md.restx.json if it doesn't exist yet - // Because a restx archive without this descriptor won't be considered as valid restx archive - Path md = workingDirectory.resolve("md.restx.json"); - boolean generatedMd = false; - if(!Files.exists(md)){ - List foreignModuleDescriptors = RestxBuild.resolveForeignModuleDescriptorsIn(workingDirectory); - if(!foreignModuleDescriptors.isEmpty()) { - Path firstModuleDescriptor = Iterables.getFirst(foreignModuleDescriptors, null); - RestxBuild.convert(firstModuleDescriptor, md); - generatedMd = true; - } else { - throw new RuntimeException("Project descriptor (either a md.restx.json, or a foreign descriptor (pom, ivy, ...) file) is missing !"); - } - } - - try { - Files.walkFileTree(targetClassesDirectory, new JarCopierFileVisitor(targetClassesDirectory, jarOS, "", Collections.emptyList())); - - // Ensuring CHROOT is made available in target jar - String path = ""; - for(String chrootChunk : Splitter.on("/").split(CHROOT)){ - if(!chrootChunk.isEmpty()) { - path += chrootChunk; - createJarDirIfNotExists(jarOS, targetClassesDirectory, path); - path += "/"; - } - } - - // Copying everything into CHROOT directory - Files.walkFileTree(workingDirectory, new JarCopierFileVisitor(workingDirectory, jarOS, CHROOT, packagingExcludes)); - } finally { - if(generatedMd) { - md.toFile().delete(); - } - } - } catch (IOException e) { - Throwables.propagate(e); - } - } - - public void unpack(Path destinationDirectory, AppSettings appSettings) { - Path targetClassesDir = destinationDirectory.resolve(appSettings.targetClasses()); - try ( JarFile jar = new JarFile(jarFile.toFile()) ) { - if(jar.getJarEntry(CHROOT+"md.restx.json") == null) { - throw new IllegalArgumentException("File "+jarFile+" is not a restx archive (no md.restx.json file found) !"); - } - for(Enumeration jarEntries = jar.entries(); jarEntries.hasMoreElements();){ - JarEntry entry = jarEntries.nextElement(); - String entryPath = entry.getName(); - if(!entry.isDirectory()) { - Path destinationFile; - // Unpacking chrooted files in app root directory.. - if(entryPath.startsWith(CHROOT)) { - Path chrootedFile = destinationDirectory.resolve(entryPath.substring(CHROOT.length())); - destinationFile = chrootedFile; - // ... and unpacking other files in classes directory - } else { - destinationFile = targetClassesDir.resolve(entryPath); - } - - com.google.common.io.Files.createParentDirs(destinationFile.toFile()); - try(InputStream jarInputStream = jar.getInputStream(entry)) { - Files.copy(jarInputStream, destinationFile); - } - } - } - } catch (IOException e) { - throw Throwables.propagate(e); - } - } -} diff --git a/restx-core-shell/src/main/java/restx/core/shell/ShellAppRunner.java b/restx-core-shell/src/main/java/restx/core/shell/ShellAppRunner.java deleted file mode 100644 index 20661aad5..000000000 --- a/restx-core-shell/src/main/java/restx/core/shell/ShellAppRunner.java +++ /dev/null @@ -1,182 +0,0 @@ -package restx.core.shell; - -import com.google.common.base.Charsets; -import com.google.common.base.Joiner; -import com.google.common.io.Files; -import restx.AppSettings; -import restx.Apps; -import restx.shell.RestxShell; - -import java.io.File; -import java.io.IOException; -import java.nio.file.FileVisitResult; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static restx.common.MoreFiles.copyDir; - -/** - * User: xavierhanin - * Date: 9/8/13 - * Time: 2:48 PM - */ -public class ShellAppRunner { - public static enum CompileMode { - NO { - @Override - boolean compile(RestxShell shell, Path targetClasses, Path dependenciesDir, Path mainSources, Path mainResources, String className) throws IOException, InterruptedException { - return true; - } - }, - RESOURCES_ONLY { - @Override - boolean compile(RestxShell shell, Path targetClasses, Path dependenciesDir, Path mainSources, Path mainResources, String className) throws IOException, InterruptedException { - shell.print("copying resources..."); - copyDir( - shell.currentLocation().resolve(mainResources), - shell.currentLocation().resolve(targetClasses) - ); - shell.printIn(" [DONE]", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(""); - return true; - } - }, - MAIN_CLASS { - @Override - boolean compile(RestxShell shell, Path targetClasses, Path dependenciesDir, Path mainSources, Path mainResources, String className) throws IOException, InterruptedException { - shell.print("compiling App..."); - shell.currentLocation().resolve(targetClasses).toFile().mkdirs(); - int compiled = new ProcessBuilder( - "javac", "-cp", dependenciesDir + "/*", "-sourcepath", mainSources.toString(), - "-d", targetClasses.toString(), - mainSources.resolve(className.replace('.', '/') + ".java").toString()) - .redirectErrorStream(true) - .redirectOutput(ProcessBuilder.Redirect.INHERIT) - .directory(shell.currentLocation().toFile().getAbsoluteFile()) - .start() - .waitFor(); - if (compiled != 0) { - shell.printIn(" [ERROR]", RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - return false; - } - shell.printIn(" [DONE]", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(""); - - shell.print("copying resources..."); - copyDir( - shell.currentLocation().resolve(mainResources), - shell.currentLocation().resolve(targetClasses) - ); - shell.printIn(" [DONE]", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(""); - return true; - } - }, - ALL { - @Override - boolean compile(RestxShell shell, - Path targetClasses, Path dependenciesDir, - final Path mainSources, Path mainResources, - String className) throws IOException, InterruptedException { - shell.print("compiling App..."); - shell.currentLocation().resolve(targetClasses).toFile().mkdirs(); - File currentDir = shell.currentLocation().toFile().getAbsoluteFile(); - - final List sources = new ArrayList<>(); - java.nio.file.Files.walkFileTree(mainSources, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (file.toString().endsWith(".java")) { - sources.add(file.toAbsolutePath().toString()); - } - return FileVisitResult.CONTINUE; - } - }); - shell.printIn(" [" + sources.size() + " source files]", RestxShell.AnsiCodes.ANSI_CYAN); - File classesFile = new File(currentDir, ".restx.classes"); - Files.write(Joiner.on("\n").join(sources), classesFile, Charsets.UTF_8); - int compiled = new ProcessBuilder( - "javac", "-cp", dependenciesDir + "/*", "-sourcepath", mainSources.toString(), - "-d", targetClasses.toString(), - "@" + classesFile.getName()) - .redirectErrorStream(true) - .redirectOutput(ProcessBuilder.Redirect.INHERIT) - .directory(currentDir) - .start() - .waitFor(); - classesFile.delete(); - - if (compiled != 0) { - shell.printIn(" [ERROR]", RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - return false; - } - shell.printIn(" [DONE]", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(""); - - shell.print("copying resources..."); - copyDir( - shell.currentLocation().resolve(mainResources), - shell.currentLocation().resolve(targetClasses) - ); - shell.printIn(" [DONE]", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(""); - return true; - } - }; - - abstract boolean compile(RestxShell shell, Path targetClasses, Path dependenciesDir, Path mainSources, Path mainResources, String className) throws IOException, InterruptedException; - - } - private final AppSettings appSettings; - - private final String appClassName; - private final CompileMode compile; - private final boolean quiet; - private final boolean daemon; - private final List vmOptions; - - public ShellAppRunner(AppSettings appSettings, String appClassName, CompileMode compile, - boolean quiet, boolean daemon, List vmOptions) { - this.appSettings = appSettings; - this.appClassName = appClassName; - this.compile = compile; - this.quiet = quiet; - this.daemon = daemon; - this.vmOptions = new ArrayList<>(vmOptions); - } - - public void run(RestxShell shell) throws IOException, InterruptedException { - Path targetClasses = Paths.get(appSettings.targetClasses()); - Path dependenciesDir = Paths.get(appSettings.targetDependency()); - Path mainSources = Paths.get(appSettings.mainSources()); - Path mainResources = Paths.get(appSettings.mainResources()); - - if (!compile.compile(shell, targetClasses, dependenciesDir, mainSources, mainResources, appClassName)) return; - - shell.println("starting " + appClassName + "..." + - (daemon ? " - type `stop` to stop it and go back to restx shell" : "")); - vmOptions.add("-Drestx.app.package=" + appSettings.appPackage()); - Process run = Apps.with(appSettings) - .run(shell.currentLocation().toFile(), - targetClasses, dependenciesDir, vmOptions, - appClassName, Collections.emptyList(), quiet); - - if (daemon) { - while (!shell.ask("", "").equals("stop")) { - shell.printIn("restx> unrecognized command - type `stop` to stop the app", - RestxShell.AnsiCodes.ANSI_YELLOW); - shell.println(""); - } - run.destroy(); - } - run.waitFor(); - } - -} diff --git a/restx-core-shell/src/main/resources/restx/core/shell/app.man b/restx-core-shell/src/main/resources/restx/core/shell/app.man deleted file mode 100644 index 478b3afae..000000000 --- a/restx-core-shell/src/main/resources/restx/core/shell/app.man +++ /dev/null @@ -1,112 +0,0 @@ -## app new - -`app new` command let you create a new restx app. - -It doesn't take any additional argument, it will ask for parameters to generate the app. - -## app compile - -Compile current application. - -This command uses javac to compile your application classes located in `src/main/java` and put compiled classes in -`target/classes`. -It uses dependencies located in `target/dependency`. - -Note: You need to be placed in a restx app root directory to run this command. - -## app generate-start-script [] - -Generate a start script to run your application outside restx shell. - -This can be useful for production, it let you avoid to have a jvm running for the shell (which is the case when you use -`app run`). - -The command actually generates 2 scripts: `start.sh` for *nix and `start.bat` for windows. - -You can optionally provide the fully qualified name of the main class, if you don't provide one restx will try to guess -it. - -Note: You need to be placed in a restx app root directory to run this command. - - -## app run [--quiet] [--fg] [-D=] [--mode=] [|] - -Run a restx application. - -Running a restx app is simply launching a java process taking all jars from `target/dependency` + classes -from `target/classes` in classpath. - -It will run `deps install` if needed (if `md.restx.json` file has changed since last `deps install` call). -If you prefer to use another dependency management mechanism, you just need to fill the `target/dependency` directory -with all your dependencies jars before calling app run. - -Your app will be started in different modes depending on your working directory typology : -- If sources are not found (in src/main/java), app will be forced in prod mode (no auto/hot compile). -- If sources are found, main class will be compiled before running the app. - It compiles only the main class because restx has auto compile feature, except in prod mode where it will compile all - classes as with `app compile`. - -### Options - -`--quiet` - do not show output in console. This is sometimes useful for performance reasons, console writing is synchronous and - can thus slow down your application, especially if you run through a slow ssh connection. - -`--fg` - by default app run the application in a separate process in the background. and wait for a `stop` command on the - shell input. Sometimes you may prefer to join the sub process and do not wait for a stop command (eg in situations - where you don't want to use shell input, like when running a restx app through batch script). - -`-D=` - allow to set system properties for the app, which are simply passed as vm options to the sub process - -`--mode=` - an easy way to set restx mode. - It has the same effect as running -Drestx.mode=, except that in prod it also influence the way compilation is - done (see above). - -`|` - Either the fully qualified name of the main class to run, - or a restx app directory name (restx app are located into your `${restx.home}/apps/` directory). - Main class will be retrieved : - - If provided as argument (main.class.Name) - - By looking into md.restx.json file ("manifest.main.classname" property) - - By guessing it from source files - - -## app archive - -Create a restx archive from current working directory. -A restx archive is a standard jar archive, with source (including assets) ressources located in `META-INF/restx/app/` -folder. - -Purpose of these archives is to be easily deployable with the `app grab` command. -They embed a restx module descriptor which will be used to provision dependencies before launching the restx app. - -`` - Path to generated restx archive vile. - -## app grab [] - -Grab and unpack a restx archive/project into a directory, then change restx shell to this directory in order -to easily chain this command with `app run` command. - -A restx archive is a standard jar archive, with sources (including assets) ressources located in `META-INF/restx/app/` -folder. -Note that a restx archive MUST contain a `META-INF/restx/app/md.restx.json` file in order to be considered valid. - -`` - different types of coordinates are available : - - GIT url (pattern : [#], for instance `git@github.com:foo/bar.git#v1.0`) - Git repository will be cloned inside `destination` directory. - Needs git executable to be available in your PATH. - - Http/https url of a Restx archive. - Archive classes will be unpacked into `/target/restx/classes/` directory, - and `META-INF/restx/app/*` (including md.restx.json file) will be chrooted into `destination` directory. - - GAV coordinates (pattern : ::) - Archive classes will be unpacked into `/target/restx/classes/` directory, - and `META-INF/restx/app/*` (including md.restx.json file) will be chrooted into `destination` directory. - -`` - destination where will reside your grabbed restx application working directory. - If not set, `~/.restx/apps//` will be used. diff --git a/restx-core-shell/src/main/resources/restx/core/shell/deps.man b/restx-core-shell/src/main/resources/restx/core/shell/deps.man deleted file mode 100644 index f72686c68..000000000 --- a/restx-core-shell/src/main/resources/restx/core/shell/deps.man +++ /dev/null @@ -1,27 +0,0 @@ -## deps install - -Resolve dependencies declared in current module descriptor (in order: either `md.restx.json`, `pom.xml` or `module.ivy`), -and synchronize them in `target/dependency` directory. - -For both `md.restx.json` and `module.ivy`, this command uses Apache Ivy under the hood to perform dependency resolution, -using settings provided by restx. You can override these Ivy settings by placing a file named ivysettings.xml in your -restx shell install location (usually `~/.restx`). - -For `pom.xml`, this command will use maven-dependency-plugin:copy-dependencies goal to perform dependency resolution. - -Note: You need to be placed in a restx app root directory to run this command. - -## deps add [scope:] [plugin.id] - -Declare new dependencies in your `md.restx.json` module descriptor, and update corresponding module descriptors -(pom and/or ivy). - -The plugin id is given in Grails like notation: `::`. You can use http://search.maven.org to -search for them and choose "Grails" on the module detail page to get the id. - -If you don't provide plugin id as a parameter to the command, the shell will provide a list of typical dependencies -that can be added to a restx app. - -You can also provide a scope as parameter, using the `scope:` notation, eg `scope:runtime`. - -This command does not install the dependencies, use `deps install` command to install them. \ No newline at end of file diff --git a/restx-core-shell/src/main/resources/restx/core/shell/hash.man b/restx-core-shell/src/main/resources/restx/core/shell/hash.man deleted file mode 100644 index 82a8dcf9e..000000000 --- a/restx-core-shell/src/main/resources/restx/core/shell/hash.man +++ /dev/null @@ -1,19 +0,0 @@ -## hash md5 - -Computes the md5 of given plain text string - -## hash sha1 <plaintext> - -Computes the sha1 of given plain text string - -## hash bcrypt <plaintext> - -bcrypt given plain text string - -## hash md5+bcrypt <plaintext> - -Hash with md5, and then bcrypt the given plain text password - -## hash sha1+bcrypt <plaintext> - -Hash with sha1, and then bcrypt the given plain text password \ No newline at end of file diff --git a/restx-core-shell/src/main/resources/templates/root/grunt-bower/ui/build.bat b/restx-core-shell/src/main/resources/templates/root/grunt-bower/ui/build.bat deleted file mode 100644 index d2f6207b8..000000000 --- a/restx-core-shell/src/main/resources/templates/root/grunt-bower/ui/build.bat +++ /dev/null @@ -1,6 +0,0 @@ -REM This script is used to build the front app and put it in the dist directory. - -npm install -bower install -grunt test -grunt build diff --git a/restx-core-shell/src/main/resources/templates/root/grunt-bower/ui/build.sh b/restx-core-shell/src/main/resources/templates/root/grunt-bower/ui/build.sh deleted file mode 100644 index 0df170cf2..000000000 --- a/restx-core-shell/src/main/resources/templates/root/grunt-bower/ui/build.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# This script is used to build the front app and put it in the dist directory. - -npm install -bower install -grunt test -grunt build diff --git a/restx-core-shell/src/main/resources/templates/root/main/_pom.xml b/restx-core-shell/src/main/resources/templates/root/main/_pom.xml deleted file mode 100644 index 58bb81859..000000000 --- a/restx-core-shell/src/main/resources/templates/root/main/_pom.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <groupId>{{groupId}}</groupId> - <artifactId>{{artifactId}}-parent</artifactId> - <version>{{version}}</version> - <packaging>pom</packaging> - - <modules> - <module>ui</module> - <module>srv</module> - </modules> -</project> \ No newline at end of file diff --git a/restx-core-shell/src/main/resources/templates/root/main/ui/_pom.xml b/restx-core-shell/src/main/resources/templates/root/main/ui/_pom.xml deleted file mode 100644 index 8b1201153..000000000 --- a/restx-core-shell/src/main/resources/templates/root/main/ui/_pom.xml +++ /dev/null @@ -1,76 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <groupId>{{groupId}}</groupId> - <artifactId>{{artifactId}}-ui</artifactId> - <version>{{version}}</version> - <packaging>pom</packaging> - - <build> - <plugins> - <plugin> - <groupId>org.codehaus.gmaven</groupId> - <artifactId>groovy-maven-plugin</artifactId> - <version>2.0</version> - <executions> - <execution> - <phase>compile</phase> - <goals> - <goal>execute</goal> - </goals> - <configuration> - <properties> - <basedir>${project.basedir}</basedir> - <buildScript>build</buildScript> - </properties> - <source><![CDATA[ - def basedir = new File(properties['basedir']) - def buildScript = properties['buildScript'] - - def isWindows = { System.properties['os.name'].toLowerCase().contains('windows') } - - if (!new File(basedir, buildScript).exists()) { - buildScript = buildScript + (isWindows() ? '.bat' : '.sh') - } - - def cmd = isWindows() ? "cmd /c $buildScript" : "sh $buildScript" - println ">> " + cmd - def process = new ProcessBuilder(cmd.split(' ')).directory(basedir) .redirectErrorStream(true).start() - process.in.eachLine { line -> println line } - ]]> - </source> - </configuration> - </execution> - </executions> - </plugin> - <plugin> - <artifactId>maven-assembly-plugin</artifactId> - <executions> - <execution> - <id>distro-assembly</id> - <phase>package</phase> - <goals> - <goal>single</goal> - </goals> - <configuration> - <appendAssemblyId>false</appendAssemblyId> - <descriptorRefs> - <descriptorRef>package-web-dist</descriptorRef> - </descriptorRefs> - </configuration> - </execution> - </executions> - <dependencies> - <dependency> - <groupId>io.restx</groupId> - <artifactId>restx-maven-assemblies</artifactId> - <version>1.0</version> - </dependency> - </dependencies> - </plugin> - </plugins> - </build> -</project> \ No newline at end of file diff --git a/restx-core-shell/src/main/resources/templates/root/no-node/ui/build.bat b/restx-core-shell/src/main/resources/templates/root/no-node/ui/build.bat deleted file mode 100644 index f49d8ccf5..000000000 --- a/restx-core-shell/src/main/resources/templates/root/no-node/ui/build.bat +++ /dev/null @@ -1,3 +0,0 @@ -REM This script is used to build the front app and put it in the dist directory. - -xcopy app dist /s /e /i /y \ No newline at end of file diff --git a/restx-core-shell/src/main/resources/templates/root/no-node/ui/build.sh b/restx-core-shell/src/main/resources/templates/root/no-node/ui/build.sh deleted file mode 100644 index 876d7b562..000000000 --- a/restx-core-shell/src/main/resources/templates/root/no-node/ui/build.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -# This script is used to build the front app and put it in the dist directory. - -rm -rf dist -cp -R app dist \ No newline at end of file diff --git a/restx-core-shell/src/main/resources/templates/srv/helloResource/data/users.json b/restx-core-shell/src/main/resources/templates/srv/helloResource/data/users.json deleted file mode 100644 index 834e03c4b..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/helloResource/data/users.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - {"name":"user1", "roles": ["hello"]}, - {"name":"user2", "roles": []} -] \ No newline at end of file diff --git a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/main/java/$packagePath$/_Roles.java b/restx-core-shell/src/main/resources/templates/srv/helloResource/src/main/java/$packagePath$/_Roles.java deleted file mode 100644 index d3b405760..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/main/java/$packagePath$/_Roles.java +++ /dev/null @@ -1,10 +0,0 @@ -package {{mainPackage}}; - -/** - * A list of roles for the application. - * - * We don't use an enum here because it must be used inside an annotation. - */ -public final class Roles { - public static final String HELLO_ROLE = "hello"; -} diff --git a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/main/java/$packagePath$/domain/_Message.java b/restx-core-shell/src/main/resources/templates/srv/helloResource/src/main/java/$packagePath$/domain/_Message.java deleted file mode 100644 index 3da2d6ee6..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/main/java/$packagePath$/domain/_Message.java +++ /dev/null @@ -1,21 +0,0 @@ -package {{mainPackage}}.domain; - -public class Message { - private String message; - - public String getMessage() { - return message; - } - - public Message setMessage(final String message) { - this.message = message; - return this; - } - - @Override - public String toString() { - return "Message{" + - "message='" + message + '\'' + - '}'; - } -} diff --git a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/main/java/$packagePath$/rest/_HelloResource.java b/restx-core-shell/src/main/resources/templates/srv/helloResource/src/main/java/$packagePath$/rest/_HelloResource.java deleted file mode 100644 index a14d34b4f..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/main/java/$packagePath$/rest/_HelloResource.java +++ /dev/null @@ -1,62 +0,0 @@ -package {{mainPackage}}.rest; - -import {{mainPackage}}.domain.Message; -import {{mainPackage}}.Roles; -import org.joda.time.DateTime; -import restx.annotations.GET; -import restx.annotations.POST; -import restx.annotations.RestxResource; -import restx.factory.Component; -import restx.security.PermitAll; -import restx.security.RolesAllowed; -import restx.security.RestxSession; - -import javax.validation.constraints.NotNull; - -@Component @RestxResource -public class HelloResource { - - /** - * Say hello to currently logged in user. - * - * Authorized only for principals with Roles.HELLO_ROLE role. - * - * @return a Message to say hello - */ - @GET("/message") - @RolesAllowed(Roles.HELLO_ROLE) - public Message sayHello() { - return new Message().setMessage(String.format( - "hello %s, it's %s", - RestxSession.current().getPrincipal().get().getName(), - DateTime.now().toString("HH:mm:ss"))); - } - - /** - * Say hello to anybody. - * - * Does not require authentication. - * - * @return a Message to say hello - */ - @GET("/hello") - @PermitAll - public Message helloPublic(String who) { - return new Message().setMessage(String.format( - "hello %s, it's %s", - who, DateTime.now().toString("HH:mm:ss"))); - } - - public static class MyPOJO { - @NotNull - String value; - public String getValue(){ return value; } - public void setValue(String value){ this.value = value; } - } - @POST("/mypojo") - @PermitAll - public MyPOJO helloPojo(MyPOJO pojo){ - pojo.setValue("hello "+pojo.getValue()); - return pojo; - } -} diff --git a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/java/$packagePath$/rest/_HelloResourceSpecTest.java b/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/java/$packagePath$/rest/_HelloResourceSpecTest.java deleted file mode 100644 index 9b1206dbf..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/java/$packagePath$/rest/_HelloResourceSpecTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package {{mainPackage}}.rest; - -import {{mainPackage}}.AppServer; -import org.junit.runner.RunWith; -import restx.tests.RestxSpecTestsRunner; -import restx.tests.FindSpecsIn; - -@RunWith(RestxSpecTestsRunner.class) -@FindSpecsIn("specs/hello") -public class HelloResourceSpecTest { - - /** - * Useless, thanks to both @RunWith(RestxSpecTestsRunner.class) & @FindSpecsIn() - * - * @Rule - * public RestxSpecRule rule = new RestxSpecRule(); - * - * @Test - * public void test_spec() throws Exception { - * rule.runTest(specTestPath); - * } - */ -} diff --git a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_admin_say_hello.spec.yaml b/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_admin_say_hello.spec.yaml deleted file mode 100644 index 1b7b8f0f9..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_admin_say_hello.spec.yaml +++ /dev/null @@ -1,10 +0,0 @@ -title: should admin say hello -given: - - time: 2013-08-28T01:18:00.822+02:00 - - uuids: [ "e2b4430f-9541-4602-9a3a-413d17c56a6b" ] -wts: - - when: | - GET message - $RestxSession: {"_expires":"2013-09-27T01:18:00.822+02:00","principal":"admin","sessionKey":"e2b4430f-9541-4602-9a3a-413d17c56a6b"} - then: | - {"message":"hello admin, it's 01:18:00"} diff --git a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_anyone_say_hello.spec.yaml b/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_anyone_say_hello.spec.yaml deleted file mode 100644 index 29b6faca3..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_anyone_say_hello.spec.yaml +++ /dev/null @@ -1,8 +0,0 @@ -title: should admin say hello -given: - - time: 2013-08-28T01:18:00.822+02:00 -wts: - - when: | - GET hello?who=xavier - then: | - {"message":"hello xavier, it's 01:18:00"} diff --git a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_missing_value_triggers_validation_error.spec.yaml b/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_missing_value_triggers_validation_error.spec.yaml deleted file mode 100644 index d0c6323ca..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_missing_value_triggers_validation_error.spec.yaml +++ /dev/null @@ -1,17 +0,0 @@ -title: should missing post value triggers a validation error -given: - - time: 2013-08-28T01:18:00.822+02:00 - - uuids: [ "e2b4430f-9541-4602-9a3a-413d17c56a6b" ] -wts: - - when: | - POST mypojo - $RestxSession: {"_expires":"2013-09-27T01:18:00.822+02:00","principal":"user1","sessionKey":"e2b4430f-9541-4602-9a3a-413d17c56a6b"} - {} - then: | - 400 - - when: | - POST mypojo - $RestxSession: {"_expires":"2013-09-27T01:18:00.822+02:00","principal":"user1","sessionKey":"e2b4430f-9541-4602-9a3a-413d17c56a6b"} - {"value":"world"} - then: | - {"value":"hello world"} diff --git a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_user1_say_hello.spec.yaml b/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_user1_say_hello.spec.yaml deleted file mode 100644 index 791a3a277..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_user1_say_hello.spec.yaml +++ /dev/null @@ -1,10 +0,0 @@ -title: should user1 say hello -given: - - time: 2013-08-28T01:18:00.822+02:00 - - uuids: [ "e2b4430f-9541-4602-9a3a-413d17c56a6b" ] -wts: - - when: | - GET message - $RestxSession: {"_expires":"2013-09-27T01:18:00.822+02:00","principal":"user1","sessionKey":"e2b4430f-9541-4602-9a3a-413d17c56a6b"} - then: | - {"message":"hello user1, it's 01:18:00"} diff --git a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_user2_not_say_hello.spec.yaml b/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_user2_not_say_hello.spec.yaml deleted file mode 100644 index ead5af8d0..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/helloResource/src/test/resources/specs/hello/_should_user2_not_say_hello.spec.yaml +++ /dev/null @@ -1,10 +0,0 @@ -title: should user2 not say hello -given: - - time: 2013-08-28T01:19:44.770+02:00 - - uuids: [ "56f71fcc-42d3-422f-9458-8ad37fc4a0b5" ] -wts: - - when: | - GET message - $RestxSession: {"_expires":"2013-09-27T01:19:44.770+02:00","principal":"user2","sessionKey":"56f71fcc-42d3-422f-9458-8ad37fc4a0b5"} - then: | - 403 diff --git a/restx-core-shell/src/main/resources/templates/srv/main/_md.restx.json b/restx-core-shell/src/main/resources/templates/srv/main/_md.restx.json deleted file mode 100644 index 3cbabd00e..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/main/_md.restx.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "module": "{{groupId}}:{{artifactId}}:{{version}}", - "packaging": "war", - - "properties": { - "java.version": "{{javaVersion}}", - "restx.version": "{{restxVersion}}"{{#useSrvuiLayout}}, - "project.war.overlay.groupId": "{{groupId}}", - "project.war.overlay.artifactId": "{{artifactId}}"{{/useSrvuiLayout}} - }, - "fragments": { - "maven": [ - "classpath:///restx/build/fragments/maven/javadoc-apidoclet.xml"{{#useSrvuiLayout}}, - "classpath:///restx/build/fragments/maven/war-overlay-resources.xml" -{{/useSrvuiLayout}} - ] - }, - "dependencies": { - "compile": [ - "io.restx:restx-core:${restx.version}", - "io.restx:restx-security-basic:${restx.version}", - "io.restx:restx-core-annotation-processor:${restx.version}", - "io.restx:restx-factory:${restx.version}", - "io.restx:restx-factory-admin:${restx.version}", - "io.restx:restx-validation:${restx.version}", - "io.restx:restx-monitor-codahale:${restx.version}", - "io.restx:restx-monitor-admin:${restx.version}", - "io.restx:restx-log-admin:${restx.version}", - "io.restx:restx-i18n-admin:${restx.version}", -{{#includeStatsModule}} - "io.restx:restx-stats-admin:${restx.version}", -{{/includeStatsModule}} - "io.restx:restx-servlet:${restx.version}", - "io.restx:restx-server-jetty8:${restx.version}!optional", - "io.restx:restx-apidocs:${restx.version}", - "io.restx:restx-specs-admin:${restx.version}", - "io.restx:restx-admin:${restx.version}", - "ch.qos.logback:logback-classic:1.0.13" - ], - "test": [ - "io.restx:restx-specs-tests:${restx.version}", - "junit:junit:4.11" - ] - } -} diff --git a/restx-core-shell/src/main/resources/templates/srv/main/data/credentials.json b/restx-core-shell/src/main/resources/templates/srv/main/data/credentials.json deleted file mode 100644 index c1a4fcf53..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/main/data/credentials.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "//": "lines with // keys are just comments (we don't have real comments in json)", - "//": "this file stores password passed through md5+bcrypt hash", - "//": "you can use `restx hash md5+bcrypt {password}` shell command to get hashed passwords to put here", - - "//": "to help startup with restx, there are comments with clear text passwords,", - "//": "which should obviously not be stored here.", - "user1": "$2a$10$iZluFUJShbjb1ue68bLrDuGCeJL9EMLHelVIf8u0SUbCseDOvKnoe", - "//": "user 1 password is 'user1-pwd'", - "user2": "$2a$10$oym3SYMFXf/9gGfDKKHO4eM1vWNqAZMsRZCL.BORCaP4yp5cdiCXu", - "//": "user 2 password is 'user2-pwd'" -} \ No newline at end of file diff --git a/restx-core-shell/src/main/resources/templates/srv/main/data/users.json b/restx-core-shell/src/main/resources/templates/srv/main/data/users.json deleted file mode 100644 index da185be43..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/main/data/users.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - {"name":"user1", "roles": []}, - {"name":"user2", "roles": []} -] \ No newline at end of file diff --git a/restx-core-shell/src/main/resources/templates/srv/main/src/main/java/$packagePath$/_AppModule.java b/restx-core-shell/src/main/resources/templates/srv/main/src/main/java/$packagePath$/_AppModule.java deleted file mode 100644 index 05a215876..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/main/src/main/java/$packagePath$/_AppModule.java +++ /dev/null @@ -1,74 +0,0 @@ -package {{mainPackage}}; - -import restx.config.ConfigLoader; -import restx.config.ConfigSupplier; -import restx.factory.Provides; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Charsets; -import com.google.common.collect.ImmutableSet; -import restx.security.*; -import restx.factory.Module; -import restx.factory.Provides; -import javax.inject.Named; - -import java.nio.file.Paths; - -@Module -public class AppModule { - @Provides - public SignatureKey signatureKey() { - return new SignatureKey("{{signatureKey}}".getBytes(Charsets.UTF_8)); - } - - @Provides - @Named("restx.admin.password") - public String restxAdminPassword() { - return "{{adminPassword}}"; - } - - @Provides - public ConfigSupplier appConfigSupplier(ConfigLoader configLoader) { - // Load settings.properties in {{mainPackage}} package as a set of config entries - return configLoader.fromResource("{{packagePath}}/settings"); - } - - @Provides - public CredentialsStrategy credentialsStrategy() { - return new BCryptCredentialsStrategy(); - } - - @Provides - public BasicPrincipalAuthenticator basicPrincipalAuthenticator( - SecuritySettings securitySettings, CredentialsStrategy credentialsStrategy, - @Named("restx.admin.passwordHash") String defaultAdminPasswordHash, ObjectMapper mapper) { - return new StdBasicPrincipalAuthenticator(new StdUserService<>( - // use file based users repository. - // Developer's note: prefer another storage mechanism for your users if you need real user management - // and better perf - new FileBasedUserRepository<>( - StdUser.class, // this is the class for the User objects, that you can get in your app code - // with RestxSession.current().getPrincipal().get() - // it can be a custom user class, it just need to be json deserializable - mapper, - - // this is the default restx admin, useful to access the restx admin console. - // if one user with restx-admin role is defined in the repository, this default user won't be - // available anymore - new StdUser("admin", ImmutableSet.<String>of("*")), - - // the path where users are stored - Paths.get("data/users.json"), - - // the path where credentials are stored. isolating both is a good practice in terms of security - // it is strongly recommended to follow this approach even if you use your own repository - Paths.get("data/credentials.json"), - - // tells that we want to reload the files dynamically if they are touched. - // this has a performance impact, if you know your users / credentials never change without a - // restart you can disable this to get better perfs - true), - credentialsStrategy, defaultAdminPasswordHash), - securitySettings); - } -} diff --git a/restx-core-shell/src/main/resources/templates/srv/main/src/main/java/$packagePath$/_AppServer.java b/restx-core-shell/src/main/resources/templates/srv/main/src/main/java/$packagePath$/_AppServer.java deleted file mode 100644 index eafaae6b7..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/main/src/main/java/$packagePath$/_AppServer.java +++ /dev/null @@ -1,32 +0,0 @@ -package {{mainPackage}}; - -import com.google.common.base.Optional; -import restx.server.WebServer; -import restx.server.Jetty8WebServer; - -/** - * This class can be used to run the app. - * - * Alternatively, you can deploy the app as a war in a regular container like tomcat or jetty. - * - * Reading the port from system env PORT makes it compatible with heroku. - */ -public class AppServer { - public static final String WEB_INF_LOCATION = "src/main/webapp/WEB-INF/web.xml"; - public static final String WEB_APP_LOCATION = "src/main/webapp"; - - public static void main(String[] args) throws Exception { - int port = Integer.valueOf(Optional.fromNullable(System.getenv("PORT")).or("{{defaultPort}}")); - WebServer server = new Jetty8WebServer(WEB_INF_LOCATION, WEB_APP_LOCATION, port, "0.0.0.0"); - - /* - * load mode from system property if defined, or default to dev - * be careful with that setting, if you use this class to launch your server in production, make sure to launch - * it with -Drestx.mode=prod or change the default here - */ - System.setProperty("restx.mode", System.getProperty("restx.mode", "dev")); - System.setProperty("restx.app.package", "{{mainPackage}}"); - - server.startAndAwait(); - } -} diff --git a/restx-core-shell/src/main/resources/templates/srv/main/src/main/resources/$packagePath$/_settings.properties b/restx-core-shell/src/main/resources/templates/srv/main/src/main/resources/$packagePath$/_settings.properties deleted file mode 100644 index e8734a342..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/main/src/main/resources/$packagePath$/_settings.properties +++ /dev/null @@ -1 +0,0 @@ -app.name={{appName}} \ No newline at end of file diff --git a/restx-core-shell/src/main/resources/templates/srv/main/src/main/resources/_logback.xml b/restx-core-shell/src/main/resources/templates/srv/main/src/main/resources/_logback.xml deleted file mode 100644 index 6f5a9402f..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/main/src/main/resources/_logback.xml +++ /dev/null @@ -1,94 +0,0 @@ -<configuration> - <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> - <resetJUL>true</resetJUL> - </contextListener> - <property name="LOGS_FOLDER" value="${logs.base:-logs}" /> - - <appender name="errorFile" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <File>${LOGS_FOLDER}/errors.log</File> - <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> - <level>ERROR</level> - </filter> - <encoder> - <pattern>%d [%-16thread] [%-10X{principal}] %-5level %logger{36} - %msg%n</pattern> - </encoder> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <fileNamePattern>${LOGS_FOLDER}/errors.%d.log</fileNamePattern> - <maxHistory>30</maxHistory> - </rollingPolicy> - </appender> - - <if condition='p("restx.mode").equals("prod")'> - <then> - <!-- production mode --> - <appender name="appLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <File>${LOGS_FOLDER}/app.log</File> - <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> - <level>INFO</level> - </filter> - <encoder> - <pattern>%d [%-16thread] [%-10X{principal}] %-5level %logger{36} - %msg%n</pattern> - </encoder> - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> - <fileNamePattern>${LOGS_FOLDER}/app.%d.log</fileNamePattern> - <maxHistory>10</maxHistory> - </rollingPolicy> - </appender> - <appender name="debugFile" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <File>${LOGS_FOLDER}/debug.log</File> - <encoder> - <pattern>%d [%-16thread] [%-10X{principal}] %-5level %logger{36} - %msg%n</pattern> - </encoder> - <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <fileNamePattern>${LOGS_FOLDER}/debug.%i.log.zip</fileNamePattern> - <minIndex>1</minIndex> - <maxIndex>3</maxIndex> - </rollingPolicy> - - <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> - <maxFileSize>50MB</maxFileSize> - </triggeringPolicy> - </appender> - <root level="INFO"> - <appender-ref ref="debugFile" /> - <appender-ref ref="appLog" /> - </root> - </then> - <else> - <!-- not production mode --> - <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> - <encoder> - <pattern>%d [%-16thread] [%-10X{principal}] %-5level %logger{36} - %msg%n</pattern> - </encoder> - </appender> - <appender name="appLog" class="ch.qos.logback.core.FileAppender"> - <File>${LOGS_FOLDER}/app.log</File> - <encoder> - <pattern>%d [%-16thread] [%-10X{principal}] %-5level %logger{36} - %msg%n</pattern> - </encoder> - </appender> - - <root level="INFO"> - <appender-ref ref="STDOUT" /> - <appender-ref ref="appLog" /> - </root> - </else> - </if> - - <!-- clean up container logs --> - <logger name="org.eclipse.jetty.server.AbstractConnector" level="WARN" /> - <logger name="org.eclipse.jetty.server.handler.ContextHandler" level="WARN" /> - <logger name="org.eclipse.jetty.webapp.StandardDescriptorProcessor" level="WARN" /> - - <logger name="org.hibernate.validator.internal.engine.ConfigurationImpl" level="WARN" /> - <logger name="org.reflections.Reflections" level="WARN" /> - - <logger name="restx.factory.Factory" level="WARN" /> - - <!-- app logs - set DEBUG level, in prod it will go to a dedicated file --> - <logger name="{{mainPackage}}" level="DEBUG" /> - - <root level="INFO"> - <appender-ref ref="errorFile" /> - </root> -</configuration> diff --git a/restx-core-shell/src/main/resources/templates/srv/main/src/main/webapp/WEB-INF/_web.xml b/restx-core-shell/src/main/resources/templates/srv/main/src/main/webapp/WEB-INF/_web.xml deleted file mode 100644 index ffb23f8f8..000000000 --- a/restx-core-shell/src/main/resources/templates/srv/main/src/main/webapp/WEB-INF/_web.xml +++ /dev/null @@ -1,15 +0,0 @@ -<web-app xmlns="http://java.sun.com/xml/ns/javaee" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" - version="3.0" metadata-complete="true"> - - <servlet> - <servlet-name>restx</servlet-name> - <servlet-class>restx.servlet.RestxMainRouterServlet</servlet-class> - <load-on-startup>1</load-on-startup> - </servlet> - <servlet-mapping> - <servlet-name>restx</servlet-name> - <url-pattern>{{baseAPIPath}}/*</url-pattern> - </servlet-mapping> -</web-app> diff --git a/restx-core-shell/src/test/java/restx/core/shell/NewAppTest.java b/restx-core-shell/src/test/java/restx/core/shell/NewAppTest.java deleted file mode 100644 index d473402fd..000000000 --- a/restx-core-shell/src/test/java/restx/core/shell/NewAppTest.java +++ /dev/null @@ -1,138 +0,0 @@ -package restx.core.shell; - -import jline.console.ConsoleReader; -import org.apache.maven.it.VerificationException; -import org.apache.maven.it.Verifier; -import org.junit.*; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import restx.CoreModule; -import restx.build.RestxJsonSupport; -import restx.common.OSUtils; -import restx.factory.Factory; -import restx.shell.RestxShell; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.List; - -import static org.mockito.Mockito.*; - -/** - * @author fcamblor - */ -@RunWith(Parameterized.class) -public class NewAppTest { - - @Rule - public TemporaryFolder workDirectory = new TemporaryFolder(); - - private final AppShellCommand.NewAppDescriptor descriptor; - private String initialRestxShellHomeValue; - - @Before - public void setup() throws IOException { - // Avoiding "restx.shell.home_IS_UNDEFINED/ dir due to logs - this.initialRestxShellHomeValue = System.getProperty("restx.shell.home"); - if(this.initialRestxShellHomeValue == null) { - System.setProperty("restx.shell.home", workDirectory.newFolder(".restx").getAbsolutePath()); - } - } - - @After - public void teardown() { - if(this.initialRestxShellHomeValue == null) { - System.getProperties().remove("restx.shell.home"); - } - } - - @Parameterized.Parameters(name="{0}") - public static Iterable<Object[]> data() throws IOException { - return Arrays.asList( - new Object[]{ "Simplest app", createDescriptor("test1", false, Arrays.asList(ModuleDescriptorType.values())) }, - new Object[]{ "App with hello resource + all descriptors", createDescriptor("test2", true, Arrays.asList(ModuleDescriptorType.values())) }, - new Object[]{ "App with hello resource + maven descriptor only", createDescriptor("test3", true, Arrays.asList(ModuleDescriptorType.MAVEN)) } - // Disabled because executing maven goals won't work with ivy-only file - // new Object[]{ "App with hello resource + ivy descriptor only", createDescriptor("test4", true, Arrays.asList(ModuleDescriptorType.IVY)) } - ); - } - - public NewAppTest(String testName, AppShellCommand.NewAppDescriptor descriptor) { - this.descriptor = descriptor; - } - - @Test - public void should_app_generated_executes_maven_well() throws IOException, VerificationException { - if ("true".equals(System.getenv("DRONE"))) { - // executing maven causes problem on drone - return; - } - - RestxShell shell = prepareRestxShell(); - - AppShellCommand.NewAppCommandRunner appCommandRunner = - new AppShellCommand(new CoreModule().uuidGenerator()).new NewAppCommandRunner(); - Path appPath = appCommandRunner.generateApp(descriptor, shell); - - Verifier mavenVerifier = new Verifier(appPath.toString()); - - if (OSUtils.isMacOSX()) { - // on MacOSX, when using the verifier JAVA_HOME is not always properly detected - // sometimes it points to JRE, making javadoc call fail. - // Here is a workaround for that problem - String javaHome = System.getProperty("java.home"); - if (javaHome.endsWith("jre")) { - javaHome = new File(javaHome).getParentFile().getCanonicalPath(); - mavenVerifier.setEnvironmentVariable("JAVA_HOME", javaHome); - } - } - if(System.getProperty("skip-offline") == null) { - mavenVerifier.addCliOption("--offline"); - } - mavenVerifier.executeGoal("package"); - mavenVerifier.verifyErrorFreeLog(); - } - - private RestxShell prepareRestxShell() throws IOException { - ConsoleReader consoleReader = new ConsoleReader(); - RestxShell shell = spy(new RestxShell(consoleReader, Factory.builder().build())); - doNothing().when(shell).println(anyString()); - doReturn(this.workDirectory.getRoot().toPath()).when(shell).currentLocation(); - return shell; - } - - private static AppShellCommand.NewAppDescriptor createDescriptor(String name, boolean generateHelloResource, List<ModuleDescriptorType> buildFiles) throws IOException { - AppShellCommand.NewAppDescriptor desc = new AppShellCommand.NewAppDescriptor(); - desc.appName = name+"App"; - desc.groupId = "com.foo"; - desc.artifactId = name; - desc.targetPath = name; - desc.mainPackage = "com.foo"; - desc.version = "0.1-SNAPSHOT"; - desc.buildFiles = buildFiles; - desc.signatureKey = "blah blah blah"; - desc.adminPassword = "pwd"; - desc.defaultPort = "8080"; - desc.baseAPIPath = "/api"; - desc.javaVersion = "1.7"; - desc.restxVersion = resolveCurrentModuleVersion(); - desc.includeStatsModule = false; - desc.generateHelloResource = generateHelloResource; - return desc; - } - - private static String resolveCurrentModuleVersion() throws IOException { - Path restxModuleDescriptor = Paths.get(".").resolve("md.restx.json"); - if(Files.notExists(restxModuleDescriptor)){ - throw new FileNotFoundException("md.restx.json not found !"); - } - - try(FileInputStream fis = new FileInputStream(restxModuleDescriptor.toFile());) { - return new RestxJsonSupport().parse(fis).getGav().getVersion(); - } - } -} diff --git a/restx-package/local-install.sh b/restx-package/local-install.sh deleted file mode 100755 index 36f5fabac..000000000 --- a/restx-package/local-install.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -PLUGINS="core-shell -specs-shell -build-shell" - -# shell script to prepare a local install of restx shell -# you need to have built restx-package and the plugins first - -rm -rf target/restx -mkdir target/restx -cd target/restx -tar xzvf ../assembly/out/restx-*-SNAPSHOT.tar.gz - -cd - - -for plugin in $PLUGINS -do - cd ../restx-$plugin - mvn -o dependency:copy-dependencies - cp target/dependency/* ../restx-package/target/restx/plugins/ - cp `ls -1 target/*.jar | grep -v javadoc | grep -v sources` ../restx-package/target/restx/plugins/ - cd - -done - -echo "local restx shell ready in target/restx" -echo "you can run it with:" -echo " target/restx/restx" diff --git a/restx-package/pom.xml b/restx-package/pom.xml deleted file mode 100644 index a9d73ea20..000000000 --- a/restx-package/pom.xml +++ /dev/null @@ -1,51 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>io.restx</groupId> - <artifactId>restx-parent</artifactId> - <version>0.35-SNAPSHOT</version> - </parent> - - <artifactId>restx-package</artifactId> - <packaging>pom</packaging> - - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-assembly-plugin</artifactId> - <executions> - <execution> - <id>make-assembly</id> - <phase>package</phase> - <goals> - <goal>single</goal> - </goals> - </execution> - </executions> - <configuration> - <descriptors> - <descriptor>src/main/assembly/shell.xml</descriptor> - </descriptors> - <finalName>restx-${project.version}</finalName> - <appendAssemblyId>false</appendAssemblyId> - <outputDirectory>target/assembly/out</outputDirectory> - <workDirectory>target/assembly/work</workDirectory> - </configuration> - </plugin> - </plugins> - </build> - - <dependencies> - <dependency> - <groupId>io.restx</groupId> - <artifactId>restx-shell</artifactId> - </dependency> - <dependency> - <groupId>io.restx</groupId> - <artifactId>restx-shell-manager</artifactId> - </dependency> - </dependencies> -</project> diff --git a/restx-package/src/main/assembly/shell.xml b/restx-package/src/main/assembly/shell.xml deleted file mode 100644 index 4d95f5a29..000000000 --- a/restx-package/src/main/assembly/shell.xml +++ /dev/null @@ -1,46 +0,0 @@ -<assembly> - <id>shell</id> - <formats> - <format>zip</format> - <format>tar.gz</format> - </formats> - <includeBaseDirectory>false</includeBaseDirectory> - <dependencySets> - <dependencySet> - <outputDirectory>lib</outputDirectory> - <scope>runtime</scope> - </dependencySet> - </dependencySets> - <fileSets> - <fileSet> - <directory>src/main/script</directory> - <outputDirectory></outputDirectory> - <lineEnding>unix</lineEnding> - <fileMode>0755</fileMode> - <includes> - <include>restx</include> - <include>launch.sh</include> - </includes> - </fileSet> - <fileSet> - <directory>src/main/script</directory> - <outputDirectory></outputDirectory> - <lineEnding>windows</lineEnding> - <includes> - <include>restx.bat</include> - <include>launch.bat</include> - </includes> - </fileSet> - <fileSet> - <directory>src/main/resources</directory> - <outputDirectory></outputDirectory> - </fileSet> - <fileSet> - <directory>..</directory> - <outputDirectory></outputDirectory> - <includes> - <include>LICENSE.txt</include> - </includes> - </fileSet> - </fileSets> -</assembly> \ No newline at end of file diff --git a/restx-package/src/main/resources/plugins/README.txt b/restx-package/src/main/resources/plugins/README.txt deleted file mode 100644 index 16c13476f..000000000 --- a/restx-package/src/main/resources/plugins/README.txt +++ /dev/null @@ -1 +0,0 @@ -This is where restx will put the shell plugins. \ No newline at end of file diff --git a/restx-package/src/main/script/launch.bat b/restx-package/src/main/script/launch.bat deleted file mode 100644 index c692a1108..000000000 --- a/restx-package/src/main/script/launch.bat +++ /dev/null @@ -1,15 +0,0 @@ -:begin -@echo off - -setlocal enabledelayedexpansion - -IF "%JAVA_OPTS%"=="" ( - SET JAVA_OPTS= -) -IF "%RESTX_OPTS%"=="" ( - SET RESTX_OPTS= -) - -java %JAVA_OPTS% %RESTX_OPTS% -Drestx.shell.home="%~dp0." -cp "%~dp0lib\*;%~dp0plugins\*;." restx.shell.RestxShell %* - -endlocal \ No newline at end of file diff --git a/restx-package/src/main/script/launch.sh b/restx-package/src/main/script/launch.sh deleted file mode 100755 index 31f0ed7c3..000000000 --- a/restx-package/src/main/script/launch.sh +++ /dev/null @@ -1,16 +0,0 @@ -#! /usr/bin/env sh - -PRG="$0" -while [ -h "$PRG" ] ; do - PRG=`readlink "$PRG"` -done - -dir=`dirname $PRG` - -if [ -z "$JAVA_HOME" ]; then - JAVA="java" -else - JAVA="$JAVA_HOME/bin/java" -fi - -"$JAVA" $JAVA_OPTS $RESTX_OPTS -Drestx.shell.home="$dir" -cp "$dir/lib/*:$dir/plugins/*:." restx.shell.RestxShell "$@" diff --git a/restx-package/src/main/script/restx b/restx-package/src/main/script/restx deleted file mode 100755 index b2fd4b1db..000000000 --- a/restx-package/src/main/script/restx +++ /dev/null @@ -1,24 +0,0 @@ -#! /usr/bin/env sh - -PRG="$0" -while [ -h "$PRG" ] ; do - PRG=`readlink "$PRG"` -done - -dir=`dirname $PRG` - -while [ 1 ]; do - if [ -f "$dir/upgrade.sh" ]; then - sh "$dir/upgrade.sh" - rm -f "$dir/upgrade.sh" - fi - - sh "$dir/launch.sh" "$@" - - if [ -f "$dir/.restart" ]; then - rm -f "$dir/.restart" - else - break - fi -done - diff --git a/restx-package/src/main/script/restx.bat b/restx-package/src/main/script/restx.bat deleted file mode 100644 index 4a99492f9..000000000 --- a/restx-package/src/main/script/restx.bat +++ /dev/null @@ -1,19 +0,0 @@ -:begin -@echo off - -setlocal enabledelayedexpansion - -:start -if exist "%~dp0upgrade.bat" ( - cmd /c "%~dp0upgrade.bat" - del "%~dp0upgrade.bat" -) - -call "%~dp0launch.bat" %* - -if exist "%~dp0.restart" ( - del "%~dp0.restart" - goto start -) - -endlocal \ No newline at end of file diff --git a/restx-shell-manager/md.restx.json b/restx-shell-manager/md.restx.json deleted file mode 100644 index 6790f9000..000000000 --- a/restx-shell-manager/md.restx.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "parent": "io.restx:restx-parent:${restx.version}", - "module": "io.restx:restx-shell-manager:${restx.version}", - - "properties": { - "@files": ["../restx.build.properties.json"] - }, - - "dependencies": { - "compile": [ - "io.restx:restx-shell:${restx.version}", - "com.fasterxml.jackson.core:jackson-databind:${jackson.version}", - "org.apache.ivy:ivy:${ivy.version}" - ], - "test": [ - "junit:junit:${junit.version}", - "org.assertj:assertj-core:${assertj-core.version}" - ] - } -} diff --git a/restx-shell-manager/module.ivy b/restx-shell-manager/module.ivy deleted file mode 100644 index f970540ce..000000000 --- a/restx-shell-manager/module.ivy +++ /dev/null @@ -1,23 +0,0 @@ -<ivy-module version="2.0" xmlns:ea="http://www.easyant.org"> - <info organisation="io.restx" module="restx-shell-manager" revision="0.35" status="integration"> - <ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.9" - compile.java.source.version="1.7" - compile.java.target.version="1.7" - /> - </info> - <configurations> - <conf name="default"/> - <conf name="runtime"/> - <conf name="test"/> - </configurations> - <publications> - <artifact type="jar"/> - </publications> - <dependencies> - <dependency org="io.restx" name="restx-shell" rev="latest.integration" conf="default" /> - <dependency org="com.fasterxml.jackson.core" name="jackson-databind" rev="2.8.10" conf="default" /> - <dependency org="org.apache.ivy" name="ivy" rev="2.3.0" conf="default" /> - <dependency org="junit" name="junit" rev="4.11" conf="test->default" /> - <dependency org="org.assertj" name="assertj-core" rev="1.6.0" conf="test->default" /> - </dependencies> -</ivy-module> diff --git a/restx-shell-manager/pom.xml b/restx-shell-manager/pom.xml deleted file mode 100644 index 225e08f98..000000000 --- a/restx-shell-manager/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>io.restx</groupId> - <artifactId>restx-parent</artifactId> - <version>0.35-SNAPSHOT</version> - </parent> - - <artifactId>restx-shell-manager</artifactId> - <name>restx-shell-manager</name> - - <dependencies> - <dependency> - <groupId>io.restx</groupId> - <artifactId>restx-shell</artifactId> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </dependency> - <dependency> - <groupId>org.apache.ivy</groupId> - <artifactId>ivy</artifactId> - </dependency> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.assertj</groupId> - <artifactId>assertj-core</artifactId> - <scope>test</scope> - </dependency> - </dependencies> -</project> diff --git a/restx-shell-manager/src/main/java/restx/plugins/ModuleDescriptor.java b/restx-shell-manager/src/main/java/restx/plugins/ModuleDescriptor.java deleted file mode 100644 index 95a0e56fc..000000000 --- a/restx-shell-manager/src/main/java/restx/plugins/ModuleDescriptor.java +++ /dev/null @@ -1,53 +0,0 @@ -package restx.plugins; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * User: xavierhanin - * Date: 5/4/13 - * Time: 2:47 PM - */ -public class ModuleDescriptor { - private final String id; - private final String category; - private final String description; - - @JsonCreator - public ModuleDescriptor(@JsonProperty("id") String id, - @JsonProperty("category") String category, - @JsonProperty("description") String description) { - this.id = id; - this.category = category; - this.description = description; - } - - @Override - public String toString() { - return "ModuleDescriptor{" + - "id='" + id + '\'' + - ", category='" + category + '\'' + - ", description='" + description + '\'' + - '}'; - } - - public String getId() { - return id; - } - - /** - * The module id without revision information - * @return module id without revision information - */ - public String getModuleId() { - return id.substring(0, id.lastIndexOf(":")); - } - - public String getCategory() { - return category; - } - - public String getDescription() { - return description; - } -} diff --git a/restx-shell-manager/src/main/java/restx/plugins/ModulesManager.java b/restx-shell-manager/src/main/java/restx/plugins/ModulesManager.java deleted file mode 100644 index 9ef6de36e..000000000 --- a/restx-shell-manager/src/main/java/restx/plugins/ModulesManager.java +++ /dev/null @@ -1,194 +0,0 @@ -package restx.plugins; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Charsets; -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import com.google.common.io.Files; -import org.apache.ivy.Ivy; -import org.apache.ivy.core.LogOptions; -import org.apache.ivy.core.module.descriptor.DefaultExcludeRule; -import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor; -import org.apache.ivy.core.module.id.ArtifactId; -import org.apache.ivy.core.module.id.ModuleId; -import org.apache.ivy.core.module.id.ModuleRevisionId; -import org.apache.ivy.core.report.ArtifactDownloadReport; -import org.apache.ivy.core.report.DownloadStatus; -import org.apache.ivy.core.report.ResolveReport; -import org.apache.ivy.core.resolve.ResolveOptions; -import org.apache.ivy.plugins.matcher.ExactOrRegexpPatternMatcher; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.regex.Pattern; - -import static com.google.common.collect.Iterables.addAll; - -/** - * User: xavierhanin - * Date: 5/4/13 - * Time: 2:46 PM - */ -public class ModulesManager { - private static final Logger logger = LoggerFactory.getLogger(ModulesManager.class); - - private static final Pattern MRID_PATTERN = Pattern.compile("(.+):(.+):(.+)"); - - private final ObjectMapper mapper = new ObjectMapper(); - private final URL url; - private final Ivy ivy; - - public static class DownloadOptions { - public static final DownloadOptions DEFAULT = new DownloadOptions(Collections.<String>emptyList(), true, false); - - private final ImmutableList<String> exclusions; - private final boolean transitive; - private final boolean changing; - - public DownloadOptions(List<String> exclusions, boolean transitive, boolean changing) { - this.exclusions = ImmutableList.copyOf(exclusions); - this.transitive = transitive; - this.changing = changing; - } - - public ImmutableList<String> getExclusions() { - return exclusions; - } - - public boolean isTransitive() { - return transitive; - } - - public boolean isChanging() { - return changing; - } - - public static class Builder { - private List<String> exclusions; - private boolean transitive; - private boolean changing; - public Builder(){ - this.exclusions = new ArrayList<>(DEFAULT.exclusions); - this.transitive = DEFAULT.transitive; - this.changing = DEFAULT.changing; - } - public Builder transitive(boolean transitive) { this.transitive = transitive; return this; } - public Builder changing(boolean changing) { this.changing = changing; return this; } - public Builder exclusions(List<String> exclusions) { this.exclusions = exclusions; return this; } - public DownloadOptions build(){ return new DownloadOptions(this.exclusions, this.transitive, this.changing); } - } - } - - public ModulesManager(URL url, Ivy ivy) { - this.url = url; - this.ivy = ivy; - } - - public List<ModuleDescriptor> searchModules(String q) throws IOException { - if (q.toLowerCase(Locale.ENGLISH).startsWith("category=")) { - String category = q.substring("category=".length()).toLowerCase(Locale.ENGLISH); - List<ModuleDescriptor> mds = loadAllRestxModuleDescriptors(); - List<ModuleDescriptor> modules = new ArrayList<>(); - for (ModuleDescriptor md : mds) { - if (md.getCategory().equals(category)) { - modules.add(md); - } - } - return modules; - } else { - throw new UnsupportedOperationException("querying for modules other than by category is not supported yet."); - } - } - - public List<File> download(List<ModuleDescriptor> modules, File toDir, DownloadOptions opts) throws IOException { - if (!toDir.exists()) { - if (!toDir.mkdirs()) { - throw new IOException("can't create directory " + toDir); - } - } - List<File> files = new ArrayList<>(); - for (ModuleDescriptor module : modules) { - ivy.pushContext(); // DefaultModuleDescriptor access Ivy current context, so we need to push it. - try { - DefaultModuleDescriptor md = DefaultModuleDescriptor.newCallerInstance( - toMrid(module.getId()), new String[]{"master", "runtime"}, opts.isTransitive(), opts.isChanging()); - for (String exclude : opts.getExclusions()) { - DefaultExcludeRule rule = new DefaultExcludeRule( - new ArtifactId(toModuleId(exclude), ".*", ".*", ".*"), - new ExactOrRegexpPatternMatcher(), - null); - rule.addConfiguration("master"); - rule.addConfiguration("runtime"); - md.addExcludeRule(rule); - } - - ResolveReport report = ivy.resolve(md, - (ResolveOptions) new ResolveOptions() - .setLog(LogOptions.LOG_QUIET) - ); - if (!report.getAllProblemMessages().isEmpty()) { - throw new IllegalStateException("plugin installation failed: " + module.getId() + "\n" - + Joiner.on("\n").join(report.getAllProblemMessages())); - } - for (ArtifactDownloadReport artifactDownloadReport : report.getAllArtifactsReports()) { - if (artifactDownloadReport.getDownloadStatus().equals(DownloadStatus.FAILED)) { - logger.warn(String.format("artifact download %s.%s failed", - artifactDownloadReport.getName(), artifactDownloadReport.getExt())); - continue; - } - File localFile = artifactDownloadReport.getLocalFile(); - File to = new File(toDir, artifactDownloadReport.getName() + "." + artifactDownloadReport.getExt()); - Files.copy(localFile, to); - files.add(to); - } - } catch (ParseException e) { - throw new RuntimeException(e); - } finally { - ivy.popContext(); - } - } - return files; - } - - public static ModuleId toModuleId(String id) { - String[] parts = id.split(":"); - if (parts.length != 2) { - throw new IllegalArgumentException("can't parse module id '" + id + "': it must be of the form groupId:artifactId"); - } - return ModuleId.newInstance(parts[0], parts[1]); - } - - public static boolean isMrid(String id) { - return MRID_PATTERN.matcher(id).matches(); - } - - public static ModuleRevisionId toMrid(String id) { - String[] parts = id.split(":"); - if (parts.length != 3) { - throw new IllegalArgumentException("can't parse module revision id '" + id + "': it must be of the form groupId:artifactId:version"); - } - return ModuleRevisionId.newInstance(parts[0], parts[1], parts[2]); - } - - private List<ModuleDescriptor> loadAllRestxModuleDescriptors() throws IOException { - List<ModuleDescriptor> modules = new ArrayList<>(); - - try (InputStreamReader reader = new InputStreamReader(url.openStream(), Charsets.UTF_8)) { - addAll(modules, mapper - .reader(new TypeReference<ArrayList<ModuleDescriptor>>() { }) - .<Iterable<ModuleDescriptor>>readValue(reader)); - } - - return modules; - } -} diff --git a/restx-shell-manager/src/main/java/restx/plugins/PluginsShellCommand.java b/restx-shell-manager/src/main/java/restx/plugins/PluginsShellCommand.java deleted file mode 100644 index d5bf26caf..000000000 --- a/restx-shell-manager/src/main/java/restx/plugins/PluginsShellCommand.java +++ /dev/null @@ -1,325 +0,0 @@ -package restx.plugins; - -import com.google.common.base.*; -import com.google.common.collect.ImmutableList; -import com.google.common.io.ByteStreams; -import com.google.common.io.CharStreams; -import com.google.common.io.Files; -import com.google.common.io.PatternFilenameFilter; -import com.google.common.io.Resources; -import jline.console.completer.ArgumentCompleter; -import jline.console.completer.Completer; -import jline.console.completer.StringsCompleter; -import org.apache.ivy.core.module.id.ModuleRevisionId; -import org.joda.time.DateTime; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import restx.factory.Component; -import restx.shell.RestxShell; -import restx.shell.ShellCommandRunner; -import restx.shell.ShellIvy; -import restx.shell.StdShellCommand; - -import java.io.*; -import java.net.URL; -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -/** - * User: xavierhanin - * Date: 5/4/13 - * Time: 2:32 PM - */ -@Component -public class PluginsShellCommand extends StdShellCommand { - private static final Logger logger = LoggerFactory.getLogger(PluginsShellCommand.class); - - /* - * this is the default exlcusions list used when fetching plugins (to avoid confusion between lib and plugins dir): - * - we exclude the main modules already part of the shell itself (shell and shell-manager) - * - we exclude logback-classic, to avoid a SLF4J warning at startup if multiple bindings are present - */ - private static final List<String> defaultExcludes = ImmutableList.of( - "io.restx:restx-shell", - "io.restx:restx-shell-manager", - "ch.qos.logback:logback-classic"); - - private static final ModulesManager.DownloadOptions defaultDownloadOptions = new ModulesManager.DownloadOptions.Builder().exclusions(defaultExcludes).build(); - - public PluginsShellCommand() { - super(ImmutableList.of("shell"), "manages the shell itself: install / update plugins, upgrade restx shell version"); - } - - @Override - protected String resourceMan() { - return "restx/plugins/shell.man"; - } - - @Override - protected Optional<? extends ShellCommandRunner> doMatch(String line) { - final List<String> args = splitArgs(line); - if (args.size() < 2) { - return Optional.absent(); - } - switch (args.get(1)) { - case "install": - return Optional.<ShellCommandRunner>of(new InstallPluginRunner(args)); - case "upgrade": - return Optional.<ShellCommandRunner>of(new UpgradeShellRunner()); - } - - return Optional.absent(); - } - - @Override - public Iterable<Completer> getCompleters() { - return ImmutableList.<Completer>of( - new ArgumentCompleter(new StringsCompleter("shell"), new StringsCompleter("install", "upgrade"))); - } - - @Override - public void start(RestxShell shell) throws IOException { - File versionFile = new File(shell.installLocation().toFile(), shell.version()); - if (versionFile.exists()) { - // upgrade check already done - return; - } - - try { - // upgrading to a new version, we check if plugins need to be upgraded - File[] pluginFiles = pluginFiles(pluginsDir(shell)); - - if (pluginFiles.length == 0) { - // no plugin installed, nothing to upgrade - return; - } - - shell.printIn("upgrading to " + shell.version() + " ...", RestxShell.AnsiCodes.ANSI_YELLOW); - shell.println(""); - - ModulesManager modulesManager = new ModulesManager( - new URL("http://restx.io/modules"), ShellIvy.loadIvy(shell)); - - List<ModuleDescriptor> plugins = modulesManager.searchModules("category=shell"); - - Set<String> allJars = new LinkedHashSet<>(); - Set<String> keepJars = new LinkedHashSet<>(); - List<ModuleDescriptor> pluginsToInstall = new ArrayList<>(); - List<String> unmatchedPlugins = new ArrayList<>(); - for (File pluginFile : pluginFiles) { - try { - List<String> desc = Files.readLines(pluginFile, Charsets.UTF_8); - String id = desc.get(0); - ModuleRevisionId mrid = ModulesManager.toMrid(id); - List<String> jars = desc.subList(2, desc.size()); - - - allJars.addAll(jars); - - ModuleDescriptor matchingModule = findMatchingPlugin(plugins, mrid); - - if (matchingModule == null) { - keepJars.addAll(jars); - unmatchedPlugins.add(id); - } else if (ModulesManager.toMrid(matchingModule.getId()).getRevision() - .equals(mrid.getRevision())) { - // up to date - keepJars.addAll(jars); - } else { - pluginsToInstall.add(matchingModule); - } - } catch (Exception e) { - shell.printIn("error while parsing plugin file " + pluginFile + ": " + e, RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - } - } - - if (!unmatchedPlugins.isEmpty()) { - shell.printIn("found unmanaged installed plugins, they won't be upgraded automatically:\n" - + Joiner.on("\n").join(unmatchedPlugins), RestxShell.AnsiCodes.ANSI_YELLOW); - shell.println(""); - } - - Set<String> jarsToRemove = new LinkedHashSet<>(); - jarsToRemove.addAll(allJars); - jarsToRemove.removeAll(keepJars); - - for (String jarToRemove : jarsToRemove) { - logger.debug("removing {}", jarToRemove); - new File(jarToRemove).delete(); - } - - if (!pluginsToInstall.isEmpty()) { - int count = 0; - shell.println("found " + pluginsToInstall.size() + " plugins to upgrade"); - for (ModuleDescriptor md : pluginsToInstall) { - if (installPlugin(shell, modulesManager, pluginsDir(shell), md)) { - count++; - } - } - if (count > 0) { - shell.println("upgraded " + count + " plugins, restarting shell"); - shell.restart(); - } - } - } finally { - Files.write(DateTime.now().toString(), versionFile, Charsets.UTF_8); - } - } - - private ModuleDescriptor findMatchingPlugin(List<ModuleDescriptor> plugins, ModuleRevisionId mrid) { - ModuleDescriptor matchingModule = null; - for (ModuleDescriptor plugin : plugins) { - ModuleRevisionId pluginId = ModulesManager.toMrid(plugin.getId()); - if (pluginId.getModuleId().equals(mrid.getModuleId())) { - matchingModule = plugin; - break; - } - } - return matchingModule; - } - - private class InstallPluginRunner implements ShellCommandRunner { - private final Optional<List<String>> pluginIds; - - public InstallPluginRunner(List<String> args) { - if (args.size() > 2) { - pluginIds = Optional.<List<String>>of(new ArrayList<>(args.subList(2, args.size()))); - } else { - pluginIds = Optional.absent(); - } - } - - @Override - public void run(RestxShell shell) throws Exception { - ModulesManager modulesManager = new ModulesManager( - new URL("http://restx.io/modules"), ShellIvy.loadIvy(shell)); - - shell.println("looking for plugins..."); - List<ModuleDescriptor> plugins = modulesManager.searchModules("category=shell"); - - Iterable<String> selected = null; - if (!pluginIds.isPresent()) { - shell.printIn("found " + plugins.size() + " available plugins", RestxShell.AnsiCodes.ANSI_CYAN); - shell.println(""); - - for (int i = 0; i < plugins.size(); i++) { - ModuleDescriptor plugin = plugins.get(i); - shell.printIn(String.format(" [%3d] %s%n", i + 1, plugin.getId()), RestxShell.AnsiCodes.ANSI_PURPLE); - shell.println("\t\t" + plugin.getDescription()); - } - - String sel = shell.ask("Which plugin would you like to install (eg '1 3 5')? \nYou can also provide a plugin id in the form <groupId>:<moduleId>:<version>\n plugin to install: ", ""); - selected = Splitter.on(" ").trimResults().omitEmptyStrings().split(sel); - } else { - selected = pluginIds.get(); - } - - File pluginsDir = pluginsDir(shell); - int count = 0; - for (String s : selected) { - ModuleDescriptor md; - if (CharMatcher.DIGIT.matchesAllOf(s)) { - int i = Integer.parseInt(s); - md = plugins.get(i - 1); - } else { - md = new ModuleDescriptor(s, "shell", ""); - } - if (installPlugin(shell, modulesManager, pluginsDir, md)) { - count++; - } - } - if (count > 0) { - shell.printIn("installed " + count + " plugins, restarting shell to take them into account", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(""); - - shell.restart(); - } else { - shell.println("no plugin installed"); - } - } - } - - private boolean installPlugin(RestxShell shell, ModulesManager modulesManager, File pluginsDir, ModuleDescriptor md) throws IOException { - shell.printIn("installing " + md.getId() + "...", RestxShell.AnsiCodes.ANSI_CYAN); - shell.println(""); - try { - List<File> copied = modulesManager.download(ImmutableList.of(md), pluginsDir, defaultDownloadOptions); - if (!copied.isEmpty()) { - shell.printIn("installed " + md.getId(), RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(""); - Files.write(md.getId() + "\n" - + DateTime.now() + "\n" - + Joiner.on("\n").join(copied), - pluginFile(pluginsDir, md), Charsets.UTF_8); - return true; - } else { - shell.printIn("problem while installing " + md.getId(), RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - } - } catch (IOException e) { - shell.printIn("IO problem while installing " + md.getId() + "\n" + e.getMessage(), RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - } catch (IllegalStateException e) { - shell.printIn(e.getMessage(), RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - } - return false; - } - - private File pluginsDir(RestxShell shell) { - return new File(shell.installLocation().toFile(), "plugins"); - } - - private File pluginFile(File pluginsDir, ModuleDescriptor md) { - return new File(pluginsDir, md.getModuleId() + ".plugin"); - } - - private File[] pluginFiles(File pluginsDir) { - File[] files = pluginsDir.listFiles(new PatternFilenameFilter(".*\\.plugin")); - return files == null ? new File[0] : files; - } - - private class UpgradeShellRunner implements ShellCommandRunner { - @Override - public void run(RestxShell shell) throws Exception { - shell.println("checking for upgrade of restx shell..."); - - try (Reader reader = new InputStreamReader(new URL("http://restx.io/version").openStream(), Charsets.UTF_8)) { - List<String> parts = CharStreams.readLines(reader); - if (parts.size() < 2) { - shell.printIn( - "unexpected content at http://restx.io/version, try again later or contact the group.\n", - RestxShell.AnsiCodes.ANSI_RED); - shell.println("content: "); - shell.println(Joiner.on("\n").join(parts)); - return; - } - - String version = parts.get(0); - String url = parts.get(1); - - if (!version.equals(shell.version())) { - shell.printIn("upgrading to " + version, RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(""); - shell.println("please wait while downloading new version, this may take a while..."); - - boolean isWindows = System.getProperty("os.name").toLowerCase().indexOf("win") >= 0; - String archiveExt = isWindows ? ".zip" : ".tar.gz"; - String scriptExt = isWindows ? ".bat" : ".sh"; - - URL source = new URL(url + archiveExt); - shell.download(source, shell.installLocation().resolve("upgrade" + archiveExt).toFile()); - - Resources.asByteSource(Resources.getResource(PluginsShellCommand.class, "upgrade" + scriptExt)) - .copyTo(Files.asByteSink(shell.installLocation().resolve("upgrade" + scriptExt).toFile())); - - shell.println("downloaded version " + version + ", restarting"); - shell.restart(); - } - } - } - } -} diff --git a/restx-shell-manager/src/main/resources/restx/plugins/shell.man b/restx-shell-manager/src/main/resources/restx/plugins/shell.man deleted file mode 100644 index d9cfbf7e2..000000000 --- a/restx-shell-manager/src/main/resources/restx/plugins/shell.man +++ /dev/null @@ -1,24 +0,0 @@ -## shell install [<plugin.id>] - -Installs plugins for the shell. - -The plugins are installed in `<shell.install.location>/plugins`. - -The shell is automatically reloaded to take new plugins into account. - -You can provide the plugin as a parameter to the `shell install` command, or select them with what restx proposes when -you give no parameter. - -The plugin id is given in Grails like notation: `<group>:<module>:<version>`. You can use http://search.maven.org to -search for them and choose "Grails" on the module detail page to get the id. - -But most of the time you will simply choose in the choices provided by restx, since all restx shell plugins should be -listed there. - -Please note that this command is only used to install shell plugins, not plugins for your app. - -## shell upgrade - -Use this command to check if a new version of restx is available and upgrade your shell. - -Please note that only the shell is upgraded, not your restx apps. \ No newline at end of file diff --git a/restx-shell-manager/src/main/resources/restx/plugins/upgrade.bat b/restx-shell-manager/src/main/resources/restx/plugins/upgrade.bat deleted file mode 100755 index f73430346..000000000 --- a/restx-shell-manager/src/main/resources/restx/plugins/upgrade.bat +++ /dev/null @@ -1,17 +0,0 @@ -:begin -@echo off - -setlocal enabledelayedexpansion - -echo "upgrading RESTX...." - -rmdir "%~dp0lib" /s /q - -set cur=%cd% -cd "%~dp0." -jar xf upgrade.zip -cd %cur% - -del "%~dp0upgrade.zip" - -endlocal \ No newline at end of file diff --git a/restx-shell-manager/src/main/resources/restx/plugins/upgrade.sh b/restx-shell-manager/src/main/resources/restx/plugins/upgrade.sh deleted file mode 100755 index 74e693a0c..000000000 --- a/restx-shell-manager/src/main/resources/restx/plugins/upgrade.sh +++ /dev/null @@ -1,16 +0,0 @@ -#! /usr/bin/env sh - -echo "upgrading RESTX...." - -PRG="$0" -while [ -h "$PRG" ] ; do - PRG=`readlink "$PRG"` -done - -dir=`dirname $PRG` - -rm -rf "$dir/lib" -tar xzf "$dir/upgrade.tar.gz" -C "$dir" - -rm -f "$dir/upgrade.tar.gz" - diff --git a/restx-shell-manager/src/test/java/restx/plugins/ModuleDescriptorTest.java b/restx-shell-manager/src/test/java/restx/plugins/ModuleDescriptorTest.java deleted file mode 100644 index 618f3ede1..000000000 --- a/restx-shell-manager/src/test/java/restx/plugins/ModuleDescriptorTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package restx.plugins; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.*; - -/** - * User: xavierhanin - * Date: 5/4/13 - * Time: 5:43 PM - */ -public class ModuleDescriptorTest { - @Test - public void should_return_module_id() throws Exception { - assertThat(new ModuleDescriptor("io.restx:restx-core:0.2", "description", "shell").getModuleId()) - .isEqualTo("io.restx:restx-core"); - } -} diff --git a/restx-shell-manager/src/test/java/restx/plugins/ModulesManagerTest.java b/restx-shell-manager/src/test/java/restx/plugins/ModulesManagerTest.java deleted file mode 100644 index aded7db58..000000000 --- a/restx-shell-manager/src/test/java/restx/plugins/ModulesManagerTest.java +++ /dev/null @@ -1,118 +0,0 @@ -package restx.plugins; - -import com.google.common.collect.ImmutableList; -import org.apache.ivy.Ivy; -import org.apache.ivy.core.module.id.ModuleId; -import org.apache.ivy.core.module.id.ModuleRevisionId; -import org.junit.Test; -import restx.shell.ShellIvy; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.text.ParseException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * User: xavierhanin - * Date: 5/4/13 - * Time: 3:06 PM - */ -public class ModulesManagerTest { - ModulesManager manager = new ModulesManager(ModulesManagerTest.class.getResource("modules.json"), - testIvy()); - - private Ivy testIvy() { - try { - Ivy ivy = new Ivy(); - ivy.configure(ShellIvy.class.getResource("ivysettings.xml")); - return ivy; - } catch (ParseException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Test - public void should_find_shell_modules() throws Exception { - List<ModuleDescriptor> descriptors = manager.searchModules("category=shell"); - assertThat(descriptors).isNotNull().isNotEmpty().hasSize(2); - assertThat(descriptors.get(0)).isNotNull(); - assertThat(descriptors.get(0).getId()).isEqualTo("io.restx:restx-build-shell:0.2"); - } - - @Test - public void should_parse_mrid() throws Exception { - ModuleRevisionId id = manager.toMrid("io.restx:restx-common:0.2"); - assertThat(id).isNotNull(); - assertThat(id.getOrganisation()).isEqualTo("io.restx"); - assertThat(id.getName()).isEqualTo("restx-common"); - assertThat(id.getRevision()).isEqualTo("0.2"); - } - - @Test - public void should_parse_mid() throws Exception { - ModuleId id = manager.toModuleId("io.restx:restx-common"); - assertThat(id).isNotNull(); - assertThat(id.getOrganisation()).isEqualTo("io.restx"); - assertThat(id.getName()).isEqualTo("restx-common"); - } - - @Test - public void should_download_module() throws Exception { - File toDir = new File("target/restx/tmp"); - delete(toDir); - manager.download( - ImmutableList.<ModuleDescriptor>of(new ModuleDescriptor("com.github.kevinsawicki:http-request:0.1", "shell", "")), - toDir, - ModulesManager.DownloadOptions.DEFAULT); - - assertThat(toDir.list()).containsOnly("http-request.jar"); - delete(toDir); - } - - @Test - public void should_download_module_and_dependencies() throws Exception { - File toDir = new File("target/restx/tmp"); - delete(toDir); - manager.download( - ImmutableList.<ModuleDescriptor>of(new ModuleDescriptor("commons-httpclient:commons-httpclient:2.0", "shell", "")), - toDir, - ModulesManager.DownloadOptions.DEFAULT); - - assertThat(toDir.list()).containsOnly("commons-httpclient.jar", "commons-lang.jar", "commons-logging.jar"); - delete(toDir); - } - - @Test - public void should_download_module_excluding_some_dependencies() throws Exception { - File toDir = new File("target/restx/tmp"); - delete(toDir); - manager.download( - ImmutableList.<ModuleDescriptor>of(new ModuleDescriptor("commons-httpclient:commons-httpclient:2.0", "shell", "")), - toDir, - new ModulesManager.DownloadOptions.Builder().exclusions(Arrays.asList("commons-logging:commons-logging")).build()); - - assertThat(toDir.list()).containsOnly("commons-httpclient.jar", "commons-lang.jar"); - delete(toDir); - } - - void delete(File f) throws IOException { - if (!f.exists()) { - return; - } - if (f.isDirectory()) { - for (File c : f.listFiles()) { - delete(c); - } - } - if (!f.delete()) { - throw new FileNotFoundException("Failed to delete file: " + f); - } - } -} diff --git a/restx-shell-manager/src/test/resources/restx/plugins/modules.json b/restx-shell-manager/src/test/resources/restx/plugins/modules.json deleted file mode 100644 index 3c36e3579..000000000 --- a/restx-shell-manager/src/test/resources/restx/plugins/modules.json +++ /dev/null @@ -1,5 +0,0 @@ -[ - { "id": "io.restx:restx-build-shell:0.2", "description": "This is a test description", "category": "shell"}, - { "id": "io.restx:restx-core-shell:0.2", "description": "This is a test description 2", "category": "shell"}, - { "id": "io.restx:restx-jongo:0.2", "description": "This is a test description 3", "category": "app"} -] \ No newline at end of file diff --git a/restx-shell/md.restx.json b/restx-shell/md.restx.json deleted file mode 100644 index 7d259b97b..000000000 --- a/restx-shell/md.restx.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "parent": "io.restx:restx-parent:${restx.version}", - "module": "io.restx:restx-shell:${restx.version}", - - "properties": { - "@files": ["../restx.build.properties.json"] - }, - - "dependencies": { - "compile": [ - "io.restx:restx-factory:${restx.version}", - "io.restx:restx-build:${restx.version}", - "jline:jline:${jline.version}", - "ch.qos.logback:logback-classic:${logback.version}", - "org.apache.ivy:ivy:${ivy.version}" - ] - } -} diff --git a/restx-shell/module.ivy b/restx-shell/module.ivy deleted file mode 100644 index fc7ce89ae..000000000 --- a/restx-shell/module.ivy +++ /dev/null @@ -1,23 +0,0 @@ -<ivy-module version="2.0" xmlns:ea="http://www.easyant.org"> - <info organisation="io.restx" module="restx-shell" revision="0.35" status="integration"> - <ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.9" - compile.java.source.version="1.7" - compile.java.target.version="1.7" - /> - </info> - <configurations> - <conf name="default"/> - <conf name="runtime"/> - <conf name="test"/> - </configurations> - <publications> - <artifact type="jar"/> - </publications> - <dependencies> - <dependency org="io.restx" name="restx-factory" rev="latest.integration" conf="default" /> - <dependency org="io.restx" name="restx-build" rev="latest.integration" conf="default" /> - <dependency org="jline" name="jline" rev="2.11" conf="default" /> - <dependency org="ch.qos.logback" name="logback-classic" rev="1.0.13" conf="default" /> - <dependency org="org.apache.ivy" name="ivy" rev="2.3.0" conf="default" /> - </dependencies> -</ivy-module> diff --git a/restx-shell/pom.xml b/restx-shell/pom.xml deleted file mode 100644 index 731b7895f..000000000 --- a/restx-shell/pom.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>io.restx</groupId> - <artifactId>restx-parent</artifactId> - <version>0.35-SNAPSHOT</version> - </parent> - - <artifactId>restx-shell</artifactId> - <name>restx-shell</name> - - <dependencies> - <dependency> - <groupId>io.restx</groupId> - <artifactId>restx-factory</artifactId> - </dependency> - <dependency> - <groupId>io.restx</groupId> - <artifactId>restx-build</artifactId> - </dependency> - <dependency> - <groupId>jline</groupId> - <artifactId>jline</artifactId> - </dependency> - <dependency> - <groupId>ch.qos.logback</groupId> - <artifactId>logback-classic</artifactId> - </dependency> - <dependency> - <groupId>org.apache.ivy</groupId> - <artifactId>ivy</artifactId> - </dependency> - </dependencies> -</project> diff --git a/restx-shell/src/main/java/restx/shell/RestxShell.java b/restx-shell/src/main/java/restx/shell/RestxShell.java deleted file mode 100644 index 880b79895..000000000 --- a/restx-shell/src/main/java/restx/shell/RestxShell.java +++ /dev/null @@ -1,530 +0,0 @@ -package restx.shell; - -import com.google.common.base.Joiner; -import com.google.common.base.Optional; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import com.google.common.io.ByteProcessor; -import com.google.common.io.ByteStreams; -import jline.console.ConsoleReader; -import jline.console.completer.Completer; -import restx.build.MavenSupport; -import restx.build.ModuleDescriptor; -import restx.build.RestxJsonSupport; -import restx.common.Version; -import restx.factory.Factory; -import restx.shell.commands.HelpCommand; - -import java.io.*; -import java.net.URL; -import java.net.URLConnection; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.WatchEvent; -import java.util.Collection; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static java.util.Arrays.asList; -import static jline.console.ConsoleReader.RESET_LINE; - -/** - * User: xavierhanin - * Date: 4/9/13 - * Time: 9:42 PM - */ -public class RestxShell implements Appendable { - public static final String DEFAULT_PROMPT = "restx"; - private final ConsoleReader consoleReader; - private final Factory factory; - private final ImmutableSet<ShellCommand> commands; - - private WatchDir watcher; - private final List<WatchListener> listeners = new CopyOnWriteArrayList<>(); - private final ExecutorService watcherExecutorService = Executors.newSingleThreadExecutor(); - private Path currentLocation = Paths.get(System.getProperty("user.dir")); - private ExecMode execMode = ExecMode.INTERACTIVE; - private Optional<String> restXProjectName = Optional.absent(); - - public RestxShell(ConsoleReader consoleReader) { - this(consoleReader, Factory.getInstance()); - } - - public RestxShell(ConsoleReader consoleReader, Factory factory) { - this.consoleReader = consoleReader; - this.factory = factory; - - this.commands = ImmutableSet.copyOf(findCommands()); - - initConsole(consoleReader); - - - } - - public ConsoleReader getConsoleReader() { - return consoleReader; - } - - public Factory getFactory() { - return factory; - } - - public ImmutableSet<ShellCommand> getCommands() { - return commands; - } - - public void start() throws IOException { - execMode = ExecMode.INTERACTIVE; - banner(); - checkIsRestXProjectDirectory(); - showPrompt(consoleReader); - - try { - for (ShellCommand command : commands) { - command.start(this); - } - } catch (ExitShell e) { - terminate(); - return; - } - - installCompleters(); - - boolean exit = false; - while (!exit) { - String line = consoleReader.readLine(); - if(line == null) { // line will be null when EOF, eg ctrl+c - exit = true; - } else { - exit = exec(line); - } - } - - terminate(); - } - - private void terminate() throws IOException { - consoleReader.println("Bye."); - synchronized (this) { - if (watcher != null) { - watcherExecutorService.shutdownNow(); - watcher = null; - } - } - consoleReader.shutdown(); - } - - public void exec(Iterable<String> commands) throws Exception { - execMode = ExecMode.BATCH; - banner(); - - try { - for (String command : commands) { - printIn("> " + command, AnsiCodes.ANSI_PURPLE); - println(""); - doExec(command); - } - } finally { - terminate(); - } - - } - - public static void printIn(Appendable appendable, String msg, String ansiCode) throws IOException { - appendable.append(ansiCode + msg + AnsiCodes.ANSI_RESET); - } - - public static List<String> splitArgs(String line) { - return ImmutableList.copyOf(Splitter.on(" ").omitEmptyStrings().split(line)); - } - - public void printIn(String msg, String ansiCode) throws IOException { - consoleReader.print(ansiCode + msg + AnsiCodes.ANSI_RESET); - } - - @Override - public Appendable append(CharSequence csq) throws IOException { - consoleReader.print(csq); - return this; - } - - @Override - public Appendable append(CharSequence csq, int start, int end) throws IOException { - if (csq != null) { - append(csq.subSequence(start, end)); - } - return this; - } - - @Override - public Appendable append(char c) throws IOException { - consoleReader.print(String.valueOf(c)); - return this; - } - - public String ask(String msg, String defaultValue) throws IOException { - return ask(msg, defaultValue, - "No help provided for that question, sorry, try to figure it out or ask to the community..."); - } - - public String ask(String msg, String defaultValue, String help) throws IOException { - while (true) { - String value = consoleReader.readLine(String.format(msg, defaultValue)); - if (value.trim().isEmpty()) { - return defaultValue; - } else if (value.trim().equals("??")) { - printIn(help, AnsiCodes.ANSI_YELLOW); - println(""); - } else { - return value.trim(); - } - } - } - - public boolean askBoolean(String message, String defaultValue) throws IOException { - return asList("y", "yes", "true", "on").contains(ask(message, defaultValue).toLowerCase(Locale.ENGLISH)); - } - - public boolean askBoolean(String message, String defaultValue, String help) throws IOException { - return asList("y", "yes", "true", "on").contains(ask(message, defaultValue, help).toLowerCase(Locale.ENGLISH)); - } - - - public void print(String s) throws IOException { - append(s); - } - - public void println(String msg) throws IOException { - consoleReader.println(msg); - consoleReader.flush(); - } - - public void printError(String msg, Exception ex) { - System.err.println(msg); - ex.printStackTrace(); - } - - public Path currentLocation() { - return currentLocation; - } - - public void cd(Path path) { - restXProjectName(Optional.<String>absent()); - currentLocation = path; - checkIsRestXProjectDirectory(); - } - - private void checkIsRestXProjectDirectory() { - File currentDirectory = currentLocation.toFile(); - - Optional<ModuleDescriptor> moduleDescriptor = getModuleDescriptor(currentDirectory); - if (moduleDescriptor.isPresent()) { - restXProjectName(Optional.of(moduleDescriptor.get().getGav().getArtifactId())); - } - } - - private Optional<ModuleDescriptor> getModuleDescriptor(File currentDirectory) { - File restXProjectDescriptor = new File(currentDirectory, "md.restx.json"); - if (restXProjectDescriptor.exists()) { - RestxJsonSupport restxJsonSupport = new RestxJsonSupport(); - try { - return Optional.of(restxJsonSupport.parse(restXProjectDescriptor.toPath())); - } catch (IOException e) { - printError("Failed to read md.restx.json", e); - } - } - File mavenProjectDescriptor = new File(currentDirectory, "pom.xml"); - if (mavenProjectDescriptor.exists()) { - MavenSupport mavenSupport = new MavenSupport(); - try { - return Optional.of(mavenSupport.parse(mavenProjectDescriptor.toPath())); - } catch (IOException e) { - printError("Failed to read pom.xml", e); - } - } - - return Optional.absent(); - } - - public Path installLocation() { - return Paths.get(System.getProperty("restx.shell.home", ".")).normalize(); - } - - public void restart() { - try { - if (execMode == ExecMode.BATCH) { - printIn("TERMINATING SHELL [NO AUTO RESTART IN BATCH MODE]...", AnsiCodes.ANSI_GREEN); - println(""); - throw new ExitShell(); - } else { - new File(installLocation().toFile(), ".restart").createNewFile(); - printIn("RESTARTING SHELL...", AnsiCodes.ANSI_RED); - println(""); - throw new ExitShell(); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void watchFile(WatchListener listener) { - synchronized (this) { - if (watcher == null) { - final Path dir = currentLocation(); - watcherExecutorService.execute(new Runnable() { - @Override - public void run() { - try { - watcher = new WatchDir(dir, true) { - @Override - protected void onEvent(WatchEvent.Kind<?> kind, Path path) { - for (WatchListener watchListener : listeners) { - try { - watchListener.onEvent(RestxShell.this, kind, path); - } catch (Exception ex) { - printError("FS event propagation to " + watchListener + - " raised an exception: " + ex, ex); - } - } - } - }; - watcher.processEvents(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }); - } - } - listeners.add(listener); - } - - protected void initConsole(ConsoleReader consoleReader) { - consoleReader.setPrompt(DEFAULT_PROMPT + "> "); - consoleReader.setHistoryEnabled(true); - } - - protected void banner() throws IOException { - consoleReader.println("==============================================================================="); - consoleReader.println("== WELCOME TO RESTX SHELL - " + version() - + (execMode == ExecMode.INTERACTIVE - ? (" - type `help` for help on available commands") - : " - BATCH MODE")); - consoleReader.println("==============================================================================="); - } - - /** - * Executes the given command line. - * - * Note: this won't raise an exception except in case of IOException with the console itself. - * - * @param line the command line to execute - * @return true if the shell should exit after this command, false otherwise. - * @throws IOException - */ - protected boolean exec(String line) throws IOException { - try { - doExec(line); - return false; - } catch (CommandNotFoundException e) { - consoleReader.println("command not found. use `help` to get the list of commands."); - return false; - } catch (ExitShell e) { - return true; - } catch (Exception e) { - consoleReader.println("command " + line + " raised an exception: " + e.getMessage()); - e.printStackTrace(); - return false; - } - } - - /** - * Executes the given command. - * - * Exception raised by command are propagated if any, including the ExitShell exception. - * - * If command is not found, it raises a CommandNotFoundException. - * - * @param line the command line to execute - * @throws Exception - */ - protected void doExec(String line) throws Exception { - for (ShellCommand command : commands) { - Optional<? extends ShellCommandRunner> match = command.match(line); - if (match.isPresent()) { - // store current completers and clean them, so that executing command can perform in a clean env - Collection<Completer> storedCompleters = ImmutableList.copyOf(consoleReader.getCompleters()); - for (Completer completer : storedCompleters) { - consoleReader.removeCompleter(completer); - } - - try { - match.get().run(this); - } finally { - for (Completer completer : ImmutableList.copyOf(consoleReader.getCompleters())) { - consoleReader.removeCompleter(completer); - } - for (Completer completer : storedCompleters) { - consoleReader.addCompleter(completer); - } - showPrompt(consoleReader); - } - return; - } - } - throw new CommandNotFoundException(line); - } - - private void showPrompt(ConsoleReader consoleReader) { - if (restXProjectName.isPresent()) { - consoleReader.setPrompt(AnsiCodes.ANSI_CYAN + restXProjectName.get() + AnsiCodes.ANSI_RESET + "> "); - } else { - consoleReader.setPrompt(DEFAULT_PROMPT + "> "); - } - } - - - protected void installCompleters() { - for (ShellCommand command : commands) { - for (Completer completer : command.getCompleters()) { - consoleReader.addCompleter(completer); - } - } - } - - protected Set<ShellCommand> findCommands() { - Set<ShellCommand> commands = factory.queryByClass(ShellCommand.class).findAsComponents(); - HelpCommand helpCommand = new HelpCommand(commands); - commands = Sets.newLinkedHashSet(commands); - commands.add(helpCommand); - return commands; - } - - public static void main(String[] args) throws Exception { - ConsoleReader consoleReader = new ConsoleReader(); - RestxShell restxShell = new RestxShell(consoleReader); - if (args.length > 0) { - try { - restxShell.exec(Splitter.on("+").trimResults().split(Joiner.on(" ").join(args))); - } catch (CommandNotFoundException e) { - System.out.println("command not found: " + e.getLine()); - System.exit(1); - } - } else { - restxShell.start(); - } - } - - public void restXProjectName(Optional<String> restXProjectName) { - this.restXProjectName = restXProjectName; - } - - public Optional<String> restXProjectName() { - return restXProjectName; - } - - public String version() { - return Version.getVersion("io.restx", "restx-shell"); - } - - public void download(final URL source, File destination) throws IOException { - final String name = source.toString(); - println("downloading " + (name.length() <= 70 ? name : "[...]" + name.substring(name.length() - 65))); - URLConnection connection = source.openConnection(); - final int total = connection.getContentLength(); - final int[] progress = new int[]{0}; - startProgress(name, total); - try (InputStream stream = connection.getInputStream(); - final OutputStream out = new FileOutputStream(destination)) { - ByteStreams.readBytes(stream, - new ByteProcessor<Void>() { - public boolean processBytes(byte[] buffer, int offset, int length) - throws IOException { - out.write(buffer, offset, length); - progress[0] += length; - updateProgress(name, progress[0], total); - return true; - } - - public Void getResult() { - return null; - } - }); - endProgress(name); - } - } - - public void endProgress(String name) throws IOException { - consoleReader.println(); - } - - public void startProgress(String name, long total) throws IOException { - updateProgress(name, 0, total); - } - - public void updateProgress(String name, long progress, long total) throws IOException { - int barWidth = 70; - StringBuilder line = new StringBuilder(); - - if (progress >= total) { - line.append("[").append(Strings.repeat("=", barWidth)).append("]"); - } else { - int p = (int) Math.min(progress * barWidth / total, barWidth - 1); - line.append("[").append(Strings.repeat("=", p)).append(">").append(Strings.repeat(" ", barWidth - p - 1)).append("]"); - } - - line.append(String.format(" %3d", (progress >= total) ? (100) : (progress * 100 / total))).append("%"); - - consoleReader.print("" + RESET_LINE + line); - } - - - public static final class ExitShell extends RuntimeException { } - - public static class AnsiCodes { - public static final String ANSI_RESET = "\u001B[0m"; - public static final String ANSI_BLACK = "\u001B[30m"; - public static final String ANSI_RED = "\u001B[31m"; - public static final String ANSI_GREEN = "\u001B[32m"; - public static final String ANSI_YELLOW = "\u001B[33m"; - public static final String ANSI_BLUE = "\u001B[34m"; - public static final String ANSI_PURPLE = "\u001B[35m"; - public static final String ANSI_CYAN = "\u001B[36m"; - public static final String ANSI_WHITE = "\u001B[37m"; - } - - public static interface WatchListener { - public void onEvent(RestxShell shell, WatchEvent.Kind<?> kind, Path path); - } - - public static enum ExecMode { - INTERACTIVE, BATCH - } - - private static class CommandNotFoundException extends RuntimeException { - private final String line; - - public CommandNotFoundException(String line) { - super("command not found: " + line); - this.line = line; - } - - public String getLine() { - return line; - } - - @Override - public String toString() { - return "CommandNotFoundException{" + - "line='" + line + '\'' + - '}'; - } - } -} diff --git a/restx-shell/src/main/java/restx/shell/ShellCommand.java b/restx-shell/src/main/java/restx/shell/ShellCommand.java deleted file mode 100644 index e100c0898..000000000 --- a/restx-shell/src/main/java/restx/shell/ShellCommand.java +++ /dev/null @@ -1,21 +0,0 @@ -package restx.shell; - -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; -import jline.console.completer.Completer; - -import java.io.IOException; - -/** - * User: xavierhanin - * Date: 4/9/13 - * Time: 10:06 PM - */ -public interface ShellCommand { - Optional<? extends ShellCommandRunner> match(String line); - void help(Appendable appendable) throws IOException; - void man(Appendable appendable) throws IOException; - Iterable<Completer> getCompleters(); - ImmutableList<String> getAliases(); - void start(RestxShell shell) throws IOException; -} diff --git a/restx-shell/src/main/java/restx/shell/ShellCommandRunner.java b/restx-shell/src/main/java/restx/shell/ShellCommandRunner.java deleted file mode 100644 index b6fc08da7..000000000 --- a/restx-shell/src/main/java/restx/shell/ShellCommandRunner.java +++ /dev/null @@ -1,10 +0,0 @@ -package restx.shell; - -/** - * User: xavierhanin - * Date: 4/9/13 - * Time: 10:07 PM - */ -public interface ShellCommandRunner { - void run(RestxShell shell) throws Exception; -} diff --git a/restx-shell/src/main/java/restx/shell/ShellIvy.java b/restx-shell/src/main/java/restx/shell/ShellIvy.java deleted file mode 100644 index b68013723..000000000 --- a/restx-shell/src/main/java/restx/shell/ShellIvy.java +++ /dev/null @@ -1,110 +0,0 @@ -package restx.shell; - -import org.apache.ivy.Ivy; -import org.apache.ivy.plugins.repository.TransferEvent; -import org.apache.ivy.plugins.repository.TransferListener; -import org.apache.ivy.util.DefaultMessageLogger; -import org.apache.ivy.util.Message; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.text.ParseException; - -/** - * User: xavierhanin - * Date: 7/28/13 - * Time: 9:24 PM - */ -public class ShellIvy { - private static final Logger logger = LoggerFactory.getLogger(ShellIvy.class); - - public static Ivy loadIvy(final RestxShell shell) { - Ivy ivy = new Ivy(); - - File settingsFile = shell.installLocation().resolve("ivysettings.xml").toFile(); - try { - if (settingsFile.exists()) { - logger.info("loading ivy settings from " + settingsFile.getAbsolutePath()); - ivy.configure(settingsFile); - } else { - URL settingsURL = ShellIvy.class.getResource("ivysettings.xml"); - logger.info("loading ivy settings from " + settingsURL); - ivy.configure(settingsURL); - } - - ivy.getEventManager().addTransferListener(new TransferListener() { - public void transferProgress(TransferEvent evt) { - switch (evt.getEventType()) { - case TransferEvent.TRANSFER_STARTED: - try { - shell.println("downloading " + evt.getResource().getName()); - } catch (IOException e) { - throw new RuntimeException(e); - } - break; - case TransferEvent.TRANSFER_PROGRESS: - try { - shell.updateProgress(evt.getResource().getName(), evt.getLength(), evt.getTotalLength()); - } catch (IOException e) { - throw new RuntimeException(e); - } - break; - case TransferEvent.TRANSFER_COMPLETED: - try { - shell.updateProgress(evt.getResource().getName(), evt.getTotalLength(), evt.getTotalLength()); - shell.endProgress(evt.getName()); - } catch (IOException e) { - throw new RuntimeException(e); - } - break; - default: - break; - } - } - }); - - ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_DEBUG) { - @Override - public void log(String msg, int level) { - try { - if (level <= Message.MSG_ERR) { - logger.error(msg); - shell.printIn(msg, RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - } else if (level <= Message.MSG_WARN) { - logger.warn(msg); - shell.printIn(msg, RestxShell.AnsiCodes.ANSI_YELLOW); - shell.println(""); - } else if (level <= Message.MSG_INFO) { - logger.info(msg); - shell.println(msg); - } else { - logger.debug(msg); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void doProgress() { - // DO NOTHING, progress is reported thanks to TransferEvent handling - } - - @Override - public void doEndProgress(String msg) { - // DO NOTHING, progress is reported thanks to TransferEvent handling - } - }); - - return ivy; - } catch (ParseException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/restx-shell/src/main/java/restx/shell/StdShellCommand.java b/restx-shell/src/main/java/restx/shell/StdShellCommand.java deleted file mode 100644 index baa70011d..000000000 --- a/restx-shell/src/main/java/restx/shell/StdShellCommand.java +++ /dev/null @@ -1,122 +0,0 @@ -package restx.shell; - -import com.google.common.base.Charsets; -import com.google.common.base.Joiner; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.io.Resources; -import com.samskivert.mustache.Mustache; -import com.samskivert.mustache.Template; -import jline.console.completer.Completer; -import jline.console.completer.StringsCompleter; -import restx.common.MoreResources; -import restx.common.Mustaches; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.net.URL; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -/** - * User: xavierhanin - * Date: 4/9/13 - * Time: 10:24 PM - */ -public abstract class StdShellCommand implements ShellCommand { - private final ImmutableList<String> aliases; - private final String shortDescription; - - protected StdShellCommand(ImmutableList<String> aliases, String shortDescription) { - this.aliases = Preconditions.checkNotNull(aliases); - if (aliases.isEmpty()) { - throw new IllegalArgumentException("aliases must not be empty"); - } - - this.shortDescription = shortDescription; - } - - @Override - public Optional<? extends ShellCommandRunner> match(String line) { - for (String alias : aliases) { - if (matchCommand(line, alias)) { - return doMatch(line); - } - } - - return Optional.absent(); - } - - private boolean matchCommand(String line, String commandName) { - return line.equals(commandName) || line.startsWith(commandName + " "); - } - - protected abstract Optional<? extends ShellCommandRunner> doMatch(String line); - - @Override - public void help(Appendable appendable) throws IOException { - RestxShell.printIn(appendable, String.format("%10s", aliases.get(0)), RestxShell.AnsiCodes.ANSI_GREEN); - appendable.append(" - " + getShortDescription() + "\n"); - } - - @Override - public void man(Appendable appendable) throws IOException { - RestxShell.printIn(appendable, aliases.get(0), RestxShell.AnsiCodes.ANSI_GREEN); - appendable.append(" - " + getShortDescription() + "\n"); - if (aliases.size() > 1) { - appendable.append(" aliases: " + Joiner.on(", ").join(aliases.subList(1, aliases.size())) + "\n"); - } - - String resourceMan = resourceMan(); - if (resourceMan != null) { - appendable.append("\n"); - appendResourceMan(appendable, resourceMan); - appendable.append("\n\n"); - } - } - - protected String resourceMan() { - return null; - } - - @Override - public Iterable<Completer> getCompleters() { - return Collections.<Completer>singleton(commandCompleter()); - } - - protected StringsCompleter commandCompleter() { - return new StringsCompleter(aliases); - } - - public ImmutableList<String> getAliases() { - return aliases; - } - - public String getShortDescription() { - return shortDescription; - } - - - protected List<String> splitArgs(String line) { - return RestxShell.splitArgs(line); - } - - @Override - public void start(RestxShell shell) throws IOException { - } - - protected Appendable appendResourceMan(Appendable appendable, String man) throws IOException { - return appendable.append(Resources.toString(Resources.getResource(man), Charsets.UTF_8)); - } -} diff --git a/restx-shell/src/main/java/restx/shell/WatchDir.java b/restx-shell/src/main/java/restx/shell/WatchDir.java deleted file mode 100644 index 0123509c3..000000000 --- a/restx-shell/src/main/java/restx/shell/WatchDir.java +++ /dev/null @@ -1,137 +0,0 @@ -package restx.shell; - -import java.io.IOException; -import java.nio.file.*; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.HashMap; -import java.util.Map; - -import static java.nio.file.LinkOption.NOFOLLOW_LINKS; -import static java.nio.file.StandardWatchEventKinds.*; - -public class WatchDir { - private final WatchService watcher; - private final Map<WatchKey,Path> keys; - private final boolean recursive; - private boolean trace = false; - - @SuppressWarnings("unchecked") - static <T> WatchEvent<T> cast(WatchEvent<?> event) { - return (WatchEvent<T>)event; - } - - /** - * Register the given directory with the WatchService - */ - private void register(Path dir) throws IOException { - WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); - if (trace) { - Path prev = keys.get(key); - if (prev == null) { - System.out.format("register: %s\n", dir); - } else { - if (!dir.equals(prev)) { - System.out.format("update: %s -> %s\n", prev, dir); - } - } - } - keys.put(key, dir); - } - - /** - * Register the given directory, and all its sub-directories, with the - * WatchService. - */ - private void registerAll(final Path start) throws IOException { - // register directory and sub-directories - Files.walkFileTree(start, new SimpleFileVisitor<Path>() { - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) - throws IOException - { - register(dir); - return FileVisitResult.CONTINUE; - } - }); - } - - /** - * Creates a WatchService and registers the given directory - */ - WatchDir(Path dir, boolean recursive) throws IOException { - this.watcher = FileSystems.getDefault().newWatchService(); - this.keys = new HashMap<>(); - this.recursive = recursive; - - if (recursive) { - registerAll(dir); - } else { - register(dir); - } - } - - /** - * Process all events for keys queued to the watcher - */ - void processEvents() { - for (;;) { - - // wait for key to be signalled - WatchKey key; - try { - key = watcher.take(); - } catch (InterruptedException x) { - return; - } - - Path dir = keys.get(key); - if (dir == null) { - System.err.println("WatchKey not recognized!!"); - continue; - } - - for (WatchEvent<?> event: key.pollEvents()) { - WatchEvent.Kind kind = event.kind(); - - // TBD - provide example of how OVERFLOW event is handled - if (kind == OVERFLOW) { - continue; - } - - // Context for directory entry event is the file name of entry - WatchEvent<Path> ev = cast(event); - Path name = ev.context(); - Path child = dir.resolve(name); - - onEvent(event.kind(), child); - - // if directory is created, and watching recursively, then - // register it and its sub-directories - if (recursive && (kind == ENTRY_CREATE)) { - try { - if (Files.isDirectory(child, NOFOLLOW_LINKS)) { - registerAll(child); - } - } catch (IOException x) { - // ignore to keep sample readbale - } - } - } - - // reset key and remove from set if directory no longer accessible - boolean valid = key.reset(); - if (!valid) { - keys.remove(key); - - // all directories are inaccessible - if (keys.isEmpty()) { - break; - } - } - } - } - - protected void onEvent(WatchEvent.Kind<?> kind, Path path) { - System.out.format("%s: %s\n", kind.name(), path); - } -} \ No newline at end of file diff --git a/restx-shell/src/main/java/restx/shell/commands/ExitCommand.java b/restx-shell/src/main/java/restx/shell/commands/ExitCommand.java deleted file mode 100644 index ad20c1df6..000000000 --- a/restx-shell/src/main/java/restx/shell/commands/ExitCommand.java +++ /dev/null @@ -1,32 +0,0 @@ -package restx.shell.commands; - -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; -import restx.factory.Component; -import restx.shell.RestxShell; -import restx.shell.ShellCommandRunner; -import restx.shell.StdShellCommand; - -import java.io.IOException; - -/** - * User: xavierhanin - * Date: 4/9/13 - * Time: 10:11 PM - */ -@Component -public class ExitCommand extends StdShellCommand { - public ExitCommand() { - super(ImmutableList.of("exit", "quit"), "exits the shell"); - } - - @Override - protected Optional<? extends ShellCommandRunner> doMatch(String line) { - return Optional.of(new ShellCommandRunner() { - @Override - public void run(RestxShell shell) throws IOException { - throw new RestxShell.ExitShell(); - } - }); - } -} diff --git a/restx-shell/src/main/java/restx/shell/commands/HelpCommand.java b/restx-shell/src/main/java/restx/shell/commands/HelpCommand.java deleted file mode 100644 index 9a9f12320..000000000 --- a/restx-shell/src/main/java/restx/shell/commands/HelpCommand.java +++ /dev/null @@ -1,67 +0,0 @@ -package restx.shell.commands; - -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; -import restx.shell.RestxShell; -import restx.shell.ShellCommand; -import restx.shell.ShellCommandRunner; -import restx.shell.StdShellCommand; - -import java.io.IOException; -import java.util.List; -import java.util.Set; - -/** - * User: xavierhanin - * Date: 4/9/13 - * Time: 10:11 PM - */ -public class HelpCommand extends StdShellCommand { - private final Set<ShellCommand> commands; - - public HelpCommand(Set<ShellCommand> commands) { - super(ImmutableList.of("help", "man"), "provides list of commands or a command manual"); - this.commands = commands; - } - - @Override - protected Optional<? extends ShellCommandRunner> doMatch(String line) { - final List<String> args = splitArgs(line); - if (args.size() > 1) { - return Optional.of(new ShellCommandRunner() { - @Override - public void run(RestxShell shell) throws IOException { - man(shell, args.get(1)); - } - }); - } else { - return Optional.of(new ShellCommandRunner() { - @Override - public void run(RestxShell shell) throws IOException { - for (ShellCommand command : commands) { - command.help(shell); - } - shell.println(""); - shell.println("use `help <command>` with any of these commands to get a detailed man on the command"); - shell.println(""); - shell.println("you can use command completion with <TAB> and command history with <UP> <DOWN> and CTRL+R"); - } - }); - } - } - - private void man(RestxShell shell, String command) throws IOException { - for (ShellCommand shellCommand : commands) { - if (shellCommand.getAliases().contains(command)) { - shellCommand.man(shell); - return; - } - } - - if (getAliases().contains(command)) { - man(shell); - } else { - shell.println("command not found: `" + command + "`. use `help` to get the list of available commands."); - } - } -} diff --git a/restx-shell/src/main/java/restx/shell/commands/SystemCommands.java b/restx-shell/src/main/java/restx/shell/commands/SystemCommands.java deleted file mode 100644 index 4689631c8..000000000 --- a/restx-shell/src/main/java/restx/shell/commands/SystemCommands.java +++ /dev/null @@ -1,86 +0,0 @@ -package restx.shell.commands; - -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; -import restx.factory.Module; -import restx.factory.Provides; -import restx.shell.RestxShell; -import restx.shell.ShellCommand; -import restx.shell.ShellCommandRunner; -import restx.shell.StdShellCommand; - -import java.io.File; -import java.util.List; - -/** - * User: xavierhanin - * Date: 4/9/13 - * Time: 10:11 PM - */ -@Module -public class SystemCommands { - - @Provides public ShellCommand cd() { - return new StdShellCommand(ImmutableList.of("cd"), "change current directory") { - @Override - protected Optional<? extends ShellCommandRunner> doMatch(String line) { - List<String> args = splitArgs(line); - - if (args.size() < 2) { - return Optional.absent(); - } - - final String to = args.get(1); - - return Optional.of(new ShellCommandRunner() { - @Override - public void run(RestxShell shell) throws Exception { - shell.cd(shell.currentLocation().resolve(to)); - } - }); - } - }; - } - - @Provides public ShellCommand pwd() { - return new StdShellCommand(ImmutableList.of("pwd"), "print current directory") { - @Override - protected Optional<? extends ShellCommandRunner> doMatch(String line) { - return Optional.of(new ShellCommandRunner() { - @Override - public void run(RestxShell shell) throws Exception { - shell.println(shell.currentLocation().toAbsolutePath().toString()); - } - }); - } - }; - } - - @Provides public ShellCommand ls() { - return new StdShellCommand(ImmutableList.of("ls"), "print current directory content") { - @Override - protected Optional<? extends ShellCommandRunner> doMatch(String line) { - return Optional.of(new ShellCommandRunner() { - @Override - public void run(RestxShell shell) throws Exception { - File currentDir = shell.currentLocation().toFile(); - if (currentDir != null) { - if (currentDir.isDirectory()) { - if (currentDir.list().length > 0) { - for (String contentFileName : currentDir.list()) { - shell.println(contentFileName); - } - } else { - shell.println("Current directory is empty"); - } - } else { - shell.println("Current location is not a directory"); - } - } - } - }); - } - }; - } - -} diff --git a/restx-shell/src/main/resources/logback.xml b/restx-shell/src/main/resources/logback.xml deleted file mode 100644 index 5e710d812..000000000 --- a/restx-shell/src/main/resources/logback.xml +++ /dev/null @@ -1,17 +0,0 @@ -<configuration> - <appender name="FILE" class="ch.qos.logback.core.FileAppender"> - <file>${restx.shell.home}/restx-shell.log</file> - <encoder> - <pattern>%d{HH:mm:ss.SSS} [%-17thread] %-5level %logger{36} - %msg%n</pattern> - </encoder> - </appender> - - <logger name="org.eclipse.jetty.server.AbstractConnector" level="WARN" /> - <logger name="org.eclipse.jetty.server.handler.ContextHandler" level="WARN" /> - <logger name="org.hibernate.validator.internal.engine.ConfigurationImpl" level="WARN" /> - <logger name="restx.factory.Factory" level="WARN" /> - - <root level="warn"> - <appender-ref ref="FILE"/> - </root> -</configuration> \ No newline at end of file diff --git a/restx-shell/src/main/resources/restx/shell/ivysettings.xml b/restx-shell/src/main/resources/restx/shell/ivysettings.xml deleted file mode 100644 index 0562d3458..000000000 --- a/restx-shell/src/main/resources/restx/shell/ivysettings.xml +++ /dev/null @@ -1,28 +0,0 @@ -<ivysettings> - <settings defaultResolver="default" /> - <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/> - <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/> - <resolvers> - <ibiblio name="public" m2compatible="true" /> - <ibiblio name="sonatype-snapshots" m2compatible="true" - root="https://oss.sonatype.org/content/repositories/snapshots/" /> - - <chain name="main" dual="true"> - <resolver ref="shared"/> - <resolver ref="public"/> - </chain> - <chain name="default" returnFirst="true"> - <resolver ref="local"/> - <resolver ref="main"/> - </chain> - <chain name="latest"> - <resolver ref="local"/> - <resolver ref="sonatype-snapshots"/> - <resolver ref="main"/> - </chain> - </resolvers> - <modules> - <module revision="latest.integration" resolver="latest" /> - <module revision=".*-SNAPSHOT" resolver="latest" matcher="regexp" /> - </modules> -</ivysettings> \ No newline at end of file diff --git a/restx-specs-shell/md.restx.json b/restx-specs-shell/md.restx.json deleted file mode 100644 index ff89f461f..000000000 --- a/restx-specs-shell/md.restx.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "parent": "io.restx:restx-parent:${restx.version}", - "module": "io.restx:restx-specs-shell:${restx.version}", - - "properties": { - "@files": ["../restx.build.properties.json"] - }, - - "dependencies": { - "compile": [ - "io.restx:restx-factory:${restx.version}", - "io.restx:restx-shell:${restx.version}", - "io.restx:restx-core-shell:${restx.version}", - "io.restx:restx-specs-server:${restx.version}" - ] - } -} diff --git a/restx-specs-shell/module.ivy b/restx-specs-shell/module.ivy deleted file mode 100644 index 59b895dd2..000000000 --- a/restx-specs-shell/module.ivy +++ /dev/null @@ -1,22 +0,0 @@ -<ivy-module version="2.0" xmlns:ea="http://www.easyant.org"> - <info organisation="io.restx" module="restx-specs-shell" revision="0.35" status="integration"> - <ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.9" - compile.java.source.version="1.7" - compile.java.target.version="1.7" - /> - </info> - <configurations> - <conf name="default"/> - <conf name="runtime"/> - <conf name="test"/> - </configurations> - <publications> - <artifact type="jar"/> - </publications> - <dependencies> - <dependency org="io.restx" name="restx-factory" rev="latest.integration" conf="default" /> - <dependency org="io.restx" name="restx-shell" rev="latest.integration" conf="default" /> - <dependency org="io.restx" name="restx-core-shell" rev="latest.integration" conf="default" /> - <dependency org="io.restx" name="restx-specs-server" rev="latest.integration" conf="default" /> - </dependencies> -</ivy-module> diff --git a/restx-specs-shell/pom.xml b/restx-specs-shell/pom.xml deleted file mode 100644 index 275ef5feb..000000000 --- a/restx-specs-shell/pom.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>io.restx</groupId> - <artifactId>restx-parent</artifactId> - <version>0.35-SNAPSHOT</version> - </parent> - - <artifactId>restx-specs-shell</artifactId> - <name>restx-specs-shell</name> - - <dependencies> - <dependency> - <groupId>io.restx</groupId> - <artifactId>restx-factory</artifactId> - </dependency> - <dependency> - <groupId>io.restx</groupId> - <artifactId>restx-shell</artifactId> - </dependency> - <dependency> - <groupId>io.restx</groupId> - <artifactId>restx-core-shell</artifactId> - </dependency> - <dependency> - <groupId>io.restx</groupId> - <artifactId>restx-specs-server</artifactId> - </dependency> - </dependencies> -</project> diff --git a/restx-specs-shell/src/main/java/restx/specs/shell/SpecsShellCommand.java b/restx-specs-shell/src/main/java/restx/specs/shell/SpecsShellCommand.java deleted file mode 100644 index a588c7ed1..000000000 --- a/restx-specs-shell/src/main/java/restx/specs/shell/SpecsShellCommand.java +++ /dev/null @@ -1,205 +0,0 @@ -package restx.specs.shell; - -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; -import jline.console.completer.ArgumentCompleter; -import jline.console.completer.Completer; -import jline.console.completer.StringsCompleter; -import restx.AppSettings; -import restx.Apps; -import restx.core.shell.DepsShellCommand; -import restx.core.shell.ShellAppRunner; -import restx.core.shell.ShellAppRunner.CompileMode; -import restx.factory.Component; -import restx.factory.NamedComponent; -import restx.factory.SingletonFactoryMachine; -import restx.server.simple.simple.SimpleWebServer; -import restx.shell.RestxShell; -import restx.shell.ShellCommandRunner; -import restx.shell.StdShellCommand; - -import java.awt.*; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * User: xavierhanin - * Date: 4/10/13 - * Time: 4:27 PM - */ -@Component -public class SpecsShellCommand extends StdShellCommand { - protected SpecsShellCommand() { - super(ImmutableList.of("spec"), "restx spec commands: server, test, ... "); - } - - @Override - protected String resourceMan() { - return "restx/specs/shell/spec.man"; - } - - @Override - protected Optional<ShellCommandRunner> doMatch(String line) { - final List<String> args = splitArgs(line); - if (args.size() < 2) { - return Optional.absent(); - } - - switch (args.get(1)) { - case "server": - return Optional.<ShellCommandRunner>of(new SpecServerCommandRunner(args)); - case "test": - if (args.size() > 2 && args.get(2).equals("server")) { - return Optional.<ShellCommandRunner>of(new SpecTestServerCommandRunner(args)); - } - // keep other arguments to run spec test directly with spec test <spec/test/to/run.spec.yaml> - } - - return Optional.absent(); - } - - @Override - public Iterable<Completer> getCompleters() { - return ImmutableList.<Completer>of( - new ArgumentCompleter(new StringsCompleter("spec"), new StringsCompleter("server", "test"), new StringsCompleter("server"))); - } - - private class SpecTestServerCommandRunner implements ShellCommandRunner { - private final List<String> args; - - public SpecTestServerCommandRunner(List<String> args) { - this.args = new ArrayList<>(args); - } - - @Override - public void run(final RestxShell shell) throws Exception { - String basePack; - boolean quiet = false; - if (args.size() > 3 && args.get(3).equalsIgnoreCase("--quiet")) { - args.remove(3); - quiet = true; - } - - if (args.size() > 3) { - basePack = args.get(3); - } else { - Optional<String> pack = Apps.with(shell.getFactory().getComponent(AppSettings.class)) - .guessAppBasePackage(shell.currentLocation()); - if (!pack.isPresent()) { - shell.printIn("can't find base app package, src/main/java should contain a AppServer.java source file somewhere", - RestxShell.AnsiCodes.ANSI_RED); - shell.println(""); - shell.println("alternatively you can provide the base package with `spec test server <base.pack>`"); - return; - } - basePack = pack.get(); - } - AppSettings appSettings = shell.getFactory() - .concat(new SingletonFactoryMachine<>(-10000, NamedComponent.of(String.class, "restx.app.package", basePack))) - .getComponent(AppSettings.class); - - if (!DepsShellCommand.depsUpToDate(shell)) { - shell.println("restx> deps install"); - new DepsShellCommand.InstallDepsCommandRunner().run(shell); - } - - new ShellAppRunner(appSettings, "restx.tests.RestxSpecTestServer", - CompileMode.RESOURCES_ONLY, quiet, false, Collections.<String>emptyList()).run(shell); - } - } - - private class SpecServerCommandRunner implements ShellCommandRunner { - private final List<String> args; - - public SpecServerCommandRunner(List<String> args) { - this.args = args; - } - - @Override - public void run(final RestxShell shell) throws Exception { - final String routerPath; - if (args.size() > 2) { - routerPath = args.get(2); - } else { - routerPath = "/api"; - } - int port = 8888; - if (args.size() > 3) { - port = Integer.parseInt(args.get(3)); - } - - System.setProperty("restx.factory.load", "onrequest"); - final SimpleWebServer webServer = SimpleWebServer.builder() - .setRouterPath(routerPath).setAppBase(".").setPort(port).build(); - webServer.start(); - String uri = webServer.baseUrl() + routerPath; - shell.printIn("SPECS SERVER READY on " + uri + "/\n", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println("type `stop` to stop the server, `help` to get help on available commands"); - - shell.getConsoleReader().setPrompt("spec-server> "); - shell.getConsoleReader().addCompleter(new StringsCompleter("stop", "open", "help")); - - boolean exit = false; - while (!exit) { - String line = shell.getConsoleReader().readLine().trim(); - switch (line) { - case "stop": - exit = stop(shell, webServer); - break; - case "open": - openInBrowser(shell, uri); - break; - case "help": - help(shell); - break; - default: - shell.println( - "command not found. use `help` to get the list of commands."); - } - } - } - - private void openInBrowser(RestxShell shell, String uri) throws IOException { - try { - Desktop.getDesktop().browse(new URI(uri)); - } catch (UnsupportedOperationException e) { - shell.printIn("can't open browser: " + e.getMessage(), RestxShell.AnsiCodes.ANSI_RED); - } catch (IOException e) { - shell.printIn("can't open browser: " + e.getMessage(), RestxShell.AnsiCodes.ANSI_RED); - } catch (URISyntaxException e) { - shell.printIn("can't open browser: " + e.getMessage(), RestxShell.AnsiCodes.ANSI_RED); - } - } - - private boolean stop(RestxShell consoleReader, SimpleWebServer webServer) { - boolean exit; - try { - consoleReader.println("stopping server..."); - webServer.stop(); - exit = true; - } catch (Exception e) { - throw new RuntimeException(e); - } - return exit; - } - - private void help(RestxShell shell) throws IOException { - shell.printIn("stop", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(" - to stop the server"); - - shell.printIn("open", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(" - open a browser on the spec server"); - - shell.printIn("help", RestxShell.AnsiCodes.ANSI_GREEN); - shell.println(" - this help"); - - shell.println(""); - shell.println("to add new routes simply create/edit .spec.yaml file in\n" + - "current directory or subdirectories."); - } - } -} diff --git a/restx-specs-shell/src/main/resources/restx/specs/shell/spec.man b/restx-specs-shell/src/main/resources/restx/specs/shell/spec.man deleted file mode 100644 index 712fbfed2..000000000 --- a/restx-specs-shell/src/main/resources/restx/specs/shell/spec.man +++ /dev/null @@ -1,25 +0,0 @@ -## spec server [<routerPath> [<port>]] - -Starts a spec server, which is recursively scanning current directory for `.spec.yaml` files to use them to mock -your REST API based on these specifications, while the implementation is not yet implemented. - -You can optionnaly specify a router path which by default is `/api` (also called restx mount point), and the port on -which the server should listen. - -## spec test server [--quiet] [<base.pack>] - -Starts a spec test server, also known as infinirest. - -This server scans your application for changes, and automatically run your spec tests whenever your application source -code changes. - -The spec server is an instance of your app with an additional entry in the admin console, which let you see details -of executed tests, and run test manually. - -Options: - -`--quiet` -Run the server in quiet mode, i.e. without console output. - -`<base.pack>` -Sets the application base package, by default restx will try to guess it. \ No newline at end of file diff --git a/restx.build.properties.json b/restx.build.properties.json index 823616778..443786a98 100644 --- a/restx.build.properties.json +++ b/restx.build.properties.json @@ -26,14 +26,10 @@ "metrics.version": "3.1.0", "javax.inject.version": "1", - "jline.version": "2.11", - "mongo-java-driver.version": "2.11.3", "bson4jackson.version": "2.3.1", "jongo.version": "1.3.0", - "ivy.version": "2.3.0", - "servlet-api.version": "2.5", "jetty7.version": "7.6.21.v20160908", @@ -44,7 +40,6 @@ "junit.version": "4.11", "assertj-core.version": "1.6.0", - "maven-verifier.version": "1.4", "mockito.version": "1.9.5", "de.flapdoodle.embed.version": "1.42",