├── .gitignore ├── .travis.yml ├── CONTRIBUTING ├── LICENSE ├── README.md ├── build.gradle ├── deploy_to_bintray.sh ├── fortify.filter ├── fortify.gradle ├── gradle.properties ├── gradlew ├── gradlew.bat ├── jacoco.gradle ├── java.gradle ├── java ├── conf │ ├── checkstyle.xml │ ├── codenarc.groovy │ └── pmd.xml ├── core │ ├── META-INF │ │ └── MANIFEST.MF │ ├── build.gradle │ ├── gradle.properties │ └── src │ │ ├── main │ │ ├── java │ │ │ └── radl │ │ │ │ ├── common │ │ │ │ ├── StringUtil.java │ │ │ │ ├── io │ │ │ │ │ ├── ByteArrayInputOutputStream.java │ │ │ │ │ ├── IO.java │ │ │ │ │ └── StringStream.java │ │ │ │ └── xml │ │ │ │ │ ├── DocumentBuilder.java │ │ │ │ │ ├── ElementProcessor.java │ │ │ │ │ ├── Xml.java │ │ │ │ │ └── XmlException.java │ │ │ │ ├── core │ │ │ │ ├── Log.java │ │ │ │ ├── Radl.java │ │ │ │ ├── cli │ │ │ │ │ ├── Application.java │ │ │ │ │ ├── Arguments.java │ │ │ │ │ └── Cli.java │ │ │ │ ├── code │ │ │ │ │ ├── Code.java │ │ │ │ │ ├── GeneratedSourceFile.java │ │ │ │ │ ├── GenericSyntax.java │ │ │ │ │ ├── Lines.java │ │ │ │ │ ├── SourceFile.java │ │ │ │ │ ├── Syntax.java │ │ │ │ │ ├── common │ │ │ │ │ │ ├── Constant.java │ │ │ │ │ │ └── Constants.java │ │ │ │ │ ├── radl │ │ │ │ │ │ ├── MediaType.java │ │ │ │ │ │ ├── Property.java │ │ │ │ │ │ ├── PropertyGroup.java │ │ │ │ │ │ ├── PropertyGroups.java │ │ │ │ │ │ ├── PropertyImpl.java │ │ │ │ │ │ └── RadlCode.java │ │ │ │ │ └── xml │ │ │ │ │ │ ├── NestedXml.java │ │ │ │ │ │ ├── XmlCode.java │ │ │ │ │ │ ├── XmlIndent.java │ │ │ │ │ │ └── XmlSyntax.java │ │ │ │ ├── documentation │ │ │ │ │ ├── DocumentationGenerator.java │ │ │ │ │ ├── JGraphStateDiagram.java │ │ │ │ │ ├── StateDiagram.java │ │ │ │ │ └── StateDiagramGenerator.java │ │ │ │ ├── enforce │ │ │ │ │ ├── Desired.java │ │ │ │ │ ├── Enforcer.java │ │ │ │ │ └── Reality.java │ │ │ │ ├── extraction │ │ │ │ │ ├── AddAction.java │ │ │ │ │ ├── ExtractOptions.java │ │ │ │ │ ├── IgnoreAction.java │ │ │ │ │ ├── MergedMethods.java │ │ │ │ │ ├── Method.java │ │ │ │ │ ├── RadlExtractor.java │ │ │ │ │ ├── RadlMerger.java │ │ │ │ │ ├── ReplaceAction.java │ │ │ │ │ ├── ResourceModel.java │ │ │ │ │ ├── ResourceModelHolder.java │ │ │ │ │ ├── ResourceModelImpl.java │ │ │ │ │ ├── ResourceModelMerger.java │ │ │ │ │ ├── ResourceModelSerializer.java │ │ │ │ │ ├── UriTemplateAction.java │ │ │ │ │ ├── UriTemplateComparison.java │ │ │ │ │ └── UriTemplateVar.java │ │ │ │ ├── generation │ │ │ │ │ ├── CodeBaseGenerator.java │ │ │ │ │ ├── CodeBaseGeneratorImpl.java │ │ │ │ │ ├── CodeGenerator.java │ │ │ │ │ ├── DesiredSourceFiles.java │ │ │ │ │ ├── Module.java │ │ │ │ │ ├── RealSourceFiles.java │ │ │ │ │ └── SourceFilesGenerator.java │ │ │ │ ├── scm │ │ │ │ │ ├── DefaultSourceCodeManagementSystem.java │ │ │ │ │ ├── OperatingSystem.java │ │ │ │ │ ├── OperatingSystemImpl.java │ │ │ │ │ ├── Perforce.java │ │ │ │ │ ├── ScmFactory.java │ │ │ │ │ └── SourceCodeManagementSystem.java │ │ │ │ ├── validation │ │ │ │ │ ├── CheckStyleIssueReporter.java │ │ │ │ │ ├── CompositeValidator.java │ │ │ │ │ ├── Issue.java │ │ │ │ │ ├── IssueReporter.java │ │ │ │ │ ├── IssueReporterFactory.java │ │ │ │ │ ├── LintValidator.java │ │ │ │ │ ├── RadlValidator.java │ │ │ │ │ ├── RelaxNgValidator.java │ │ │ │ │ └── Validator.java │ │ │ │ └── xml │ │ │ │ │ ├── DocumentProcessor.java │ │ │ │ │ ├── RadlFileAssembler.java │ │ │ │ │ └── XmlMerger.java │ │ │ │ └── java │ │ │ │ ├── code │ │ │ │ ├── ImportComparator.java │ │ │ │ ├── Java.java │ │ │ │ ├── JavaBeanProperty.java │ │ │ │ ├── JavaCode.java │ │ │ │ └── JavaSyntax.java │ │ │ │ ├── extraction │ │ │ │ ├── AbstractRestAnnotationProcessor.java │ │ │ │ ├── AbstractRestProcessor.java │ │ │ │ ├── Clock.java │ │ │ │ ├── FromJavaExtractOptions.java │ │ │ │ ├── FromJavaRadlExtractor.java │ │ │ │ ├── JaxrsProcessor.java │ │ │ │ ├── Parameter.java │ │ │ │ ├── ProcessorOptions.java │ │ │ │ ├── SpringProcessor.java │ │ │ │ ├── SystemClock.java │ │ │ │ └── Timer.java │ │ │ │ └── generation │ │ │ │ └── spring │ │ │ │ ├── AbstractControllersGenerator.java │ │ │ │ ├── ActionsGenerator.java │ │ │ │ ├── ApiGenerator.java │ │ │ │ ├── ControllerSupportsGenerator.java │ │ │ │ ├── ControllersGenerator.java │ │ │ │ ├── DtosGenerator.java │ │ │ │ ├── ErrorDtoGenerator.java │ │ │ │ ├── ExceptionHandlerGenerator.java │ │ │ │ ├── ExceptionsGenerator.java │ │ │ │ ├── FromRadlCodeGenerationInitializer.java │ │ │ │ ├── FromRadlCodeGenerator.java │ │ │ │ ├── FromRadlErrorsCodeGenerator.java │ │ │ │ ├── IdentifiableGenerator.java │ │ │ │ ├── RadlToSpringServer.java │ │ │ │ ├── RestResponseGenerator.java │ │ │ │ ├── SpringCodeBaseGenerator.java │ │ │ │ ├── SpringSourceFilesGenerator.java │ │ │ │ └── UrisGenerator.java │ │ └── resources │ │ │ └── META-INF │ │ │ └── services │ │ │ ├── radl.core.extraction.RestProcessor │ │ │ ├── radl.core.scm.SourceCodeManagementSystem │ │ │ └── radl.core.validation.IssueReporter │ │ └── test │ │ ├── java │ │ └── radl │ │ │ ├── core │ │ │ ├── cli │ │ │ │ └── ArgumentsTest.java │ │ │ ├── code │ │ │ │ ├── CodeTest.java │ │ │ │ ├── GeneratedSourceFileTest.java │ │ │ │ ├── LinesTest.java │ │ │ │ ├── RadlCodeTest.java │ │ │ │ ├── SourceFileTest.java │ │ │ │ └── XmlCodeTest.java │ │ │ ├── documentation │ │ │ │ ├── AssertEquals.java │ │ │ │ ├── Assertion.java │ │ │ │ ├── DocumentationGeneratorTest.java │ │ │ │ ├── DocumentationTest.java │ │ │ │ ├── DocumentationVerifier.java │ │ │ │ ├── JGraphStateDiagramTest.java │ │ │ │ ├── LiteralValue.java │ │ │ │ ├── SelectorValue.java │ │ │ │ ├── StateDiagramGeneratorTest.java │ │ │ │ ├── TestParser.java │ │ │ │ └── Value.java │ │ │ ├── enforce │ │ │ │ └── EnforcerTest.java │ │ │ ├── extraction │ │ │ │ ├── RadlMergerTest.java │ │ │ │ └── ResourceModelImplTest.java │ │ │ ├── generation │ │ │ │ ├── DesiredSourceFilesTest.java │ │ │ │ └── RealSourceFilesTest.java │ │ │ ├── integration │ │ │ │ ├── GenerateAndExtractTest.java │ │ │ │ ├── JavaCompiler.java │ │ │ │ └── RadlComparer.java │ │ │ ├── io │ │ │ │ ├── ByteArrayInputOutputStreamTest.java │ │ │ │ └── IOTest.java │ │ │ ├── scm │ │ │ │ ├── OperatingSystemImplTest.java │ │ │ │ ├── PerforceTest.java │ │ │ │ └── ScmFactoryTest.java │ │ │ ├── validation │ │ │ │ ├── CheckStyleIssueReporterTest.java │ │ │ │ ├── CompositeValidatorTest.java │ │ │ │ ├── IssueReporterFactoryTest.java │ │ │ │ ├── LintValidatorTest.java │ │ │ │ ├── PrintStreamIssueReporter.java │ │ │ │ ├── RadlValidatorTest.java │ │ │ │ ├── RelaxNgValidatorTest.java │ │ │ │ └── TestIssueReporter.java │ │ │ └── xml │ │ │ │ ├── DocumentBuilderTest.java │ │ │ │ ├── RadlFileAssemblerTest.java │ │ │ │ ├── XmlMergerTest.java │ │ │ │ └── XmlTest.java │ │ │ ├── java │ │ │ ├── code │ │ │ │ ├── JavaCodeTest.java │ │ │ │ └── JavaTest.java │ │ │ ├── extraction │ │ │ │ ├── AbstractRestAnnotationProcessorTest.java │ │ │ │ ├── FromJavaRadlExtractorTest.java │ │ │ │ ├── JaxrsProcessorTest.java │ │ │ │ ├── SpringProcessorTest.java │ │ │ │ ├── TimerTest.java │ │ │ │ └── test │ │ │ │ │ ├── Annotatable.java │ │ │ │ │ ├── Annotation.java │ │ │ │ │ ├── AnnotationBuilder.java │ │ │ │ │ ├── Documentable.java │ │ │ │ │ ├── Method.java │ │ │ │ │ ├── MethodBuilder.java │ │ │ │ │ ├── Parameter.java │ │ │ │ │ ├── ParameterBuilder.java │ │ │ │ │ ├── Project.java │ │ │ │ │ ├── ProjectBuilder.java │ │ │ │ │ ├── TestName.java │ │ │ │ │ ├── TestRoundEnvironment.java │ │ │ │ │ ├── Type.java │ │ │ │ │ └── TypeBuilder.java │ │ │ └── generation │ │ │ │ └── spring │ │ │ │ ├── AbstractSpringCodeGeneratorTestCase.java │ │ │ │ ├── ApiGeneratorTest.java │ │ │ │ ├── ControllerGeneratorTest.java │ │ │ │ ├── ControllerSupportGeneratorTest.java │ │ │ │ ├── DtosGeneratorTest.java │ │ │ │ ├── ErrorDtoGeneratorTest.java │ │ │ │ ├── ExceptionsGeneratorTest.java │ │ │ │ ├── RadlToSpringServerTest.java │ │ │ │ ├── SpringSourceFilesGeneratorTest.java │ │ │ │ └── UrisGeneratorTest.java │ │ │ └── test │ │ │ ├── ErrorBuilder.java │ │ │ ├── LinkRelationBuilder.java │ │ │ ├── LinkRelationsBuilder.java │ │ │ ├── MethodBuilder.java │ │ │ ├── PropertGroupContainer.java │ │ │ ├── PropertyBuilder.java │ │ │ ├── PropertyGroupBuilder.java │ │ │ ├── RadlBuilder.java │ │ │ ├── RandomData.java │ │ │ ├── ResourceBuilder.java │ │ │ ├── StateBuilder.java │ │ │ ├── StatesBuilder.java │ │ │ ├── TestUtil.java │ │ │ └── TransitionBuilder.java │ │ └── resources │ │ ├── META-INF │ │ └── services │ │ │ └── radl.core.validation.IssueReporter │ │ └── radl │ │ └── core │ │ ├── documentation │ │ └── radl-test.css │ │ └── xml │ │ ├── sample-complete.radl │ │ ├── sample-part1.radl │ │ ├── sample-part2.radl │ │ ├── sample-part3.radl │ │ ├── sample-part4.radl │ │ └── sample-part5.radl ├── eclipse │ ├── META-INF │ │ └── MANIFEST.MF │ ├── build.gradle │ ├── build.properties │ ├── features.gradle │ ├── gradle.properties │ ├── icons │ │ └── api.gif │ ├── lib │ │ └── eclipse │ │ │ ├── org.eclipse.core.commands_3.6.0.I20100512-1500.jar │ │ │ ├── org.eclipse.core.contenttype_3.4.100.v20100505-1235.jar │ │ │ ├── org.eclipse.core.databinding.observable_1.3.0.I20100601-0800.jar │ │ │ ├── org.eclipse.core.databinding.property_1.3.0.I20100601-0800.jar │ │ │ ├── org.eclipse.core.databinding_1.3.100.I20100601-0800.jar │ │ │ ├── org.eclipse.core.expressions_3.4.200.v20100505.jar │ │ │ ├── org.eclipse.core.filesystem_1.3.0.v20100526-0737.jar │ │ │ ├── org.eclipse.core.jobs_3.5.0.v20100515.jar │ │ │ ├── org.eclipse.core.resources_3.6.0.v20100526-0737.jar │ │ │ ├── org.eclipse.core.runtime_3.6.0.v20100505.jar │ │ │ ├── org.eclipse.equinox.app_1.3.0.v20100512.jar │ │ │ ├── org.eclipse.equinox.common_3.6.0.v20100503.jar │ │ │ ├── org.eclipse.equinox.preferences_3.3.0.v20100503.jar │ │ │ ├── org.eclipse.equinox.registry_3.5.0.v20100503.jar │ │ │ ├── org.eclipse.help_3.5.0.v20100524.jar │ │ │ ├── org.eclipse.jdt.core_3.6.0.xx-20100630-0900-e36.jar │ │ │ ├── org.eclipse.jdt.launching_3.5.100.v20100526.jar │ │ │ ├── org.eclipse.jdt.ui_3.6.1.r361_v20100825-0800.jar │ │ │ ├── org.eclipse.jface.databinding_1.4.0.I20100601-0800.jar │ │ │ ├── org.eclipse.jface.text_3.6.1.r361_v20100825-0800.jar │ │ │ ├── org.eclipse.jface_3.6.1.M20100825-0800.jar │ │ │ ├── org.eclipse.ltk.core.refactoring_3.5.200.v20110505-0800.jar │ │ │ ├── org.eclipse.osgi_3.6.0.v20100517.jar │ │ │ ├── org.eclipse.swt.win32.win32.x86_3.6.0.v3650b.jar │ │ │ ├── org.eclipse.swt_3.6.0.v3650b.jar │ │ │ ├── org.eclipse.text_3.5.0.v20100601-1300.jar │ │ │ ├── org.eclipse.ui.ide_3.6.0.I20100601-0800.jar │ │ │ ├── org.eclipse.ui.workbench_3.6.0.I20100603-1100.jar │ │ │ └── org.eclipse.ui_3.6.0.I20100603-1100.jar │ ├── plugin.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── radl │ │ │ └── eclipse │ │ │ ├── builder │ │ │ ├── RadlBuilder.java │ │ │ ├── RadlNature.java │ │ │ └── RadlValidatingVisitor.java │ │ │ └── wizards │ │ │ ├── RadlCreator.java │ │ │ ├── RadlNewWizard.java │ │ │ └── RadlNewWizardPage.java │ │ └── test │ │ └── java │ │ └── radl │ │ └── eclipse │ │ ├── builder │ │ ├── RadlNatureTest.java │ │ └── RadlValidatingVisitorTest.java │ │ └── wizards │ │ └── RadlCreatorTest.java ├── gradle │ ├── build.gradle │ ├── gradle.properties │ └── src │ │ └── main │ │ ├── groovy │ │ └── radl │ │ │ └── gradle │ │ │ ├── RadlExtension.groovy │ │ │ └── RadlPlugin.groovy │ │ └── resources │ │ └── META-INF │ │ └── gradle-plugins │ │ └── radl-gradle.properties └── maven │ ├── build.gradle │ ├── gradle.properties │ └── src │ └── main │ ├── java │ └── radl │ │ └── maven │ │ ├── MavenConfig.java │ │ ├── Radl2HtmlDocPlugin.java │ │ ├── Radl2SpringPlugin.java │ │ ├── RadlFromCodePlugin.java │ │ ├── RadlValidationPlugin.java │ │ └── util │ │ └── RadlFileUtil.java │ └── resources │ └── META-INF │ └── maven │ ├── plugin.xml │ └── radl │ └── radl-maven │ └── plugin-help.xml ├── logo.png ├── settings.gradle ├── specification ├── examples │ ├── restbucks.radl │ └── xacml.radl ├── schema │ ├── documentation.rnc │ ├── radl.rnc │ └── ref.rnc ├── spec.md ├── tests │ ├── README.md │ ├── documentation │ │ └── linksToMediaTypeSpecification │ │ │ ├── instance.xml │ │ │ └── test.xml │ └── validation │ │ ├── reportsErrorOnDuplicateLinkRelation │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── reportsErrorOnDuplicateMediaType │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── reportsErrorOnDuplicateResource │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── reportsErrorOnDuplicateState │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── reportsErrorOnResourcesWithTheSameLocation │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── reportsErrorOnUndefinedConsumedMediaType │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── reportsErrorOnUndefinedProducedMediaType │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnActionUri │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnDisconnectedState │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnDuplicateVariableInUriTemplate │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnInitialTransitionToUndefinedState │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnMethodThatDoesntImplementATransition │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnMethodThatImplementsUndefinedTransition │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnMethodWithoutRequestAndResponse │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnMissingLocation │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnMissingStartState │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnOverlappingUriAndUriTemplate │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnRepeatedPartInUri │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnResourceWithoutMethod │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnTransitionToUndefinedState │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnUnconnectedStartState │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnUndefinedTransition │ │ ├── instance.xml │ │ └── issue.xml │ │ ├── warnsOnUndiscoverableTransition │ │ ├── instance.xml │ │ └── issue.xml │ │ └── warnsOnUnimplementedTransition │ │ ├── instance.xml │ │ └── issue.xml └── xslt │ ├── radl-default.css │ └── radl2html.xsl └── wrapper ├── wrapper.jar └── wrapper.properties /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | bin/ 3 | classes/ 4 | .settings/ 5 | .gradle/ 6 | .classpath 7 | .project 8 | 9 | *.iws 10 | 11 | *.iml 12 | 13 | .idea/**/*.* 14 | 15 | **/target/**/*.* 16 | 17 | *.ipr 18 | 19 | java/maven/pom.xml 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false # Run on containers rather than VMs to enable caching 2 | cache: 3 | directories: 4 | - $HOME/.gradle 5 | - .gradle 6 | env: 7 | global: 8 | - USER=ApiSecRay 9 | # BINTRAY API KEY: 10 | - secure: XgXG6UVWg8+MpXXaNH0c3w3Tsp9XBi1eXPbGUi16ztZUS/DVDnCbrFFX1ABXz4Dw+qCER67hjtcL6O0bczt1oJFFurC1tMzSXqZSrVIDcDAEVKCi08dy73yxm0QX4HFWg/z67O0DzJi8teYMcItSgBAsKbhnVEV+mnYxS/wR86c= 11 | # COVERITY API KEY: 12 | - secure: "Rtj2gG4t84+r62T4IXOsJPA+3R8cfFJaCrehh8W9gFGXTRvwEnpBLkjJGBT//DhpnENZFncjy7Kk5LdDY3dY4qBtek+lxrAXTWqHmxOAEuwHBymlSWsQt0II1LD8HmmHeMUvo2LPq6flbZG7x4qR6/bk2y5BFAtdLn8G3G/CbOg=" 13 | # HIPCHAT API KEY: 14 | - secure: "UN6AK7fRKtaR50eo6IMCTeAgBkQUiCXu1PizMyHqwMesPGWIcuTZ1mSse65+lua6bfk9nabKVj/fTfP+1/mYPUZk+ltQJnoEGGfR+SB/8EzH6 15 | WesK3eGbG8jWz+Lm2tVFBhppZ+DMpUzDtcv5I+S1/fg0T8PT6ckvejBzDmqqXw=" 16 | 17 | language: java 18 | jdk: 19 | - openjdk7 20 | install: true 21 | script: ./gradlew build 22 | 23 | 24 | ## Notifications 25 | notifications: 26 | slack: 27 | secure: LJfuvagJjFqaoA8AJQtfLOtymOzpifA2qUqA1XI5Kd67sVFY5BViIHZ/+qy3jV+Ve7Msl8St+XiB9zrLqKOxFNNaFvYZYgpn4fb4RDxVWipZrVY9/DRwEImzuWNsx1Il7rn9zWK0jgmIyK2DK6wtWPnZUTinHGPIw3RtvR22AyA= 28 | webhooks: 29 | urls: 30 | - https://webhooks.gitter.im/e/9964f490aeaa2be3c3c9 31 | on_success: always 32 | on_failure: always 33 | on_start: true 34 | hipchat: $HIPCHAT_KEY@Radl 35 | 36 | after_success: 37 | - ./deploy_to_bintray.sh 38 | - bash <(curl -s https://codecov.io/bash) 39 | 40 | before_deploy: 41 | - gem install mime-types -v 2.6.2 42 | 43 | deploy: 44 | provider: releases 45 | api_key: 46 | secure: KQctlwYK908PwgFmD0huCtraaN/XyE3Ev7nz2KK6CJ8N4jrBN+m+7U4N+GgMICrgpjPUnjeye5ZRk1YFxKvvsIiAYRPdCfNZ2R5VKV6vLt8+d1VZP6ndxLuzigdwlYiVVlCHig9X7JQwuvYjGyaOUOVKTBjMvPrn+wUUhSyoDK4= 47 | skip_cleanup: true 48 | file_glob: true 49 | file: 50 | - java/core/build/libs/* 51 | - java/eclipse/build/libs/* 52 | - java/gradle/build/libs/* 53 | - java/maven/build/libs/* 54 | on: 55 | repo: restful-api-description-language/RADL 56 | tags: true 57 | all_branches: true 58 | 59 | addons: 60 | coverity_scan: 61 | project: 62 | name: "restful-api-description-language/RADL" 63 | description: "Build submitted via Travis CI" 64 | notification_email: rssinnema@yahoo.com 65 | build_command_prepend: "./gradlew clean" 66 | build_command: "./gradlew assemble" 67 | branch_pattern: coverity_scan 68 | -------------------------------------------------------------------------------- /CONTRIBUTING: -------------------------------------------------------------------------------- 1 | See https://github.com/restful-api-description-language/RADL/wiki/Contributing. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/README.md -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | task wrapper(type: Wrapper) { 2 | description = 'Generates gradlew (for internal use only)' 3 | gradleVersion = '2.11' 4 | jarFile = 'wrapper/wrapper.jar' 5 | } 6 | 7 | subprojects.findAll { it.path.startsWith(':java:') }.each { 8 | it.apply from: file('java.gradle') 9 | } 10 | 11 | defaultTasks 'check' 12 | -------------------------------------------------------------------------------- /deploy_to_bintray.sh: -------------------------------------------------------------------------------- 1 | if [ ! -z "$TRAVIS_TAG" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then 2 | for package in "core" "gradle" "maven"; do 3 | echo Uploading radl-$package to BinTray 4 | for path in java/$package/build/libs/*; do 5 | version=$(basename $path | awk -F- '{print $3}' | cut -d. -f1-3) 6 | file=$(basename $path) 7 | echo " $file" 8 | curl -T $path -u$USER:$BINTRAY_KEY https://api.bintray.com/content/radl/RADL/radl/radl-$package/$version/$(basename $path)\;bt_package=radl-$package\;bt_version=$version\;publish=1\;override=1 9 | done 10 | done 11 | else 12 | echo TRAVIS_TAG=$TRAVIS_TAG 13 | echo TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST 14 | echo TRAVIS_SECURE_ENV_VARS=$TRAVIS_SECURE_ENV_VARS 15 | fi 16 | -------------------------------------------------------------------------------- /fortify.filter: -------------------------------------------------------------------------------- 1 | Dead Code 2 | Denial of Service 3 | J2EE Bad Practices 4 | Path Manipulation 5 | Poor Error Handling 6 | Poor Style 7 | Redundant Null Check 8 | Setting Manipulation 9 | System Information Leak: Internal 10 | Unchecked Return Value 11 | 12 | 13 | # Dynamic Code Evaluation: Unsafe Deserialization at core/src/main/java/radl/core/extraction/ResourceModelSerializer.java:36 14 | 2AC4D2D5E4AF5DA2CA9626EE1C28FF87 15 | 16 | # Code Correctness: Class Does Not Implement equals at core/src/main/java/radl/core/enforce/Enforcer.java:62 17 | 7386485C6D0221D050F612C680A27C9D 18 | 19 | # Command Injection at core/src/main/java/radl/core/scm/OperatingSystemImpl.java:12 20 | 4C1E50C28290C3AC7FABE1EE6B0A2B10 21 | 22 | # Missing XML Validation at core/src/main/java/radl/common/xml/Xml.java:204 23 | EAD4B05E08B003FD6B8AF80F676C7607 24 | 25 | # System Information Leak at core/src/main/java/radl/java/code/Java.java:59 26 | 41780D7942540F52B6CA5E1382227BF9 -------------------------------------------------------------------------------- /fortify.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Scan the source with Fortify SCA. Only works from within EMC. 3 | * Use this as a Gradle init script, using e.g. './gradlew -I fortify.gradle sca' 4 | */ 5 | 6 | initscript { 7 | repositories { 8 | maven { url 'http://maven.xhive.archipel/artifactory/remote-repos' } 9 | } 10 | dependencies { 11 | classpath 'com.emc.gradle:fortify:1.448' 12 | } 13 | } 14 | 15 | apply plugin: FortifyInitPlugin 16 | 17 | class FortifyInitPlugin implements Plugin { 18 | 19 | void apply(Gradle gradle) { 20 | gradle.allprojects { project -> 21 | if (project.path == ':') { // Root project 22 | project.apply plugin: 'java' 23 | project.apply plugin: com.emc.gradle.fortify.FortifyPlugin 24 | 25 | project.convention.plugins.fortify.filter = project.file('fortify.filter') 26 | project.subprojects.each { 27 | it.convention.plugins.fortify.scan = it.path.startsWith(':java:') 28 | } 29 | } 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | codeNarcVersion = 0.23 2 | guavaVersion = 16.0 3 | hamcrestVersion = 1.3 4 | httpComponentsVersion = 4.2 5 | jacocoVersion = 0.7.4.201502262128 6 | powermockVersion = 1.5.1 7 | saxonVersion = 9.7.0-1 8 | 9 | findbugsXmx=1024M 10 | findbugsMaxPermSize=512M 11 | -------------------------------------------------------------------------------- /jacoco.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'jacoco' 2 | 3 | ext { 4 | limits = [ 5 | 'instruction': 80, 6 | 'branch' : 70, 7 | 'line' : 80, 8 | 'complexity' : 75, 9 | 'method' : 85, 10 | 'class' : 90 // TODO: 100% 11 | ] 12 | } 13 | 14 | jacocoTestReport { 15 | dependsOn 'test' 16 | reports { 17 | xml.enabled true 18 | } 19 | doLast { 20 | def report = file("${jacoco.reportsDir}/test/jacocoTestReport.xml") 21 | def parser = new XmlParser() 22 | parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 23 | parser.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false) 24 | def results = parser.parse(report) 25 | def percentage = { 26 | def covered = it.'@covered' as Double 27 | def missed = it.'@missed' as Double 28 | ((covered / (covered + missed)) * 100).round(2) 29 | } 30 | def counters = results.counter 31 | def metrics = [:] 32 | metrics << [ 33 | 'instruction': percentage(counters.find { it.'@type'.equals('INSTRUCTION') }), 34 | 'branch' : percentage(counters.find { it.'@type'.equals('BRANCH') }), 35 | 'line' : percentage(counters.find { it.'@type'.equals('LINE') }), 36 | 'complexity' : percentage(counters.find { it.'@type'.equals('COMPLEXITY') }), 37 | 'method' : percentage(counters.find { it.'@type'.equals('METHOD') }), 38 | 'class' : percentage(counters.find { it.'@type'.equals('CLASS') }) 39 | ] 40 | def failures = [] 41 | metrics.each { 42 | def limit = limits[it.key] 43 | if (it.value < limit) { 44 | failures.add("- ${it.key} coverage rate is: ${it.value}%, minimum is ${limit}%") 45 | } 46 | } 47 | if (failures) { 48 | logger.error("------------------ Code Coverage Failed -----------------------") 49 | failures.each { 50 | logger.error(it) 51 | } 52 | logger.error("---------------------------------------------------------------") 53 | throw new GradleException("Code coverage failed") 54 | } else{ 55 | logger.debug("Passed Code Coverage Checks") 56 | } 57 | } 58 | } 59 | 60 | check.dependsOn jacocoTestReport 61 | -------------------------------------------------------------------------------- /java/core/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: RADL core 4 | Bundle-SymbolicName: radl-core 5 | Bundle-Version: 0.9.10 6 | Bundle-Vendor: RADL 7 | Export-Package: radl.core.cli, 8 | radl.core.code, 9 | radl.core.documentation, 10 | radl.core.extraction, 11 | radl.core.generation, 12 | radl.core.scm, 13 | radl.core.validation 14 | Bundle-RequiredExecutionEnvironment: JavaSE-1.7 15 | Import-Package: com.google.common.escape, 16 | com.mxgraph.layout.hierarchical, 17 | com.mxgraph.util, 18 | com.mxgraph.view, 19 | com.thaiopensource.relaxng.jaxp, 20 | javax.annotation.processing, 21 | javax.imageio, 22 | javax.lang.model, 23 | javax.lang.model.element, 24 | javax.lang.model.type, 25 | javax.lang.model.util, 26 | javax.tools, 27 | javax.xml.parsers, 28 | javax.xml.transform, 29 | javax.xml.transform.dom, 30 | javax.xml.transform.sax, 31 | javax.xml.transform.stream, 32 | javax.xml.validation, 33 | net.sf.saxon, 34 | org.apache.commons.lang, 35 | org.jaxen, 36 | org.jaxen.dom, 37 | org.w3c.dom, 38 | org.w3c.dom.ls, 39 | org.xml.sax 40 | Bundle-Category: 41 | -------------------------------------------------------------------------------- /java/core/gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) EMC Corporation. All rights reserved. 3 | # 4 | 5 | version = 2.0.2 6 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/common/StringUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.common; 5 | 6 | 7 | /** 8 | * Utility methods for working with quoted strings. 9 | */ 10 | public final class StringUtil { 11 | 12 | private StringUtil() { 13 | // Utility class 14 | } 15 | 16 | public static boolean isQuoted(String value) { 17 | return value.matches("\\\"[^\\\"]+\\\""); 18 | } 19 | 20 | public static String stripQuotes(String value) { 21 | if (isQuoted(value)) { 22 | return value.substring(1, value.length() - 1); 23 | } 24 | return value; 25 | } 26 | 27 | public static String initCap(String text) { 28 | return Character.toUpperCase(text.charAt(0)) + text.substring(1); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/common/io/ByteArrayInputOutputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.common.io; 5 | 6 | import java.io.ByteArrayInputStream; 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.InputStream; 9 | 10 | 11 | /** 12 | * Combination of {@linkplain ByteArrayInputStream} and {@linkplain ByteArrayOutputStream} that share a byte buffer to 13 | * avoid copying. 14 | */ 15 | public class ByteArrayInputOutputStream extends ByteArrayOutputStream { 16 | 17 | public InputStream getInputStream() { 18 | return new ByteArrayInputStream(buf, 0, count); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/common/io/IO.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.common.io; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.File; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.io.InputStreamReader; 11 | import java.io.OutputStream; 12 | import java.util.ArrayList; 13 | import java.util.Collection; 14 | 15 | 16 | /** 17 | * Utility functions for working with files and streams. 18 | */ 19 | public final class IO { 20 | 21 | public static final int BUFFER_SIZE = 4096; 22 | 23 | private IO() { 24 | // Utility class 25 | } 26 | 27 | public static void delete(File root) { 28 | if (root == null || !root.exists()) { 29 | return; 30 | } 31 | if (root.isDirectory()) { 32 | for (File file : root.listFiles()) { 33 | delete(file); 34 | } 35 | } 36 | if (!root.delete()) { 37 | root.deleteOnExit(); 38 | } 39 | } 40 | 41 | public static void copy(InputStream source, OutputStream destination) throws IOException { 42 | byte[] buffer = new byte[BUFFER_SIZE]; 43 | int numRead = source.read(buffer); 44 | while (numRead > 0) { 45 | destination.write(buffer, 0, numRead); 46 | numRead = source.read(buffer); 47 | } 48 | source.close(); 49 | destination.close(); 50 | } 51 | 52 | public static Iterable linesOf(InputStream stream) { 53 | Collection result = new ArrayList<>(); 54 | try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF8"))) { 55 | String line = reader.readLine(); 56 | while (line != null) { 57 | result.add(line); 58 | line = reader.readLine(); 59 | } 60 | } catch (IOException e) { 61 | throw new RuntimeException(e); 62 | } 63 | return result; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/common/io/StringStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.common.io; 5 | 6 | import java.io.ByteArrayInputStream; 7 | import java.io.InputStream; 8 | import java.io.UnsupportedEncodingException; 9 | 10 | 11 | /** 12 | * Use a {@linkplain String} as an {@linkplain InputStream}. 13 | */ 14 | public class StringStream extends ByteArrayInputStream { 15 | 16 | public StringStream(String text) { 17 | this(text, "UTF8"); 18 | } 19 | 20 | public StringStream(String text, String charSetName) { 21 | super(getBytes(text, charSetName)); 22 | } 23 | 24 | private static byte[] getBytes(String text, String charSetName) { 25 | try { 26 | return text.getBytes(charSetName); 27 | } catch (UnsupportedEncodingException e) { 28 | throw new RuntimeException(e); 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/common/xml/ElementProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.common.xml; 5 | 6 | import org.w3c.dom.Element; 7 | 8 | 9 | /** 10 | * Process an XML DOM {@linkplain Element}. 11 | */ 12 | public interface ElementProcessor { 13 | 14 | void process(Element element) throws Exception; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/common/xml/XmlException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.common.xml; 5 | 6 | 7 | public class XmlException extends Exception { 8 | 9 | public XmlException(Exception cause) { 10 | super(cause); 11 | } 12 | 13 | @Override 14 | public String getMessage() { 15 | return getCause().getMessage(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/Log.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core; 5 | 6 | import java.io.PrintStream; 7 | 8 | 9 | /** 10 | * Extremely simple logging. 11 | */ 12 | public final class Log { 13 | 14 | private static boolean active = true; 15 | 16 | private Log() { 17 | // Utility class 18 | } 19 | 20 | public static void activate() { 21 | active = true; 22 | } 23 | 24 | public static void deactivate() { 25 | active = false; 26 | } 27 | 28 | public static void info(Object message) { 29 | log(System.out, message); 30 | } 31 | 32 | private static void log(PrintStream out, Object message) { 33 | if (active) { 34 | out.println(message); // NOPMD SystemPrintln 35 | } 36 | } 37 | 38 | public static void error(Object message) { 39 | log(System.err, message); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/Radl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core; 5 | 6 | 7 | public interface Radl { 8 | 9 | /** 10 | * The XML namespace URI for the core RADL schema. 11 | */ 12 | String NAMESPACE_URI = "urn:radl:service"; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/cli/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.cli; 5 | 6 | 7 | /** 8 | * An application with a command-line interface. 9 | */ 10 | public interface Application { 11 | 12 | /** 13 | * Run the application with the provided arguments. 14 | * @param arguments The command-line arguments to the application 15 | * @return The program exit code. Use zero for success and non-zero for failure 16 | */ 17 | int run(Arguments arguments); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/cli/Cli.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.cli; 5 | 6 | import radl.core.Log; 7 | 8 | 9 | /** 10 | * Support for command-line interfaces. 11 | */ 12 | public final class Cli { 13 | 14 | private Cli() { 15 | // Utility class 16 | } 17 | 18 | /** 19 | * Run a command-line application with the provided arguments. This method is typically called from a 20 | * main() method. All exceptions are caught and printed on stderr. In case of an exception, the 21 | * application exists with a negative exit code. 22 | * @param applicationClass The type of application to run 23 | * @param arguments The arguments to run the application with 24 | */ 25 | public static void run(Class applicationClass, String[] arguments) { 26 | int exitCode; 27 | try { 28 | exitCode = applicationClass.newInstance().run(new Arguments(arguments)); 29 | } catch (Exception e) { 30 | Log.error(e.getMessage()); 31 | exitCode = -1; 32 | } 33 | System.exit(exitCode); // NOPMD DoNotCallSystemExit 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/GeneratedSourceFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code; 5 | 6 | 7 | /** 8 | * A source file that was generated by some process rather than hand-coded. Two generated source files are considered 9 | * equal if they are stored at the same path and contain the same code. 10 | */ 11 | public class GeneratedSourceFile extends SourceFile { 12 | 13 | public GeneratedSourceFile(String path) { 14 | this(path, null); 15 | } 16 | 17 | public GeneratedSourceFile(String path, Code code) { 18 | super(path, code); 19 | } 20 | 21 | @Override 22 | public int hashCode() { 23 | final int prime = 31; 24 | int result = super.hashCode(); 25 | result = prime * result + code().hashCode(); 26 | return result; 27 | } 28 | 29 | @Override 30 | public boolean equals(Object obj) { 31 | if (!super.equals(obj)) { 32 | return false; 33 | } 34 | return code().equals(((SourceFile)obj).code()); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/GenericSyntax.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | 9 | 10 | /** 11 | * Default code syntax. Strings are surrounded by either single or double quotes. 12 | */ 13 | public class GenericSyntax implements Syntax { 14 | 15 | private static final Collection QUOTES = Arrays.asList('"', '\''); 16 | 17 | @Override 18 | public boolean isStringStart(char c) { 19 | return QUOTES.contains(c); 20 | } 21 | 22 | @Override 23 | public boolean canSplitCommentOn(char c) { 24 | return !Character.isLetter(c) && c != '\''; 25 | } 26 | 27 | @Override 28 | public boolean canSplitOn(char c, boolean commentIsEmpty) { 29 | return Character.isWhitespace(c) && commentIsEmpty; 30 | } 31 | 32 | @Override 33 | public boolean startsMultiLineComment(String line) { 34 | return false; 35 | } 36 | 37 | @Override 38 | public boolean endsMultiLineComment(String line) { 39 | return false; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/Syntax.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code; 5 | 6 | 7 | /** 8 | * Syntax for code in some language. 9 | */ 10 | public interface Syntax { 11 | 12 | boolean isStringStart(char c); 13 | 14 | boolean canSplitCommentOn(char c); 15 | 16 | boolean canSplitOn(char c, boolean commentIsEmpty); 17 | 18 | boolean startsMultiLineComment(String line); 19 | 20 | boolean endsMultiLineComment(String line); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/common/Constant.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code.common; 5 | 6 | 7 | public class Constant { 8 | 9 | private final String name; 10 | private final String comments; 11 | private final String value; 12 | 13 | public Constant(String name, String value, String comments) { 14 | this.name = name; 15 | this.value = value; 16 | this.comments = comments; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public String getValue() { 24 | return value; 25 | } 26 | 27 | public String[] getComments() { 28 | return comments == null ? new String[0] : comments.split("\n"); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/common/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code.common; 5 | 6 | import java.util.Locale; 7 | import java.util.Map; 8 | import java.util.TreeMap; 9 | 10 | import radl.java.code.Java; 11 | 12 | 13 | public class Constants { 14 | 15 | private static final char WORD_SEPARATOR = '_'; 16 | 17 | private final Map itemsByValue = new TreeMap<>(); 18 | private final String prefix; 19 | private final String description; 20 | 21 | public Constants(String prefix, String description) { 22 | this.prefix = prefix.isEmpty() ? "" : prefix + WORD_SEPARATOR; 23 | this.description = description; 24 | } 25 | 26 | public String getDescription() { 27 | return description; 28 | } 29 | 30 | public Constant add(String baseName, String value, String comments) { 31 | Constant result = new Constant(constantName(baseName), value, comments); 32 | add(result); 33 | return result; 34 | } 35 | 36 | private String constantName(String name) { 37 | return prefix + Java.toName(name.replace('/', WORD_SEPARATOR).toUpperCase(Locale.getDefault())); 38 | } 39 | 40 | private void add(Constant constant) { 41 | itemsByValue.put(constant.getValue(), constant); 42 | } 43 | 44 | public Constant byValue(String value) { 45 | return itemsByValue.get(value); 46 | } 47 | 48 | public Iterable all() { 49 | return itemsByValue.values(); 50 | } 51 | 52 | public Constants filter(String baseName, boolean include) { 53 | Constants result = new Constants(prefix, description); 54 | String name = constantName(baseName); 55 | for (Constant candidate : all()) { 56 | if (include == candidate.getName().equals(name)) { 57 | result.add(candidate); 58 | } 59 | } 60 | return result; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/radl/MediaType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code.radl; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | 9 | 10 | public class MediaType { 11 | 12 | private static final Collection SEMANTIC_MEDIA_TYPES = Arrays.asList( 13 | "application/ld+json"); 14 | private static final Collection HYPER_MEDIA_TYPES = Arrays.asList( 15 | "application/hal+json", 16 | "application/vnd.collection+json", 17 | "application/vnd.mason+json", 18 | "application/vnd.siren+json", 19 | "application/vnd.uber+json", 20 | "application/vnd.uber+xml", 21 | "application/atom+xml"); 22 | 23 | private final String name; 24 | 25 | public MediaType(String name) { 26 | this.name = name; 27 | } 28 | 29 | public String name() { 30 | return name; 31 | } 32 | 33 | public boolean isHyperMediaType() { 34 | return SEMANTIC_MEDIA_TYPES.contains(name) || HYPER_MEDIA_TYPES.contains(name); 35 | } 36 | 37 | public boolean isSemanticMediaType() { 38 | return SEMANTIC_MEDIA_TYPES.contains(name); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/radl/Property.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code.radl; 5 | 6 | 7 | public interface Property { 8 | 9 | String uri(); 10 | 11 | String type(); 12 | 13 | boolean repeats(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/radl/PropertyGroup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code.radl; 5 | 6 | import org.w3c.dom.Element; 7 | 8 | import radl.core.code.xml.NestedXml; 9 | 10 | 11 | public class PropertyGroup extends PropertyGroups implements Property { 12 | 13 | public PropertyGroup(NestedXml xml) { 14 | super(xml); 15 | } 16 | 17 | public String name() { 18 | return attr("name"); 19 | } 20 | 21 | private String attr(String name) { 22 | return xml().attr(xml().asElement(), name); 23 | } 24 | 25 | public boolean hasSemantics() { 26 | if (hasUri()) { 27 | return true; 28 | } 29 | for (String name : names()) { 30 | if (item(name).hasSemantics()) { 31 | return true; 32 | } 33 | } 34 | return false; 35 | } 36 | 37 | public boolean hasUri() { 38 | return !uri().isEmpty(); 39 | } 40 | 41 | @Override 42 | public String uri() { 43 | return attr("uri"); 44 | } 45 | 46 | public String reference() { 47 | return attr("ref"); 48 | } 49 | 50 | public Iterable propertyNames() { 51 | return xml().elementsAttribute("name", "radl:*[local-name(.) = 'property' or local-name(.) = 'property-group']"); 52 | } 53 | 54 | public Property property(String name) { 55 | Element propertyElement = xml().one("radl:*[@name='" + name + "']", Element.class); 56 | if (propertyElement.getLocalName().equals("property-group")) { 57 | return item(name); 58 | } 59 | return new PropertyImpl(propertyElement, xml().namespaces()); 60 | } 61 | 62 | @Override 63 | public String type() { 64 | return attr("type"); 65 | } 66 | 67 | @Override 68 | public boolean repeats() { 69 | return Boolean.parseBoolean(attr("repeats")); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/radl/PropertyGroups.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code.radl; 5 | 6 | import radl.core.code.xml.NestedXml; 7 | 8 | public class PropertyGroups { 9 | 10 | private final NestedXml xml; 11 | 12 | public PropertyGroups(NestedXml xml) { 13 | this.xml = xml; 14 | } 15 | 16 | protected NestedXml xml() { 17 | return xml; 18 | } 19 | 20 | public Iterable names() { 21 | return xml.items(); 22 | } 23 | 24 | public PropertyGroup item(String name) { 25 | return new PropertyGroup(xml.item(name)); 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return xml.toString(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/radl/PropertyImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code.radl; 5 | 6 | import java.util.Map; 7 | 8 | import org.w3c.dom.Element; 9 | 10 | import radl.core.code.xml.XmlCode; 11 | 12 | 13 | public class PropertyImpl extends XmlCode implements Property { 14 | 15 | public PropertyImpl(Element propertyElement, Map namespaces) { 16 | super(propertyElement, namespaces); 17 | } 18 | 19 | @Override 20 | public String uri() { 21 | return attr("uri"); 22 | } 23 | 24 | private String attr(String name) { 25 | return attr(asElement(), name); 26 | } 27 | 28 | @Override 29 | public String type() { 30 | return attr("type"); 31 | } 32 | 33 | @Override 34 | public boolean repeats() { 35 | return Boolean.parseBoolean(attr("repeats")); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/xml/NestedXml.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code.xml; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collection; 8 | import java.util.Map; 9 | 10 | import org.w3c.dom.Element; 11 | 12 | 13 | public class NestedXml extends XmlCode { 14 | 15 | private final String elementName; 16 | private final String idAttributeName; 17 | 18 | public NestedXml(Element root, String elementName, String idAttributeName, Map namespaces) { 19 | super(root, namespaces); 20 | this.elementName = elementName; 21 | this.idAttributeName = idAttributeName; 22 | } 23 | 24 | public Iterable items() { 25 | Collection result = new ArrayList<>(); 26 | for (Element element : multiple(elementName, Element.class)) { 27 | result.add(attr(element, idAttributeName)); 28 | } 29 | return result; 30 | } 31 | 32 | public NestedXml item(String name) { 33 | Element root = one(String.format("%s[@%s='%s']", elementName, idAttributeName, name), Element.class); 34 | return new NestedXml(root, elementName, idAttributeName, namespaces()); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/xml/XmlIndent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code.xml; 5 | 6 | 7 | /** 8 | * Indentation for XML files. 9 | */ 10 | public class XmlIndent /* TODO: Java 7 implements AutoCloseable */ { 11 | 12 | private static final int INDENTATION = 2; 13 | 14 | private final XmlCode xml; 15 | 16 | public XmlIndent(XmlCode xml) { 17 | this.xml = xml; 18 | xml.indent(INDENTATION); 19 | } 20 | 21 | // TODO: Java 7 @Override 22 | public void close() { 23 | xml.unindent(INDENTATION); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/code/xml/XmlSyntax.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.code.xml; 5 | 6 | import radl.core.code.GenericSyntax; 7 | 8 | /** 9 | * Syntax for XML code. 10 | */ 11 | public class XmlSyntax extends GenericSyntax { 12 | 13 | @Override 14 | public boolean canSplitOn(char c, boolean commentIsEmpty) { 15 | return super.canSplitOn(c, commentIsEmpty) && c != '>' && c != '/'; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/documentation/JGraphStateDiagram.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.documentation; 5 | 6 | import java.io.File; 7 | 8 | /* TODO: Not supported on Java 6 9 | import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; 10 | import com.mxgraph.util.mxCellRenderer; 11 | import com.mxgraph.util.mxConstants; 12 | import com.mxgraph.view.mxGraph; 13 | */ 14 | 15 | 16 | /** 17 | * State diagram built using the JGraph library. 18 | */ 19 | public class JGraphStateDiagram implements StateDiagram { 20 | 21 | /* 22 | private static final String VERTEX_STYLE 23 | = String.format("%s=%s", mxConstants.STYLE_SHAPE, mxConstants.SHAPE_ELLIPSE); 24 | private static final String START_VERTEX_STYLE = VERTEX_STYLE + ";fillColor=#FFDEAD;strokeColor=maroon"; 25 | private static final String EDGE_STYLE = String.format("%s=%s;%s=black", mxConstants.STYLE_ALIGN, 26 | mxConstants.ALIGN_LEFT, mxConstants.STYLE_FONTCOLOR); 27 | 28 | private final mxGraph graph; 29 | private final Map cells = new HashMap<>(); 30 | private final Object parent; 31 | 32 | public JGraphStateDiagram() { 33 | graph = new mxGraph(); 34 | parent = graph.getDefaultParent(); 35 | graph.getModel().beginUpdate(); 36 | } 37 | */ 38 | 39 | @Override 40 | public void setTitle(String title) { 41 | // Nothing to do 42 | } 43 | 44 | @Override 45 | public void addStartState(String name) { 46 | //doAddState(name, START_VERTEX_STYLE); 47 | } 48 | 49 | @Override 50 | public void addState(String name) { 51 | // doAddState(name, VERTEX_STYLE); 52 | } 53 | 54 | /* 55 | protected Object doAddState(String name, String style) { 56 | int count = graph.getModel().getChildCount(parent); 57 | return cells.put(name, graph.insertVertex(parent, null, name, count, count, name.length() * 10 + 10, 30, style)); 58 | } 59 | */ 60 | 61 | @Override 62 | public void addTransition(String from, String to, String name) { 63 | // graph.insertEdge(parent, null, name, cells.get(from), cells.get(to), EDGE_STYLE); 64 | } 65 | 66 | @Override 67 | public void toImage(File file) { 68 | /* 69 | new mxHierarchicalLayout(graph).execute(parent); 70 | graph.getModel().endUpdate(); 71 | RenderedImage image = mxCellRenderer.createBufferedImage(graph, null, 1, Color.WHITE, false, null); 72 | try { 73 | ImageIO.write(image, "png", file); 74 | } catch (IOException e) { 75 | throw new RuntimeException(e); 76 | } 77 | */ 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/documentation/StateDiagram.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.documentation; 5 | 6 | import java.io.File; 7 | 8 | 9 | /** 10 | * Diagram with states and transitions between them that can be saved to an image. 11 | */ 12 | public interface StateDiagram { 13 | 14 | void setTitle(String title); 15 | 16 | void addStartState(String name); 17 | 18 | void addState(String name); 19 | 20 | void addTransition(String from, String to, String name); 21 | 22 | void toImage(File image); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/enforce/Desired.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.enforce; 5 | 6 | import java.util.Collection; 7 | 8 | 9 | /** 10 | * The desired situation. A situation is identified by a number of objects of type T that are each 11 | * identified by an ID of type I. 12 | */ 13 | public interface Desired { 14 | 15 | /** 16 | * @return The IDs of all the desired objects 17 | */ 18 | Collection getIds(); 19 | 20 | /** 21 | * @param id The ID of a desired object. This must be an ID returned by {@linkplain #getIds()} 22 | * @return The desired object identified by the given ID 23 | */ 24 | T get(I id); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/enforce/Reality.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.enforce; 5 | 6 | 7 | /** 8 | * The real situation. A situation is identified by a number of objects of type T that are each 9 | * identified by an ID of type I. 10 | */ 11 | public interface Reality extends Desired { 12 | 13 | /** 14 | * Add a desired object to reality. 15 | * @param id The ID of the desired object 16 | * @param object The desired object 17 | */ 18 | void add(I id, T object); 19 | 20 | /** 21 | * Remove an unwanted object from reality. 22 | * @param id The ID of the unwanted object 23 | */ 24 | void remove(I id); 25 | 26 | /** 27 | * Replace an object by a desired version of it. 28 | * @param id The ID of the object to update 29 | * @param oldObject The object as it currently exists in reality 30 | * @param newObject The object as it is desired 31 | */ 32 | void update(I id, T oldObject, T newObject); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/AddAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.extraction; 6 | 7 | import java.util.Collection; 8 | 9 | class AddAction implements UriTemplateAction { 10 | 11 | private final String value; 12 | 13 | public AddAction(String value) { 14 | this.value = value; 15 | } 16 | 17 | @Override 18 | public boolean isFinal() { 19 | return false; 20 | } 21 | 22 | @Override 23 | public void execute(Collection values) { 24 | values.add(value); 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/ExtractOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.extraction; 5 | 6 | 7 | /** 8 | * Options for extracting RADL from something else, like Java code. 9 | */ 10 | public interface ExtractOptions { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/IgnoreAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.extraction; 6 | 7 | import java.util.Collection; 8 | 9 | class IgnoreAction implements UriTemplateAction { 10 | 11 | @Override 12 | public boolean isFinal() { 13 | return true; 14 | } 15 | 16 | @Override 17 | public void execute(Collection values) { 18 | // Nothing to do 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/MergedMethods.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.extraction; 6 | 7 | import java.util.Collection; 8 | 9 | class MergedMethods { 10 | 11 | private final Collection resources; 12 | private final Collection methods; 13 | 14 | public MergedMethods(Collection resources, Collection methods) { 15 | this.resources = resources; 16 | this.methods = methods; 17 | } 18 | 19 | public Collection getResources() { 20 | return resources; 21 | } 22 | 23 | public Collection getMethods() { 24 | return methods; 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/RadlExtractor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.extraction; 5 | 6 | import java.io.File; 7 | 8 | import org.w3c.dom.Document; 9 | 10 | 11 | /** 12 | * Extracts a (partial) RADL file from a directory of source files. 13 | */ 14 | public interface RadlExtractor { 15 | 16 | Document extractFrom(String serviceName, File baseDir, ExtractOptions options); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/ReplaceAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.extraction; 6 | 7 | import java.util.Collection; 8 | 9 | class ReplaceAction implements UriTemplateAction { 10 | 11 | private final String oldValue; 12 | private final String newValue; 13 | 14 | public ReplaceAction(String oldValue, String newValue) { 15 | this.oldValue = oldValue; 16 | this.newValue = newValue; 17 | } 18 | 19 | @Override 20 | public boolean isFinal() { 21 | return false; 22 | } 23 | 24 | @Override 25 | public void execute(Collection values) { 26 | values.remove(oldValue); 27 | values.add(newValue); 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/ResourceModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.extraction; 5 | 6 | import java.util.Collection; 7 | import java.util.Properties; 8 | import java.util.Set; 9 | 10 | 11 | /** 12 | * A set of interlinked HTTP resources. 13 | */ 14 | public interface ResourceModel { 15 | 16 | void configure(Properties configuration); 17 | 18 | void addResource(String resourceName, String documentation); 19 | 20 | void addParentResource(String childResource, String parentResource); 21 | 22 | void addLocations(String resourceName, Collection lcoations); 23 | 24 | void setLocations(String resourceName, Collection locations); 25 | 26 | void addLocationVar(String resourceName, String varName, String documentation); 27 | 28 | Iterable getLocationVars(String resourceName); 29 | 30 | String getLocationVarDocumentation(String resourceName, String varName); 31 | 32 | void addMethod(String resourceName, String methodName, String consumes, String produces, String documentation); 33 | 34 | Iterable mediaTypes(); 35 | 36 | Set resourcesWithMethods(); 37 | 38 | String getFriendlyName(String resourceName); 39 | 40 | String getUri(String resourceName); 41 | 42 | Collection methodsOf(String resourceName); 43 | 44 | void build(); 45 | 46 | String getDocumentation(String resourceName); 47 | 48 | void markComplete(); 49 | 50 | boolean isCompleted(); 51 | 52 | } 53 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/ResourceModelHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.extraction; 5 | 6 | /** 7 | * Singleton pattern for {@linkplain ResourceModel}. 8 | */ 9 | public enum ResourceModelHolder { 10 | 11 | INSTANCE; 12 | 13 | private ResourceModel resourceModel= new ResourceModelImpl(); 14 | 15 | public ResourceModel get() { 16 | return this.resourceModel; 17 | } 18 | 19 | public void set(ResourceModel given) { 20 | this.resourceModel = given; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/ResourceModelMerger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.extraction; 5 | 6 | import org.w3c.dom.Document; 7 | 8 | 9 | /** 10 | * Merge a resource model into an existing RADL document. 11 | */ 12 | public interface ResourceModelMerger { 13 | 14 | void setService(String serviceName); 15 | 16 | Document toRadl(ResourceModel resourceModel); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/ResourceModelSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | 5 | package radl.core.extraction; 6 | 7 | import java.io.File; 8 | import java.io.FileInputStream; 9 | import java.io.FileOutputStream; 10 | import java.io.InputStream; 11 | import java.io.ObjectInputStream; 12 | import java.io.ObjectOutputStream; 13 | import java.io.OutputStream; 14 | 15 | import radl.core.Log; 16 | 17 | 18 | public final class ResourceModelSerializer { 19 | 20 | private ResourceModelSerializer() { 21 | } 22 | 23 | public static void serializeModelToFile(ResourceModel resourceModel, File file) { 24 | Log.info("Saving resource model to file: " + file); 25 | if (file == null) { 26 | return; 27 | } 28 | try (OutputStream stream = new FileOutputStream(file)) { 29 | try (ObjectOutputStream output = new ObjectOutputStream(stream)) { 30 | output.writeObject(resourceModel); 31 | } 32 | } catch (Exception e) { 33 | throw new RuntimeException("Failed to write resource model to file.", e); 34 | } 35 | } 36 | 37 | public static ResourceModel deserializeModelFromFile(File file) { 38 | Log.info("Loading resource model from file: " + file); 39 | try (InputStream stream = new FileInputStream(file)) { 40 | try (ObjectInputStream input = new ObjectInputStream(stream)) { 41 | return (ResourceModel)input.readObject(); 42 | } 43 | } catch (Exception e) { 44 | throw new RuntimeException("Failed to load resource model from file", e); 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/UriTemplateAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.extraction; 6 | 7 | import java.util.Collection; 8 | 9 | interface UriTemplateAction { 10 | 11 | boolean isFinal(); 12 | 13 | void execute(Collection values); 14 | 15 | } -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/UriTemplateComparison.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.extraction; 6 | 7 | enum UriTemplateComparison { EQUAL, SPECIALIZATION, GENERALIZATION, DIFFERENT } -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/extraction/UriTemplateVar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.extraction; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * A variable in a URI template, as defined by RFC 6570. 10 | */ 11 | public class UriTemplateVar implements Serializable { 12 | 13 | private final String name; 14 | private final String documentation; 15 | 16 | public UriTemplateVar(String name, String documentation) { 17 | this.name = name; 18 | this.documentation = documentation; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public String getDocumentation() { 26 | return documentation; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/generation/CodeBaseGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.generation; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Generates code from a RADL document. 10 | */ 11 | public interface CodeBaseGenerator { 12 | 13 | /** 14 | * Generate a code base. 15 | * @param source The input modules from which to generate code 16 | * @param destination The output modules in which code gets generated 17 | */ 18 | void generate(List source, Listdestination); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/generation/CodeBaseGeneratorImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.generation; 5 | 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | 11 | /** 12 | * Default implementation of {@linkplain CodeBaseGenerator} that defers to a suite of {@linkplain CodeGenerator}s. 13 | */ 14 | public class CodeBaseGeneratorImpl implements CodeBaseGenerator { 15 | 16 | private final CodeGenerator[] generators; 17 | private final String packagePrefix; 18 | private final String fileHeader; 19 | 20 | public CodeBaseGeneratorImpl(String packagePrefix, String fileHeader, CodeGenerator... generators) { 21 | this.packagePrefix = packagePrefix; 22 | this.fileHeader = fileHeader; 23 | this.generators = generators; 24 | } 25 | 26 | @Override 27 | public void generate(List source, List destination) { 28 | Map context = newContext(); 29 | context.put(CodeGenerator.OUTPUT_MODULES, destination); 30 | for (CodeGenerator generator : generators) { 31 | moduleFor(destination, generator).addAll(generator.generateFrom(source, context)); 32 | } 33 | } 34 | 35 | protected Map newContext() { 36 | Map result = new HashMap<>(); 37 | result.put(CodeGenerator.PACKAGE_PREFIX, packagePrefix); 38 | result.put(CodeGenerator.FILE_HEADER, fileHeader); 39 | return result; 40 | } 41 | 42 | /** 43 | * Determine what module should contain generated code. 44 | * @param modules The available output modules 45 | * @param generator The generator 46 | * @return The module to store the generated code into 47 | */ 48 | protected Module moduleFor(List modules, CodeGenerator generator) { 49 | return modules.get(0); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/generation/CodeGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.generation; 5 | 6 | import java.util.Collection; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import radl.core.code.Code; 11 | 12 | 13 | public interface CodeGenerator { 14 | 15 | String FILE_HEADER = "file.header"; 16 | String PACKAGE_PREFIX = "package.prefix"; 17 | String OUTPUT_MODULES = "modules.output"; 18 | 19 | /** 20 | * Generate code from input code. 21 | * @param input The input modules from which to generate code 22 | * @param context Context that is shared between code generators 23 | * @return The generated code 24 | */ 25 | Collection generateFrom(List input, Map context); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/generation/DesiredSourceFiles.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.generation; 5 | 6 | import java.io.File; 7 | import java.util.Collection; 8 | import java.util.Collections; 9 | import java.util.Map; 10 | import java.util.TreeMap; 11 | 12 | import org.w3c.dom.Document; 13 | 14 | import radl.core.code.SourceFile; 15 | import radl.core.enforce.Desired; 16 | 17 | 18 | /** 19 | * Describes the source files that would implement a RADL document. 20 | */ 21 | public class DesiredSourceFiles implements Desired { 22 | 23 | private final Document radl; 24 | private final SourceFilesGenerator generator; 25 | private final File baseDir; 26 | private Map sourceFiles; 27 | 28 | /** 29 | * @param radl The RESTful API description that represents the desired state 30 | * @param generator A generator that can generate source files from a RESTful API description 31 | * @param baseDir Directory under which to generate source files 32 | */ 33 | public DesiredSourceFiles(Document radl, SourceFilesGenerator generator, File baseDir) { 34 | this.radl = radl; 35 | this.generator = generator; 36 | this.baseDir = baseDir; 37 | } 38 | 39 | @Override 40 | public Collection getIds() { 41 | return Collections.unmodifiableCollection(sourceFiles().keySet()); 42 | } 43 | 44 | private Map sourceFiles() { 45 | if (sourceFiles == null) { 46 | sourceFiles = new TreeMap<>(); 47 | for (SourceFile sourceFile : generator.generateFrom(radl, baseDir)) { 48 | sourceFiles.put(sourceFile.path(), sourceFile); 49 | } 50 | } 51 | return sourceFiles; 52 | } 53 | 54 | @Override 55 | public SourceFile get(String id) { 56 | return sourceFiles().get(id); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/generation/Module.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.generation; 5 | 6 | import java.util.ArrayList; 7 | 8 | import radl.core.code.Code; 9 | 10 | 11 | public class Module extends ArrayList { 12 | 13 | public Module(Code... codes) { 14 | for (Code code : codes) { 15 | add(code); 16 | } 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/generation/SourceFilesGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.generation; 5 | 6 | import java.io.File; 7 | 8 | import org.w3c.dom.Document; 9 | 10 | import radl.core.code.SourceFile; 11 | 12 | 13 | /** 14 | * Generates source files from a RADL document. 15 | */ 16 | public interface SourceFilesGenerator { 17 | 18 | Iterable generateFrom(Document radl, File baseDir); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/scm/DefaultSourceCodeManagementSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.scm; 5 | 6 | import java.io.File; 7 | 8 | 9 | /** 10 | * Default implementation of {@linkplain SourceCodeManagementSystem}. 11 | */ 12 | public class DefaultSourceCodeManagementSystem implements SourceCodeManagementSystem { 13 | 14 | @Override 15 | public String getId() { 16 | return "default"; 17 | } 18 | 19 | @Override 20 | public void prepareForUpdate(File file) { 21 | // Nothing to do 22 | } 23 | 24 | @Override 25 | public void prepareForDelete(File file) { 26 | // Nothing to do 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/scm/OperatingSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.scm; 5 | 6 | /** 7 | * Interface to the operating system. 8 | */ 9 | public interface OperatingSystem { 10 | 11 | void run(String command); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/scm/OperatingSystemImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.scm; 5 | 6 | 7 | public class OperatingSystemImpl implements OperatingSystem { 8 | 9 | @Override 10 | public void run(String command) { 11 | try { 12 | Process process = Runtime.getRuntime().exec(command); 13 | int exitCode = process.waitFor(); 14 | if (exitCode != 0) { 15 | throw new RuntimeException("Command " + command + " exited with value " + exitCode); 16 | } 17 | } catch (Exception e) { 18 | throw new RuntimeException(e); 19 | } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/scm/Perforce.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.scm; 5 | 6 | import java.io.File; 7 | 8 | 9 | /** 10 | * The Perforce {@linkplain SourceCodeManagementSystem}. 11 | */ 12 | public class Perforce implements SourceCodeManagementSystem { 13 | 14 | private final OperatingSystem operatingSystem; 15 | 16 | public Perforce() { 17 | this(new OperatingSystemImpl()); 18 | } 19 | 20 | public Perforce(OperatingSystem operatingSystem) { 21 | this.operatingSystem = operatingSystem; 22 | } 23 | 24 | @Override 25 | public String getId() { 26 | return "p4"; 27 | } 28 | 29 | @Override 30 | public void prepareForUpdate(File file) { 31 | runPerforceCommandIfNeeded("edit", file); 32 | } 33 | 34 | private void runPerforceCommandIfNeeded(String command, File file) { 35 | if (file.canWrite()) { 36 | return; 37 | } 38 | operatingSystem.run(String.format("p4 %s %s", command, file.getAbsolutePath())); 39 | } 40 | 41 | @Override 42 | public void prepareForDelete(File file) { 43 | runPerforceCommandIfNeeded("delete", file); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/scm/ScmFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.scm; 5 | 6 | import java.util.Iterator; 7 | import java.util.ServiceLoader; 8 | 9 | 10 | /** 11 | * Factory for creating {@linkplain SourceCodeManagementSystem} instances. 12 | */ 13 | public final class ScmFactory { 14 | 15 | private ScmFactory() { 16 | // Utility class 17 | } 18 | 19 | public static SourceCodeManagementSystem newInstance(String id) { 20 | ServiceLoader serviceLoader = ServiceLoader.load(SourceCodeManagementSystem.class); 21 | Iterator services = serviceLoader.iterator(); 22 | while (services.hasNext()) { 23 | SourceCodeManagementSystem scm = services.next(); 24 | if (scm.getId().equals(id)) { 25 | return scm; 26 | } 27 | } 28 | throw new IllegalArgumentException("Unknown SCM: " + id); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/scm/SourceCodeManagementSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.scm; 5 | 6 | import java.io.File; 7 | 8 | 9 | /** 10 | * Facade to source code management systems. 11 | */ 12 | public interface SourceCodeManagementSystem { 13 | 14 | /** 15 | * @return The ID of this type of source code management system. 16 | */ 17 | String getId(); 18 | 19 | /** 20 | * Do whatever is needed to update a given file. 21 | * @param file The file that is about to be updated 22 | */ 23 | void prepareForUpdate(File file); 24 | 25 | /** 26 | * Do whatever is needed to delete a given file. 27 | * @param file The file that is about to be deleted 28 | */ 29 | void prepareForDelete(File file); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/validation/CheckStyleIssueReporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.validation; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.io.PrintWriter; 9 | import java.util.Locale; 10 | 11 | import radl.common.xml.DocumentBuilder; 12 | import radl.common.xml.Xml; 13 | 14 | 15 | /** 16 | * Report validation issues in CheckStyle format, for easy integration into Continuous Integration builds. 17 | */ 18 | public class CheckStyleIssueReporter implements IssueReporter { 19 | 20 | public static final String ID = "checkstyle"; 21 | 22 | private final DocumentBuilder output = DocumentBuilder.newDocument() 23 | .element("checkstyle") 24 | .attribute("version", "5.6"); 25 | private String currentFileName; 26 | private String outputFileName; 27 | 28 | @Override 29 | public void setReportFileName(String reportFileName) { 30 | this.outputFileName = reportFileName; 31 | } 32 | 33 | @Override 34 | public void start() { 35 | currentFileName = null; 36 | } 37 | 38 | @Override 39 | public void file(String fileName) { 40 | if (currentFileName != null) { 41 | output.end(); 42 | } 43 | currentFileName = fileName; 44 | output.element("file") 45 | .attribute("name", fileName); 46 | } 47 | 48 | @Override 49 | public void issue(Issue issue) { 50 | output.element("error") 51 | .attribute("line", Integer.toString(issue.getLine())) 52 | .attribute("column", Integer.toString(issue.getColumn())) 53 | .attribute("source", issue.getSource()) 54 | .attribute("severity", issue.getLevel().toString().toLowerCase(Locale.getDefault())) 55 | .attribute("message", encodeXml(issue.getMessage())) 56 | .end(); 57 | } 58 | 59 | private String encodeXml(String value) { 60 | return value.replace("&", "&").replace("\"", """).replace("'", "'").replace("<", "<") 61 | .replace(">", ">"); 62 | } 63 | 64 | @Override 65 | public void end() { 66 | File outputFile = new File(outputFileName); 67 | if (outputFile.getParentFile() != null) { 68 | outputFile.getParentFile().mkdirs(); 69 | } 70 | try (PrintWriter writer = new PrintWriter(outputFile, "UTF8")) { 71 | writer.print(Xml.toString(output.build())); 72 | } catch (IOException e) { 73 | throw new RuntimeException(e); 74 | } 75 | } 76 | 77 | @Override 78 | public String getId() { 79 | return ID; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/validation/CompositeValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.validation; 5 | 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.util.Collection; 9 | 10 | import radl.common.io.ByteArrayInputOutputStream; 11 | import radl.common.io.IO; 12 | import radl.core.validation.Issue.Level; 13 | 14 | 15 | /** 16 | * Composite pattern for RADL validators. 17 | */ 18 | public class CompositeValidator implements Validator { 19 | 20 | private final Validator[] validators; 21 | 22 | public CompositeValidator(Validator... validators) { 23 | this.validators = validators; 24 | } 25 | 26 | @Override 27 | public void validate(InputStream contents, Collection issues) { 28 | ByteArrayInputOutputStream reusableStream = new ByteArrayInputOutputStream(); 29 | try { 30 | IO.copy(contents, reusableStream); 31 | } catch (IOException e) { 32 | addExceptionIssue(e, issues); 33 | } 34 | for (Validator validator : validators) { 35 | try (InputStream stream = reusableStream.getInputStream()) { 36 | validator.validate(stream, issues); 37 | } catch (IOException e) { 38 | addExceptionIssue(e, issues); 39 | } 40 | } 41 | } 42 | 43 | private boolean addExceptionIssue(IOException exception, Collection issues) { 44 | return issues.add(new Issue(getClass(), Level.ERROR, 0, 0, exception.toString())); 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | StringBuilder result = new StringBuilder(); 50 | String prefix = ""; 51 | for (Validator validator : validators) { 52 | result.append(prefix).append(validator.toString()); 53 | prefix = ","; 54 | } 55 | return result.toString(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/validation/Issue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.validation; 5 | 6 | 7 | /** 8 | * An issue found in a RADL document. 9 | */ 10 | public final class Issue { 11 | 12 | public enum Level { INFO, WARNING, ERROR } 13 | 14 | private final String source; 15 | private final Level level; 16 | private final int line; 17 | private final int column; 18 | private final String message; 19 | 20 | public Issue(Class source, Level level, int line, int column, String message) { 21 | if (source == null || level == null || message == null) { 22 | throw new IllegalArgumentException("Source, level, and message are required"); 23 | } 24 | this.source = source.getSimpleName(); 25 | this.level = level; 26 | this.line = line; 27 | this.column = column; 28 | this.message = message; 29 | } 30 | 31 | public String getSource() { 32 | return source; 33 | } 34 | 35 | public Level getLevel() { 36 | return level; 37 | } 38 | 39 | public int getLine() { 40 | return line; 41 | } 42 | 43 | public int getColumn() { 44 | return column; 45 | } 46 | 47 | public String getMessage() { 48 | return message; 49 | } 50 | 51 | @Override 52 | public int hashCode() { 53 | final int prime = 31; 54 | int result = 1; 55 | result = prime * result + level.hashCode(); 56 | result = prime * result + line; 57 | result = prime * result + column; 58 | result = prime * result + message.hashCode(); 59 | return result; 60 | } 61 | 62 | @Override 63 | public boolean equals(Object obj) { 64 | if (this == obj) { 65 | return true; 66 | } 67 | if (!(obj instanceof Issue)) { 68 | return false; 69 | } 70 | Issue other = (Issue)obj; 71 | if (level != other.level) { 72 | return false; 73 | } 74 | if (line != other.line) { 75 | return false; 76 | } 77 | if (column != other.column) { 78 | return false; 79 | } 80 | if (!message.equals(other.message)) { 81 | return false; 82 | } 83 | return true; 84 | } 85 | 86 | @Override 87 | public String toString() { 88 | return String.format("%s [%d,%d]: %s", getLevel(), getLine(), getColumn(), getMessage()); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/validation/IssueReporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.validation; 5 | 6 | 7 | /** 8 | * Report validation issues. 9 | */ 10 | public interface IssueReporter { 11 | 12 | void setReportFileName(String reportFileName); 13 | 14 | /** 15 | * Start the report. 16 | */ 17 | void start(); 18 | 19 | /** 20 | * Start a new section of the report for the given file. 21 | * @param fileName The name of the RADL file for which issues will be reported 22 | */ 23 | void file(String fileName); 24 | 25 | /** 26 | * Report an issue. 27 | * @param issue The issue to report 28 | */ 29 | void issue(Issue issue); 30 | 31 | /** 32 | * End the report. 33 | */ 34 | void end(); 35 | 36 | /** 37 | * @return A unique identifier for the issue reporter 38 | */ 39 | String getId(); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/validation/IssueReporterFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.validation; 5 | 6 | import java.util.Iterator; 7 | import java.util.ServiceLoader; 8 | 9 | import radl.core.scm.SourceCodeManagementSystem; 10 | 11 | 12 | /** 13 | * Factory for creating {@linkplain SourceCodeManagementSystem} instances. 14 | */ 15 | public final class IssueReporterFactory { 16 | 17 | private IssueReporterFactory() { 18 | // Utility class 19 | } 20 | 21 | public static IssueReporter newInstance(String id) { 22 | ServiceLoader serviceLoader = ServiceLoader.load(IssueReporter.class); 23 | Iterator services = serviceLoader.iterator(); 24 | while (services.hasNext()) { 25 | IssueReporter reporter = services.next(); 26 | if (reporter.getId().equals(id)) { 27 | return reporter; 28 | } 29 | } 30 | throw new IllegalArgumentException("Unknown issue reporter: " + id); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/validation/Validator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.validation; 5 | 6 | import java.io.InputStream; 7 | import java.util.Collection; 8 | 9 | 10 | /** 11 | * Validate a RADL document. 12 | */ 13 | public interface Validator { 14 | 15 | /** 16 | * Add issues in a given RADL document to a given list of issues. 17 | * @param radl The RADL document 18 | * @param issues The list of issues to add to 19 | */ 20 | void validate(InputStream radl, Collection issues); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/xml/DocumentProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.xml; 5 | 6 | import org.w3c.dom.Document; 7 | 8 | 9 | /** 10 | * Process XML DOM {@linkplain Document}s. 11 | */ 12 | public interface DocumentProcessor { 13 | 14 | /** 15 | * Process a given XML DOM Document. May be called multiple times. 16 | * @param document The document to process 17 | */ 18 | void process(Document document); 19 | 20 | /** 21 | * @return The result of all the processing 22 | */ 23 | Document result(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/core/xml/RadlFileAssembler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | 5 | package radl.core.xml; 6 | 7 | import java.io.File; 8 | 9 | import radl.common.xml.Xml; 10 | import radl.common.xml.XmlException; 11 | import radl.core.Log; 12 | 13 | 14 | public final class RadlFileAssembler { 15 | 16 | public static final String XINCLUDE_FIXUP_BASE_URI = "http://apache.org/xml/features/xinclude/fixup-base-uris"; 17 | public static final String XINCLUDE_FIXUP_LANGUAGE = "http://apache.org/xml/features/xinclude/fixup-language"; 18 | 19 | private RadlFileAssembler() { 20 | // Utility class 21 | } 22 | 23 | public static File assemble(File radlFile, File targetDirectory) { 24 | File result = createOutputFile(radlFile, targetDirectory); 25 | try { 26 | // Merge potentially several RADL files into a single file using identity transformation and XInclude-aware parser 27 | Xml.identityTransform(Xml.parseWithIncludes(radlFile), result); 28 | } catch (XmlException e) { 29 | Log.error("Failed to assemble RADL file: " + e.getMessage()); 30 | return radlFile; 31 | } 32 | 33 | return result; 34 | } 35 | 36 | private static File createOutputFile(File radlFile, File targetDirectory) { 37 | String name = radlFile.getName(); 38 | File dir = targetDirectory; 39 | if (dir == null) { 40 | dir = radlFile.getParentFile(); 41 | } else { 42 | dir.mkdirs(); 43 | } 44 | return new File(dir, name + ".out"); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/code/ImportComparator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.code; 5 | 6 | import java.util.Comparator; 7 | 8 | 9 | public class ImportComparator implements Comparator { 10 | 11 | private static final String[] PRIORITY_PACKAGES = { "java", "javax", "org" }; 12 | 13 | @Override 14 | public int compare(String fqn1, String fqn2) { 15 | String pkg1 = packageOf(fqn1); 16 | String pkg2 = packageOf(fqn2); 17 | for (String pkg : PRIORITY_PACKAGES) { 18 | if (pkg.equals(pkg1)) { 19 | if (!pkg.equals(pkg2)) { 20 | return -1; 21 | } 22 | } else if (pkg.equals(pkg2)) { 23 | return 1; 24 | } 25 | } 26 | return fqn1.compareTo(fqn2); 27 | } 28 | 29 | private String packageOf(String fqn) { 30 | return fqn.split("\\.")[0]; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/code/JavaBeanProperty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.code; 5 | 6 | 7 | public class JavaBeanProperty { 8 | 9 | private final String name; 10 | private final String type; 11 | private final String annotation; 12 | 13 | public JavaBeanProperty(String name) { 14 | this(name, String.class.getSimpleName(), null); 15 | } 16 | 17 | public JavaBeanProperty(String name, String type, String annotation) { 18 | this.name = name; 19 | this.type = type; 20 | this.annotation = annotation; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public String getType() { 28 | return type; 29 | } 30 | 31 | public String getAnnotation() { 32 | return annotation; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/code/JavaSyntax.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.code; 5 | 6 | import radl.core.code.GenericSyntax; 7 | 8 | 9 | /** 10 | * Syntax for the Java programming language. 11 | */ 12 | public class JavaSyntax extends GenericSyntax { 13 | 14 | @Override 15 | public boolean canSplitOn(char c, boolean commentIsEmpty) { 16 | return !Character.isJavaIdentifierPart(c) && commentIsEmpty; 17 | } 18 | 19 | @Override 20 | public boolean startsMultiLineComment(String line) { 21 | return line.startsWith("/*"); 22 | } 23 | 24 | @Override 25 | public boolean endsMultiLineComment(String line) { 26 | return line.endsWith("*/"); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/extraction/Clock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction; 5 | 6 | 7 | /** 8 | * An instrument for measuring time. 9 | */ 10 | public interface Clock { 11 | 12 | /** 13 | * @return The current time, in milliseconds passed since midnight, January 1, 1970 UTC 14 | */ 15 | long now(); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/extraction/FromJavaExtractOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction; 5 | 6 | import java.io.File; 7 | import java.util.Collection; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | import radl.core.extraction.ExtractOptions; 12 | 13 | 14 | /** 15 | * Options for extracting RADL from Java code. Supports Spring and JAX-RS by default. 16 | */ 17 | public class FromJavaExtractOptions implements ExtractOptions { 18 | 19 | private final Collection classpath; 20 | private final String extraProcessors; 21 | private final String javaVersion; 22 | private final String annotationProcessorOptions; 23 | private final Collection extraSource; 24 | private final boolean serializeModel; 25 | 26 | public FromJavaExtractOptions(Collection extraSource, Collection classpath, String extraProcessors, 27 | String javaVersion, String annotationProcessorOptions, boolean serializeModel) { 28 | this.extraSource = extraSource; 29 | this.classpath = classpath; 30 | this.extraProcessors = extraProcessors; 31 | this.javaVersion = javaVersion; 32 | this.annotationProcessorOptions = annotationProcessorOptions; 33 | this.serializeModel = serializeModel; 34 | } 35 | 36 | public Collection getClasspath() { 37 | return classpath; 38 | } 39 | 40 | public String getAnnotationProcessors() { 41 | String result = JaxrsProcessor.class.getName() + ',' + SpringProcessor.class.getName(); 42 | return extraProcessors.isEmpty() ? result : result + ',' + extraProcessors; 43 | } 44 | 45 | public String getJavaVersion() { 46 | return javaVersion; 47 | } 48 | 49 | public Map getAnnotationProcessorOptions() { 50 | Map result = new HashMap<>(); 51 | if (annotationProcessorOptions == null) { 52 | return result; 53 | } 54 | for (String nameValue : annotationProcessorOptions.split(";")) { 55 | String[] nameAndValue = nameValue.split(":"); 56 | result.put(nameAndValue[0], nameAndValue[1]); 57 | } 58 | return result; 59 | } 60 | 61 | public Collection getExtraSource() { 62 | return extraSource; 63 | } 64 | 65 | public boolean isSerializeModel() { 66 | return serializeModel; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/extraction/Parameter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction; 5 | 6 | 7 | /** 8 | * A parameter to a method. 9 | */ 10 | public class Parameter { 11 | 12 | private final String name; 13 | private final String documentation; 14 | 15 | public Parameter(String name, String documentation) { 16 | this.name = name; 17 | this.documentation = documentation; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public String getDocumentation() { 25 | return documentation; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return name; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/extraction/ProcessorOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | 5 | package radl.java.extraction; 6 | 7 | 8 | public class ProcessorOptions { 9 | public static final String RESOURCE_MODEL_FILE = "resourceModelFile"; 10 | } 11 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/extraction/SystemClock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction; 5 | 6 | 7 | /** 8 | * Tell time based on the system clock. 9 | */ 10 | public class SystemClock implements Clock { 11 | 12 | @Override 13 | public long now() { 14 | return System.currentTimeMillis(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/extraction/Timer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction; 5 | 6 | 7 | /** 8 | * Time the duration of an operation. Create the Timer, perform the operation, then use the 9 | * Timer's {@linkplain #toString()} method to acquire a human readable representation of the duration. 10 | */ 11 | public class Timer { 12 | 13 | private final Clock clock; 14 | private final long start; 15 | 16 | public Timer() { 17 | this(new SystemClock()); 18 | } 19 | 20 | public Timer(Clock clock) { 21 | this.clock = clock; 22 | this.start = clock.now(); 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | long value = clock.now() - start; 28 | long remainder = 0; 29 | String separator = "."; 30 | String unit = "ms"; 31 | if (value >= 1000) { 32 | remainder = (value % 1000) / 100; 33 | value /= 1000; 34 | unit = "s"; 35 | if (value >= 60) { 36 | separator = ":"; 37 | remainder = value % 60; 38 | value /= 60; 39 | unit = "min"; 40 | } 41 | } 42 | StringBuilder result = new StringBuilder(); 43 | result.append(value); 44 | if (remainder > 0) { 45 | result.append(separator).append(remainder); 46 | } 47 | return result.append(' ').append(unit).toString(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/generation/spring/ActionsGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | */ 3 | package radl.java.generation.spring; 4 | 5 | import java.util.Arrays; 6 | import java.util.Collection; 7 | import java.util.Map; 8 | import java.util.TreeSet; 9 | 10 | import radl.core.code.Code; 11 | import radl.core.code.common.Constants; 12 | import radl.core.code.radl.RadlCode; 13 | import radl.java.code.JavaCode; 14 | 15 | public class ActionsGenerator extends FromRadlCodeGenerator { 16 | 17 | private final Constants transitionConstants = new Constants("", ""); 18 | 19 | @Override 20 | protected Collection generateFromRadl(RadlCode radl, Map context) { 21 | Code result = generateActions(radl, (Boolean)context.get(HAS_HYPERMEDIA)); 22 | context.put(TRANSITION_CONSTANTS, transitionConstants); 23 | return Arrays.asList(result); 24 | } 25 | 26 | private Code generateActions(RadlCode radl, boolean hasHyperMediaTypes) { 27 | JavaCode result = new JavaCode(); 28 | addPackage(IMPL_PACKAGE, result); 29 | result.add(""); 30 | result.add(""); 31 | result.add("public interface %s {", ACTIONS_TYPE); 32 | if (hasHyperMediaTypes) { 33 | addTransitionConstants(radl, result); 34 | result.add(""); 35 | } 36 | result.add("}"); 37 | return result; 38 | } 39 | 40 | private void addTransitionConstants(RadlCode radl, JavaCode code) { 41 | for (String transition : getTransitions(radl)) { 42 | transitionConstants.add(transition, transition, null); 43 | } 44 | addConstants(transitionConstants, code); 45 | } 46 | 47 | private Iterable getTransitions(RadlCode radl) { 48 | Collection result = new TreeSet<>(); 49 | for (String state : radl.stateNames()) { 50 | if (radl.isStartState(state)) { 51 | continue; 52 | } 53 | for (String transition : radl.stateTransitionNames(state)) { 54 | result.add(transition); 55 | } 56 | } 57 | return result; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/generation/spring/ApiGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.generation.spring; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | import java.util.Map; 9 | 10 | import radl.core.code.Code; 11 | import radl.core.code.common.Constants; 12 | import radl.core.code.radl.MediaType; 13 | import radl.core.code.radl.RadlCode; 14 | import radl.java.code.JavaCode; 15 | 16 | 17 | public class ApiGenerator extends FromRadlCodeGenerator { 18 | 19 | private Constants errorConstants; 20 | private Constants uriConstants; 21 | private Constants linkRelationConstants; 22 | private Constants mediaTypeConstants; 23 | private MediaType defaultMediaType; 24 | 25 | @Override 26 | protected Collection generateFromRadl(RadlCode radl, Map context) { 27 | errorConstants = (Constants)context.get(FromRadlCodeGenerator.ERROR_CONSTANTS); 28 | uriConstants = (Constants)context.get(FromRadlCodeGenerator.URI_CONSTANTS); 29 | linkRelationConstants = (Constants)context.get(FromRadlCodeGenerator.LINK_RELATION_CONSTANTS); 30 | mediaTypeConstants = (Constants)context.get(FromRadlCodeGenerator.MEDIA_TYPE_CONSTANTS); 31 | defaultMediaType = (MediaType)context.get(FromRadlCodeGenerationInitializer.DEFAULT_MEDIA_TYPE); 32 | return Arrays.asList(generateApi()); 33 | } 34 | 35 | private Code generateApi() { 36 | JavaCode result = new JavaCode(); 37 | addPackage(API_PACKAGE, result); 38 | result.add(""); 39 | result.add(""); 40 | result.add("public interface %s {", API_TYPE); 41 | addConstants(uriConstants.filter(BILLBOARD_URL, true), result); 42 | addConstants(linkRelationConstants, result); 43 | addConstants(errorConstants, result); 44 | addConstants(mediaTypeConstants, result); 45 | addDefaultMediaType(result); 46 | result.add(""); 47 | result.add("}"); 48 | return result; 49 | } 50 | 51 | private void addDefaultMediaType(Code code) { 52 | if (defaultMediaType != null) { 53 | if (!mediaTypeConstants.all().iterator().hasNext()) { 54 | addConstantsHeading(mediaTypeConstants.getDescription(), code); 55 | } 56 | String defaultMediaTypeConstant = getLocalMediaTypeConstant(mediaTypeConstants, defaultMediaType.name()); 57 | code.add(" String %s = \"%s\";", defaultMediaTypeConstant, defaultMediaType.name()); 58 | code.add(" String %s = %s;", DEFAULT_MEDIA_TYPE_CONSTANT, defaultMediaTypeConstant); 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/generation/spring/ErrorDtoGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.generation.spring; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | import java.util.Map; 9 | 10 | import radl.core.code.Code; 11 | import radl.core.code.radl.RadlCode; 12 | import radl.java.code.JavaBeanProperty; 13 | import radl.java.code.JavaCode; 14 | 15 | 16 | public class ErrorDtoGenerator extends FromRadlErrorsCodeGenerator { 17 | 18 | @Override 19 | protected void generateFromRadlErrors(RadlCode radl, Iterable errors, Map context, 20 | Collection sources) { 21 | sources.add(generateErrorDto()); 22 | } 23 | 24 | private Code generateErrorDto() { 25 | Code result = new JavaCode(); 26 | addPackage(IMPL_PACKAGE, result); 27 | result.add(""); 28 | result.add(""); 29 | result.add("public class %s {", ERROR_DTO_TYPE); 30 | result.add(""); 31 | addProperties(result, Arrays.asList(new JavaBeanProperty("title"), new JavaBeanProperty("type"))); 32 | result.add("}"); 33 | return result; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/generation/spring/FromRadlErrorsCodeGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.generation.spring; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collection; 8 | import java.util.Collections; 9 | import java.util.Map; 10 | 11 | import radl.core.code.Code; 12 | import radl.core.code.radl.RadlCode; 13 | import radl.java.code.Java; 14 | 15 | 16 | public abstract class FromRadlErrorsCodeGenerator extends FromRadlCodeGenerator { 17 | 18 | protected static final String ERROR_DTO_TYPE = "Error" + FromRadlCodeGenerator.DTO_SUFFIX; 19 | protected static final String IDENTIFIABLE_TYPE = "Identifiable"; 20 | protected static final int BAD_REQUEST = 400; 21 | protected static final int INTERNAL_SERVER_ERROR = 500; 22 | 23 | @Override 24 | protected Collection generateFromRadl(RadlCode radl, Map context) { 25 | Iterable errors = radl.errors(); 26 | if (!errors.iterator().hasNext()) { 27 | return Collections.emptyList(); 28 | } 29 | Collection result = new ArrayList<>(); 30 | generateFromRadlErrors(radl, errors, context, result); 31 | return result; 32 | } 33 | 34 | protected abstract void generateFromRadlErrors(RadlCode radl, Iterable errors, Map context, 35 | Collection sources); 36 | 37 | protected String toExceptionTypeName(String name) { 38 | return Java.toIdentifier(name + "Exception"); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/generation/spring/IdentifiableGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.generation.spring; 5 | 6 | import java.util.Collection; 7 | import java.util.Map; 8 | 9 | import radl.core.code.Code; 10 | import radl.core.code.radl.RadlCode; 11 | import radl.java.code.JavaCode; 12 | 13 | 14 | public class IdentifiableGenerator extends FromRadlErrorsCodeGenerator { 15 | 16 | @Override 17 | protected void generateFromRadlErrors(RadlCode radl, Iterable errors, Map context, 18 | Collection sources) { 19 | sources.add(generateIdentifiable()); 20 | } 21 | 22 | private Code generateIdentifiable() { 23 | Code result = new JavaCode(); 24 | addPackage(IMPL_PACKAGE, result); 25 | result.add(""); 26 | result.add(""); 27 | result.add("public interface %s {", IDENTIFIABLE_TYPE); 28 | result.add(""); 29 | result.add(" String getId();"); 30 | result.add(""); 31 | result.add("}"); 32 | return result; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/generation/spring/SpringCodeBaseGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.generation.spring; 5 | 6 | import java.util.List; 7 | 8 | import radl.core.generation.CodeBaseGeneratorImpl; 9 | import radl.core.generation.CodeGenerator; 10 | import radl.core.generation.Module; 11 | 12 | 13 | /** 14 | * Generates a Java code base for the Spring framework from a RADL document. 15 | */ 16 | public class SpringCodeBaseGenerator extends CodeBaseGeneratorImpl { 17 | 18 | private static final String DEFAULT_HEADER = "Generated from RADL."; 19 | 20 | public SpringCodeBaseGenerator(String packagePrefix) { 21 | this(packagePrefix, null); 22 | } 23 | 24 | public SpringCodeBaseGenerator(String packagePrefix, String header) { 25 | super(packagePrefix, header == null || header.trim().isEmpty() ? DEFAULT_HEADER : header, 26 | new FromRadlCodeGenerationInitializer(), 27 | new ActionsGenerator(), 28 | new DtosGenerator(), 29 | new ErrorDtoGenerator(), 30 | new ExceptionsGenerator(), 31 | new IdentifiableGenerator(), 32 | new ExceptionHandlerGenerator(), 33 | new RestResponseGenerator(), 34 | new ControllersGenerator(), 35 | new ControllerSupportsGenerator(), 36 | new UrisGenerator(), 37 | new ApiGenerator()); 38 | } 39 | 40 | @Override 41 | protected Module moduleFor(List modules, CodeGenerator generator) { 42 | if (generator instanceof ControllerSupportsGenerator) { 43 | return modules.get(1); 44 | } 45 | return super.moduleFor(modules, generator); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /java/core/src/main/java/radl/java/generation/spring/UrisGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.generation.spring; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | import java.util.Map; 9 | 10 | import radl.core.code.Code; 11 | import radl.core.code.common.Constants; 12 | import radl.core.code.radl.RadlCode; 13 | import radl.java.code.JavaCode; 14 | 15 | 16 | public class UrisGenerator extends FromRadlCodeGenerator { 17 | 18 | @Override 19 | protected Collection generateFromRadl(RadlCode radl, Map context) { 20 | Constants uriConstants = (Constants)context.get(URI_CONSTANTS); 21 | return Arrays.asList(generateUris(uriConstants)); 22 | } 23 | 24 | private Code generateUris(Constants uriConstants) { 25 | JavaCode result = new JavaCode(); 26 | addPackage(IMPL_PACKAGE, result); 27 | result.add(""); 28 | result.add(""); 29 | result.add("public interface %s {", URIS_TYPE); 30 | addUris(uriConstants, result); 31 | result.add(""); 32 | result.add("}"); 33 | return result; 34 | } 35 | 36 | private void addUris(Constants uriConstants, JavaCode code) { 37 | addConstants(uriConstants.filter(BILLBOARD_URL, false), code); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /java/core/src/main/resources/META-INF/services/radl.core.extraction.RestProcessor: -------------------------------------------------------------------------------- 1 | radl.core.extraction.JaxrsProcessor 2 | radl.core.extraction.SpringProcessor 3 | -------------------------------------------------------------------------------- /java/core/src/main/resources/META-INF/services/radl.core.scm.SourceCodeManagementSystem: -------------------------------------------------------------------------------- 1 | radl.core.scm.DefaultSourceCodeManagementSystem 2 | radl.core.scm.Perforce 3 | -------------------------------------------------------------------------------- /java/core/src/main/resources/META-INF/services/radl.core.validation.IssueReporter: -------------------------------------------------------------------------------- 1 | radl.core.validation.CheckStyleIssueReporter 2 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/cli/ArgumentsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.cli; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | import static org.junit.Assert.assertFalse; 8 | 9 | import java.io.File; 10 | 11 | import org.junit.Test; 12 | 13 | import radl.test.RandomData; 14 | 15 | 16 | public class ArgumentsTest { 17 | 18 | private static final RandomData RANDOM = new RandomData(); 19 | 20 | @Test 21 | public void extractsExistingArgumentsInOrder() { 22 | String arg1 = RANDOM.string(); 23 | String arg2 = RANDOM.string(); 24 | 25 | Arguments arguments = new Arguments(new String[] { arg1, arg2 }); 26 | 27 | assertEquals("#1", arg1, arguments.next()); 28 | assertEquals("#2", arg2, arguments.next()); 29 | assertFalse("Has #3", arguments.hasNext()); 30 | } 31 | 32 | @Test 33 | public void returnsDefaultValueForMissingArgument() { 34 | String arg = RANDOM.string(); 35 | String defaultValue = RANDOM.string(); 36 | 37 | Arguments arguments = new Arguments(new String[] { arg }); 38 | 39 | assertEquals("Existing", arg, arguments.next(defaultValue)); 40 | assertEquals("Default", defaultValue, arguments.next(defaultValue)); 41 | } 42 | 43 | @Test 44 | public void convertsToFile() { 45 | String fileName = RANDOM.string(); 46 | String defaultValue = RANDOM.string(); 47 | 48 | Arguments arguments = new Arguments(new String[] { fileName }); 49 | 50 | assertEquals("Existing", new File(fileName), arguments.file()); 51 | assertEquals("Default", new File(defaultValue), arguments.file(defaultValue)); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/documentation/AssertEquals.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.documentation; 6 | 7 | import org.jsoup.nodes.Document; 8 | import org.junit.Assert; 9 | 10 | 11 | public class AssertEquals implements Assertion { 12 | 13 | private final String message; 14 | private final Value expectation; 15 | private final Value actualization; 16 | 17 | public AssertEquals(String message, Value expected, Value actual) { 18 | this.message = message; 19 | this.expectation = expected; 20 | this.actualization = actual; 21 | } 22 | 23 | @Override 24 | public void verify(Document document) { 25 | String expected = expectation.get(document); 26 | String actual = actualization.get(document); 27 | Assert.assertEquals(message, expected, actual); 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return message + ": " + expectation + " == " + actualization; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/documentation/Assertion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.documentation; 6 | 7 | import org.jsoup.nodes.Document; 8 | 9 | 10 | public interface Assertion { 11 | 12 | void verify(Document document); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/documentation/DocumentationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.documentation; 6 | 7 | import java.io.File; 8 | import java.util.ArrayList; 9 | import java.util.Collection; 10 | 11 | import org.jsoup.Jsoup; 12 | import org.jsoup.nodes.Document; 13 | import org.junit.AfterClass; 14 | import org.junit.BeforeClass; 15 | import org.junit.Test; 16 | import org.junit.runner.RunWith; 17 | import org.junit.runners.Parameterized; 18 | import org.junit.runners.Parameterized.Parameter; 19 | import org.junit.runners.Parameterized.Parameters; 20 | 21 | import radl.core.Log; 22 | import radl.core.cli.Arguments; 23 | 24 | 25 | @RunWith(Parameterized.class) 26 | public class DocumentationTest { 27 | 28 | private static final File TESTS_DIR = new File(System.getProperty("radl.dir", "."), 29 | "specification/tests/documentation"); 30 | private static final File BUILD_DIR = new File("build/tmp/doc"); 31 | private static final String RADL_FILE = "instance"; 32 | 33 | @Parameters(name = "{0}") 34 | public static Iterable tests() { 35 | Collection result = new ArrayList<>(); 36 | for (String dir : TESTS_DIR.list()) { 37 | result.add(new String[] { dir }); 38 | } 39 | return result; 40 | } 41 | 42 | @Parameter 43 | public String dir; 44 | 45 | @BeforeClass 46 | public static void init() { 47 | Log.deactivate(); 48 | } 49 | 50 | @AfterClass 51 | public static void done() { 52 | Log.activate(); 53 | } 54 | 55 | @Test 56 | public void testValidation() throws Exception { 57 | File testDir = new File(TESTS_DIR, dir); 58 | File radlFile = new File (testDir, RADL_FILE + ".xml"); 59 | File docDir = new File(BUILD_DIR, dir); 60 | DocumentationVerifier documentationVerifier = new DocumentationVerifier(new File(testDir, "test.xml")); 61 | 62 | new DocumentationGenerator().run(new Arguments(new String[] { 63 | docDir.getAbsolutePath(), 64 | radlFile.getAbsolutePath() 65 | })); 66 | 67 | Document documentation = Jsoup.parse(new File(docDir, RADL_FILE + "/index.html"), "UTF-8", ""); 68 | documentationVerifier.verify(documentation); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/documentation/DocumentationVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.documentation; 6 | 7 | import java.io.File; 8 | 9 | import org.jsoup.nodes.Document; 10 | 11 | 12 | public class DocumentationVerifier { 13 | 14 | private final Iterable assertions; 15 | 16 | public DocumentationVerifier(File testFile) throws Exception { 17 | assertions = new TestParser().parse(testFile); 18 | } 19 | 20 | public void verify(Document document) { 21 | for (Assertion assertion : assertions) { 22 | assertion.verify(document); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/documentation/JGraphStateDiagramTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.documentation; 5 | 6 | import static org.junit.Assert.assertTrue; 7 | 8 | import java.io.File; 9 | 10 | import org.junit.After; 11 | import org.junit.Before; 12 | import org.junit.Ignore; 13 | import org.junit.Test; 14 | 15 | import radl.common.io.IO; 16 | import radl.test.RandomData; 17 | import radl.test.TestUtil; 18 | 19 | 20 | public class JGraphStateDiagramTest { 21 | 22 | private static final RandomData RANDOM = new RandomData(); 23 | 24 | private final String title = aName(); 25 | private final StateDiagram std = new JGraphStateDiagram(); 26 | private final File dir = TestUtil.randomDir(JGraphStateDiagramTest.class); 27 | 28 | public String aName() { 29 | return RANDOM.string(8); 30 | } 31 | 32 | @Before 33 | public void init() { 34 | std.setTitle(title); 35 | } 36 | 37 | @After 38 | public void done() { 39 | IO.delete(dir); 40 | } 41 | 42 | @Test 43 | @Ignore("Enable when we move to Java 7") 44 | public void convertsGraphToImageFile() { 45 | String from = aName(); 46 | String intermediate = aName(); 47 | String to = aName(); 48 | String transition1 = aName(); 49 | String transition2 = aName(); 50 | std.addStartState(from); 51 | std.addState(intermediate); 52 | std.addState(to); 53 | std.addTransition(from, intermediate, transition1); 54 | std.addTransition(intermediate, to, transition2); 55 | File image = TestUtil.randomFile(JGraphStateDiagramTest.class, "png"); 56 | 57 | std.toImage(image); 58 | 59 | assertTrue("Image not created", image.exists()); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/documentation/LiteralValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.documentation; 6 | 7 | import org.jsoup.nodes.Document; 8 | import org.w3c.dom.Element; 9 | 10 | 11 | public class LiteralValue implements Value { 12 | 13 | private final String value; 14 | 15 | public LiteralValue(Element element) { 16 | value = element.getTextContent(); 17 | } 18 | 19 | @Override 20 | public String get(Document document) { 21 | return value; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "'" + value + "'"; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/documentation/SelectorValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.documentation; 6 | 7 | import org.jsoup.nodes.Document; 8 | import org.jsoup.select.Elements; 9 | import org.w3c.dom.Element; 10 | 11 | 12 | public class SelectorValue implements Value { 13 | 14 | private final String element; 15 | private final String attribute; 16 | 17 | public SelectorValue(Element element) { 18 | this.element = element.getAttributeNS(null, "element"); 19 | this.attribute = element.getAttributeNS(null, "attribute"); 20 | } 21 | 22 | @Override 23 | public String get(Document document) { 24 | Elements elements = document.select(element); 25 | if (elements.isEmpty()) { 26 | return null; 27 | } 28 | if (attribute.isEmpty()) { 29 | return elements.first().text(); 30 | } 31 | return elements.first().attr(attribute); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | StringBuilder result = new StringBuilder(); 37 | result.append("select(").append(element).append(')'); 38 | if (attribute != null) { 39 | result.append("/@").append(attribute); 40 | } 41 | return result.toString(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/documentation/TestParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.documentation; 6 | 7 | import java.io.File; 8 | import java.util.ArrayList; 9 | import java.util.Collection; 10 | 11 | import org.w3c.dom.Document; 12 | import org.w3c.dom.Element; 13 | 14 | import radl.common.xml.ElementProcessor; 15 | import radl.common.xml.Xml; 16 | 17 | 18 | public class TestParser { 19 | 20 | public Iterable parse(File test) throws Exception { 21 | final Collection result = new ArrayList<>(); 22 | Document assertions = Xml.parse(test); 23 | Xml.processChildElements(assertions.getDocumentElement(), new ElementProcessor() { 24 | @Override 25 | public void process(Element element) throws Exception { 26 | String message = element.getAttributeNS(null, "message"); 27 | if ("equals".equals(element.getLocalName())) { 28 | result.add(parseEquals(element, message)); 29 | } 30 | } 31 | }); 32 | return result; 33 | } 34 | 35 | private Assertion parseEquals(Element element, String message) { 36 | Element child = Xml.getFirstChildElement(element, null); 37 | Value expected = parseValue(child); 38 | Value actual = parseValue(Xml.nextElement(child)); 39 | return new AssertEquals(message, expected, actual); 40 | } 41 | 42 | private Value parseValue(Element element) { 43 | String tag = element.getLocalName(); 44 | if ("literal".equals(tag)) { 45 | return new LiteralValue(element); 46 | } 47 | if ("select".equals(tag)) { 48 | return new SelectorValue(element); 49 | } 50 | throw new UnsupportedOperationException("Unknown value type: " + tag); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/documentation/Value.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 EMC Corporation. All Rights Reserved. 3 | * EMC Confidential: Restricted Internal Distribution 4 | */ 5 | package radl.core.documentation; 6 | 7 | import org.jsoup.nodes.Document; 8 | 9 | 10 | public interface Value { 11 | 12 | String get(Document document); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/generation/DesiredSourceFilesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.generation; 5 | 6 | import static org.mockito.Mockito.mock; 7 | import static org.mockito.Mockito.when; 8 | 9 | import java.io.File; 10 | import java.util.Arrays; 11 | import java.util.Collection; 12 | import java.util.List; 13 | 14 | import org.junit.After; 15 | import org.junit.Assert; 16 | import org.junit.Test; 17 | import org.w3c.dom.Document; 18 | 19 | import radl.common.io.IO; 20 | import radl.common.xml.DocumentBuilder; 21 | import radl.core.code.SourceFile; 22 | import radl.core.enforce.Desired; 23 | import radl.test.RandomData; 24 | import radl.test.TestUtil; 25 | 26 | 27 | public class DesiredSourceFilesTest { 28 | 29 | private static final RandomData RANDOM = new RandomData(); 30 | 31 | private final Document radl = DocumentBuilder.newDocument().build(); 32 | private final SourceFilesGenerator generator = mock(SourceFilesGenerator.class); 33 | private final String basePath = TestUtil.randomDir(DesiredSourceFilesTest.class).getPath() + File.separator; 34 | private final Desired desired = new DesiredSourceFiles(radl, generator, new File(basePath)); 35 | 36 | @After 37 | public void done() { 38 | IO.delete(new File(basePath)); 39 | } 40 | 41 | @Test 42 | public void returnsPathsOfSourceFilesAsIds() throws Exception { 43 | String path1 = "z" + RANDOM.string(); 44 | String path2 = "a" + RANDOM.string(); 45 | when(generator.generateFrom(radl, new File(basePath))).thenReturn( 46 | Arrays.asList(new SourceFile(path1), new SourceFile(path2))); 47 | List expected = Arrays.asList(path2, path1); 48 | 49 | Collection actual = desired.getIds(); 50 | 51 | TestUtil.assertCollectionEquals("IDs", expected, actual); 52 | } 53 | 54 | @Test 55 | public void returnsSourceFile() throws Exception { 56 | SourceFile expected = new SourceFile(basePath + RANDOM.string()); 57 | when(generator.generateFrom(radl, new File(basePath))).thenReturn(Arrays.asList(expected)); 58 | 59 | SourceFile actual = desired.get(expected.path()); 60 | 61 | Assert.assertEquals("Source file", expected, actual); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/integration/JavaCompiler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.integration; 5 | 6 | import java.io.File; 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.Collection; 10 | import java.util.Properties; 11 | 12 | import radl.core.cli.Application; 13 | import radl.core.cli.Arguments; 14 | import radl.java.code.Java; 15 | 16 | 17 | public class JavaCompiler implements Application { 18 | 19 | @Override 20 | public int run(Arguments arguments) { 21 | return Java.getCompiler().run(System.in, System.out, System.err, getCompileArguments(arguments)); 22 | } 23 | 24 | private String[] getCompileArguments(Arguments arguments) { 25 | Collection result = new ArrayList<>(); 26 | Properties properties = arguments.properties(); 27 | File baseDir = new File(properties.getProperty("base.dir")); 28 | File outputDir = new File(baseDir, "classes"); 29 | outputDir.mkdirs(); 30 | String classpath = properties.getProperty("classpath"); 31 | String javaVersion = properties.getProperty("java.version"); 32 | result.addAll(Arrays.asList( 33 | "-d", outputDir.getPath(), 34 | "-cp", classpath, 35 | "-source", javaVersion 36 | )); 37 | addSource(baseDir, result); 38 | return result.toArray(new String[result.size()]); 39 | } 40 | 41 | private void addSource(File dir, Collection paths) { 42 | for (File file : dir.listFiles()) { 43 | if (file.isDirectory()) { 44 | addSource(file, paths); 45 | } else if (file.isFile() && file.getName().endsWith(".java")) { 46 | paths.add(file.getPath()); 47 | } 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/io/ByteArrayInputOutputStreamTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.io; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.IOException; 8 | import java.io.InputStreamReader; 9 | import java.io.OutputStreamWriter; 10 | import java.io.PrintWriter; 11 | 12 | import org.junit.Assert; 13 | import org.junit.Test; 14 | 15 | import radl.common.io.ByteArrayInputOutputStream; 16 | import radl.test.RandomData; 17 | 18 | 19 | public class ByteArrayInputOutputStreamTest { 20 | 21 | private static final RandomData RANDOM = new RandomData(); 22 | 23 | @Test 24 | public void readsWhatWasWritten() throws IOException { 25 | String line1 = RANDOM.string(); 26 | String line2 = RANDOM.string(); 27 | try (ByteArrayInputOutputStream stream = new ByteArrayInputOutputStream()) { 28 | try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(stream, "UTF8"))) { 29 | writer.println(line1); 30 | writer.println(line2); 31 | } 32 | try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream.getInputStream(), "UTF8"))) { 33 | Assert.assertEquals("1st line", line1, reader.readLine()); 34 | Assert.assertEquals("2nd line", line2, reader.readLine()); 35 | Assert.assertNull("Extra line", reader.readLine()); 36 | } 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/scm/OperatingSystemImplTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.scm; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | import static org.junit.Assert.assertNotNull; 8 | import static org.junit.Assert.assertTrue; 9 | import static org.junit.Assert.fail; 10 | 11 | import java.io.IOException; 12 | import java.util.UUID; 13 | 14 | import org.junit.Test; 15 | 16 | 17 | public class OperatingSystemImplTest { 18 | 19 | @Test 20 | public void executesCommand() { 21 | String command = UUID.randomUUID().toString(); 22 | 23 | try { 24 | new OperatingSystemImpl().run(command); 25 | fail("Missing exception"); 26 | } catch (RuntimeException e) { 27 | assertNotNull("Missing cause", e.getCause()); 28 | assertEquals("Exception", IOException.class, e.getCause().getClass()); 29 | assertTrue("Exception message", e.getCause().getMessage().contains(command)); 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/scm/PerforceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.scm; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | import static org.mockito.Matchers.anyString; 8 | import static org.mockito.Mockito.mock; 9 | import static org.mockito.Mockito.never; 10 | import static org.mockito.Mockito.verify; 11 | 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.io.PrintWriter; 15 | 16 | import org.junit.Test; 17 | 18 | import radl.common.io.IO; 19 | import radl.test.TestUtil; 20 | 21 | 22 | public class PerforceTest { 23 | 24 | private final OperatingSystem operatingSystem = mock(OperatingSystem.class); 25 | private final SourceCodeManagementSystem p4 = new Perforce(operatingSystem); 26 | 27 | @Test 28 | public void returnsId() { 29 | assertEquals("ID", "p4", p4.getId()); 30 | } 31 | 32 | @Test 33 | public void editsReadOnlyFile() throws IOException { 34 | File file = someFile(); 35 | try { 36 | file.setReadOnly(); 37 | 38 | p4.prepareForUpdate(file); 39 | 40 | verify(operatingSystem).run("p4 edit " + file.getAbsolutePath()); 41 | } finally { 42 | IO.delete(file); 43 | } 44 | } 45 | 46 | private File someFile() throws IOException { 47 | File result = TestUtil.randomFile(getClass(), ".p4"); 48 | try (PrintWriter writer = new PrintWriter(result, "UTF8")) { 49 | writer.println(); 50 | } 51 | return result; 52 | } 53 | 54 | @Test 55 | public void doesntEditWritableFile() throws IOException { 56 | File file = someFile(); 57 | try { 58 | p4.prepareForUpdate(file); 59 | 60 | verify(operatingSystem, never()).run(anyString()); 61 | } finally { 62 | IO.delete(file); 63 | } 64 | } 65 | 66 | @Test 67 | public void doesntDeleteWritableFile() throws IOException { 68 | File file = someFile(); 69 | try { 70 | p4.prepareForDelete(file); 71 | 72 | verify(operatingSystem, never()).run(anyString()); 73 | } finally { 74 | IO.delete(file); 75 | } 76 | } 77 | 78 | @Test 79 | public void deletesReadOnlyFile() throws IOException { 80 | File file = someFile(); 81 | try { 82 | file.setReadOnly(); 83 | 84 | p4.prepareForDelete(file); 85 | 86 | verify(operatingSystem).run("p4 delete " + file.getAbsolutePath()); 87 | } finally { 88 | IO.delete(file); 89 | } 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/scm/ScmFactoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.scm; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | 8 | import org.junit.Test; 9 | 10 | import radl.test.RandomData; 11 | 12 | 13 | public class ScmFactoryTest { 14 | 15 | private static final RandomData RANDOM = new RandomData(); 16 | 17 | private final String id = RANDOM.string(); 18 | 19 | @Test(expected = IllegalArgumentException.class) 20 | public void throwsExceptionOnUnknownId() { 21 | ScmFactory.newInstance(id); 22 | } 23 | 24 | @Test 25 | public void returnsPerforceScm() throws Exception { 26 | assertScm(Perforce.class, "p4"); 27 | } 28 | 29 | private void assertScm(Class scmClass, String scmId) { 30 | assertEquals("SCM", scmClass, ScmFactory.newInstance(scmId).getClass()); 31 | } 32 | 33 | @Test 34 | public void returnsDefaultScm() throws Exception { 35 | assertScm(DefaultSourceCodeManagementSystem.class, "default"); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/validation/IssueReporterFactoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.validation; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | 8 | import org.junit.Test; 9 | 10 | import radl.test.RandomData; 11 | 12 | 13 | public class IssueReporterFactoryTest { 14 | 15 | private static final RandomData RANDOM = new RandomData(); 16 | 17 | private final String id = RANDOM.string(); 18 | 19 | @Test(expected = IllegalArgumentException.class) 20 | public void throwsExceptionOnUnknownId() { 21 | IssueReporterFactory.newInstance(id); 22 | } 23 | 24 | @Test 25 | public void checkStyle() throws Exception { 26 | assertIssueReporter(CheckStyleIssueReporter.class, "checkstyle"); 27 | } 28 | 29 | private void assertIssueReporter(Class scmClass, String scmId) { 30 | assertEquals("SCM", scmClass, IssueReporterFactory.newInstance(scmId).getClass()); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/validation/PrintStreamIssueReporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.validation; 5 | 6 | import java.io.FileNotFoundException; 7 | import java.io.PrintStream; 8 | 9 | import radl.core.validation.Issue.Level; 10 | 11 | 12 | /* 13 | * Print validation issues to a stream. 14 | */ 15 | public class PrintStreamIssueReporter implements IssueReporter { 16 | 17 | private static final String NL = System.getProperty("line.separator"); 18 | 19 | private PrintStream stream; 20 | private StringBuilder errors; // NOPMD AvoidStringBufferField 21 | private String currentFile; 22 | 23 | public PrintStreamIssueReporter() { 24 | this(System.out); 25 | } 26 | 27 | public PrintStreamIssueReporter(PrintStream stream) { 28 | this.stream = stream; 29 | } 30 | 31 | @Override 32 | public void setReportFileName(String reportFileName) { 33 | try { 34 | this.stream = new PrintStream(reportFileName); 35 | } catch (FileNotFoundException e) { 36 | throw new RuntimeException(e); 37 | } 38 | } 39 | 40 | @Override 41 | public void start() { 42 | errors = new StringBuilder(); 43 | } 44 | 45 | @Override 46 | public void file(String file) { 47 | currentFile = file; 48 | } 49 | 50 | @Override 51 | public void issue(Issue issue) { 52 | if (issue.getLevel() == Level.ERROR) { 53 | errors.append("File: ").append(currentFile).append("; ").append(issue).append(NL); 54 | } else { 55 | stream.print("File: "); 56 | stream.print(currentFile); 57 | stream.print("; "); 58 | stream.println(issue); 59 | } 60 | } 61 | 62 | @Override 63 | public void end() { 64 | if (errors.length() > 0) { 65 | throw new IllegalArgumentException(errors.toString()); 66 | } 67 | } 68 | 69 | @Override 70 | public String getId() { 71 | return "stdout"; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/validation/RelaxNgValidatorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.core.validation; 5 | 6 | import static org.junit.Assert.assertTrue; 7 | 8 | import java.io.File; 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.Collection; 12 | 13 | import org.junit.After; 14 | import org.junit.Test; 15 | 16 | import radl.common.io.IO; 17 | import radl.common.io.StringStream; 18 | import radl.core.Radl; 19 | import radl.test.RandomData; 20 | import radl.test.TestUtil; 21 | 22 | 23 | public class RelaxNgValidatorTest { 24 | 25 | private static final RandomData RANDOM = new RandomData(); 26 | 27 | private final File file = new File(RANDOM.string()); 28 | private final Validator validator = new RelaxNgValidator(); 29 | private final Collection issues = new ArrayList<>(); 30 | 31 | @After 32 | public void done() { 33 | IO.delete(file); 34 | } 35 | 36 | @Test 37 | public void acceptsValidRadlFile() { 38 | validate(""); 39 | 40 | assertTrue("Unexpected issues added: " + issues, issues.isEmpty()); 41 | } 42 | 43 | private void validate(String contents) { 44 | validator.validate(new StringStream(contents), issues); 45 | } 46 | 47 | @Test 48 | public void addsErrorsForSchemaViolations() { 49 | validate(""); 50 | 51 | Issue expectedIssue = new Issue(RelaxNgValidator.class, Issue.Level.ERROR, 1, 7, 52 | "element \"foo\" not allowed anywhere; expected element \"service\" " 53 | + "(with xmlns=\"" + Radl.NAMESPACE_URI + "\")"); 54 | TestUtil.assertCollectionEquals("Issues", Arrays.asList(expectedIssue), issues); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/core/validation/TestIssueReporter.java: -------------------------------------------------------------------------------- 1 | package radl.core.validation; 2 | 3 | import java.io.IOException; 4 | import java.io.PrintWriter; 5 | 6 | 7 | public class TestIssueReporter implements IssueReporter { 8 | 9 | public static final String FILE_NAME = TestIssueReporter.class.getName(); 10 | public static final String ID = "test"; 11 | 12 | @Override 13 | public void setReportFileName(String reportFileName) { 14 | try (PrintWriter writer = new PrintWriter(FILE_NAME, "UTF-8")) { 15 | writer.println(FILE_NAME); 16 | } catch (IOException e) { 17 | throw new RuntimeException(e); 18 | } 19 | } 20 | 21 | @Override 22 | public void start() { 23 | } 24 | 25 | @Override 26 | public void file(String fileName) { 27 | } 28 | 29 | @Override 30 | public void issue(Issue issue) { 31 | } 32 | 33 | @Override 34 | public void end() { 35 | } 36 | 37 | @Override 38 | public String getId() { 39 | return ID; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/code/JavaTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.code; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.io.PrintWriter; 11 | 12 | import org.junit.Test; 13 | 14 | import radl.common.io.IO; 15 | 16 | 17 | public class JavaTest { 18 | 19 | private static final File TMP_DIR = new File("build/tmp"); 20 | 21 | @Test 22 | public void findsJdk() throws IOException { 23 | assertJdk("foo"); 24 | assertJdk("bar\\"); 25 | assertJdk("baz/"); 26 | assertJdk("jre"); 27 | } 28 | 29 | private void assertJdk(String dir) throws IOException { 30 | String path = simulateJdkIn(dir); 31 | try { 32 | String saveJavaHome = System.getProperty(Java.JAVA_HOME); 33 | try { 34 | System.setProperty(Java.JAVA_HOME, path); 35 | Java.ensureCorrectJavaHome(); 36 | 37 | assertEquals("JDK in '" + dir + "'", path, System.getProperty(Java.JAVA_HOME)); 38 | } finally { 39 | System.setProperty(Java.JAVA_HOME, saveJavaHome); 40 | } 41 | } finally { 42 | IO.delete(TMP_DIR); 43 | } 44 | } 45 | 46 | private String simulateJdkIn(String path) throws IOException { 47 | File result = new File(TMP_DIR, path); 48 | File dir = new File(result, "lib"); 49 | if (!dir.mkdirs()) { 50 | throw new IllegalStateException("Couldn't create directory: " + dir.getPath()); 51 | } 52 | try (PrintWriter writer = new PrintWriter(new File(dir, "tools.jar"), "UTF8")) { 53 | writer.println(); 54 | } 55 | return result.getAbsolutePath(); 56 | } 57 | 58 | @Test 59 | public void toJavaString() { 60 | assertJavaString("ape", "ape"); 61 | assertJavaString("bear\ncheetah", "bear\\ncheetah"); 62 | assertJavaString("dingo\"elephant", "dingo\\\"elephant"); 63 | } 64 | 65 | private void assertJavaString(String input, String expected) { 66 | assertEquals("toString(" + input + ")", expected, Java.toString(input)); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/TimerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | import static org.mockito.Mockito.mock; 8 | import static org.mockito.Mockito.when; 9 | 10 | import org.junit.Test; 11 | 12 | import radl.test.RandomData; 13 | 14 | 15 | public class TimerTest { 16 | 17 | private static final RandomData RANDOM = new RandomData(); 18 | 19 | private final Clock clock = mock(Clock.class); 20 | private final Timer timer = new Timer(clock); 21 | 22 | @Test 23 | public void showsMilliSeconds() { 24 | long ms = someMilliSeconds(); 25 | 26 | assertTime(ms, ms + " ms"); 27 | } 28 | 29 | private int someMilliSeconds() { 30 | return RANDOM.integer(100, 999); 31 | } 32 | 33 | private void assertTime(long now, String expected) { 34 | when(clock.now()).thenReturn(now); 35 | assertEquals(now + " ms", expected, timer.toString()); 36 | } 37 | 38 | @Test 39 | public void showsSecondsAndMilliSeconds() { 40 | long sec = someSeconds(); 41 | int ms = someMilliSeconds() / 100; 42 | 43 | assertTime(1000 * sec + 100 * ms + RANDOM.integer(49), sec + "." + ms + " s"); 44 | } 45 | 46 | private int someSeconds() { 47 | return RANDOM.integer(1, 59); 48 | } 49 | 50 | @Test 51 | public void showsMinutesAndSeconds() { 52 | long min = someMinutes(); 53 | int sec = someSeconds(); 54 | long now = 1000 * (60 * min + sec) + someMilliSeconds(); 55 | 56 | assertTime(now, min + ":" + sec + " min"); 57 | } 58 | 59 | private long someMinutes() { 60 | return someSeconds(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/Annotatable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | import java.util.Collection; 7 | 8 | 9 | interface Annotatable { 10 | 11 | T annotateWith(Collection annotations); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/Annotation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | 7 | public class Annotation { 8 | 9 | private final String name; 10 | private final String property; 11 | private final String value; 12 | 13 | public Annotation(String name) { 14 | this(name, null); 15 | } 16 | 17 | public Annotation(String name, String value) { 18 | this(name, "value", value); 19 | } 20 | 21 | public Annotation(String name, String property, String value) { 22 | this.name = name; 23 | this.property = property; 24 | this.value = value; 25 | } 26 | 27 | public String getName() { 28 | return name; 29 | } 30 | 31 | public String getProperty() { 32 | return property; 33 | } 34 | 35 | public String getValue() { 36 | return value; 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | return name.hashCode(); 42 | } 43 | 44 | @Override 45 | public boolean equals(Object obj) { 46 | return obj instanceof Annotation && name.equals(((Annotation)obj).name); 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | StringBuilder result = new StringBuilder().append(name); 52 | if (value != null) { 53 | result.append('(').append(property).append("=\"").append(value).append("\")"); 54 | } 55 | return result.toString(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/AnnotationBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | import java.util.Collection; 7 | import java.util.HashSet; 8 | 9 | 10 | public class AnnotationBuilder> { 11 | 12 | private static final String ANNOTATION_PACKAGE = "javax.ws.rs."; 13 | 14 | private final T parent; 15 | private final Collection annotations = new HashSet<>(); 16 | 17 | public AnnotationBuilder(T parent) { 18 | this.parent = parent; 19 | } 20 | 21 | public AnnotationBuilder path(String uri) { 22 | annotations.add(new Annotation(ANNOTATION_PACKAGE + "Path", uri)); 23 | return this; 24 | } 25 | 26 | public AnnotationBuilder applicationPath(String uri) { 27 | annotations.add(new Annotation(ANNOTATION_PACKAGE + "ApplicationPath", uri)); 28 | return this; 29 | } 30 | 31 | public AnnotationBuilder method(String method) { 32 | annotations.add(new Annotation(ANNOTATION_PACKAGE + method)); 33 | return this; 34 | } 35 | 36 | public AnnotationBuilder consuming(String mediaType) { 37 | annotations.add(new Annotation(ANNOTATION_PACKAGE + "Consumes", mediaType)); 38 | return this; 39 | } 40 | 41 | public AnnotationBuilder producing(String mediaType) { 42 | annotations.add(new Annotation(ANNOTATION_PACKAGE + "Produces", mediaType)); 43 | return this; 44 | } 45 | 46 | public AnnotationBuilder annotation(String annotation) { 47 | annotations.add(new Annotation(annotation)); 48 | return this; 49 | } 50 | 51 | public T end() { 52 | return parent.annotateWith(annotations); 53 | } 54 | 55 | public AnnotationBuilder pathParam(String name) { 56 | annotations.add(new Annotation(ANNOTATION_PACKAGE + "PathParam", name)); 57 | return this; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/Documentable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | 7 | public class Documentable { 8 | 9 | private final String documentation; 10 | 11 | public Documentable(String documentation) { 12 | this.documentation = documentation; 13 | } 14 | 15 | public boolean hasDocumentation() { 16 | return documentation != null; 17 | } 18 | 19 | public String getDocumentation() { 20 | return documentation; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/Method.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | import java.util.Collection; 7 | 8 | 9 | public class Method extends Documentable { 10 | 11 | private final String name; 12 | private final String returnType; 13 | private final Collection annotations; 14 | private final Collection parameters; 15 | 16 | public Method(String name, String returnType, String documentation, Collection annotations, 17 | Collection parameters) { 18 | super(documentation); 19 | this.name = name; 20 | this.returnType = returnType; 21 | this.annotations = annotations; 22 | this.parameters = parameters; 23 | } 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public String getReturnType() { 30 | return returnType; 31 | } 32 | 33 | public Collection getAnnotations() { 34 | return annotations; 35 | } 36 | 37 | public Collection getParameters() { 38 | return parameters; 39 | } 40 | 41 | @Override 42 | public int hashCode() { 43 | return name.hashCode(); 44 | } 45 | 46 | @Override 47 | public boolean equals(Object obj) { 48 | return obj instanceof Method && name.equals(((Method)obj).name); 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return new StringBuilder() 54 | .append(returnType == null ? "void" : returnType).append(' ').append(name).append("()") 55 | .toString(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/MethodBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collection; 8 | import java.util.HashSet; 9 | 10 | 11 | public class MethodBuilder implements Annotatable { 12 | 13 | private final TypeBuilder parent; 14 | private final String name; 15 | private final Collection annotations = new HashSet<>(); 16 | private String returnType; 17 | private String documentation; 18 | private final Collection parameters = new ArrayList<>(); 19 | 20 | public MethodBuilder(TypeBuilder parent, String name) { 21 | this.parent = parent; 22 | this.name = name; 23 | } 24 | 25 | public AnnotationBuilder annotatedWith() { 26 | return new AnnotationBuilder<>(this); 27 | } 28 | 29 | @Override 30 | public MethodBuilder annotateWith(Collection provided) { 31 | annotations.addAll(provided); 32 | return this; 33 | } 34 | 35 | public MethodBuilder returning(String type) { 36 | returnType = type; 37 | return this; 38 | } 39 | 40 | public TypeBuilder end() { 41 | return parent.addMethod(new Method(name, returnType, documentation, annotations, parameters)); 42 | } 43 | 44 | public MethodBuilder documentedWith(String provided) { 45 | this.documentation = provided; 46 | return this; 47 | } 48 | 49 | public ParameterBuilder withParameter(String var) { 50 | return new ParameterBuilder(this, var); 51 | } 52 | 53 | public MethodBuilder addParameter(Parameter parameter) { 54 | parameters.add(parameter); 55 | return this; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/Parameter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | import java.util.Collection; 7 | 8 | 9 | public class Parameter extends Documentable { 10 | 11 | private final String name; 12 | private final Collection annotations; 13 | 14 | public Parameter(String name, String documentation, Collection annotations) { 15 | super(documentation); 16 | this.name = name; 17 | this.annotations = annotations; 18 | } 19 | 20 | public Collection getAnnotations() { 21 | return annotations; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/ParameterBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | import java.util.Collection; 7 | import java.util.HashSet; 8 | 9 | 10 | public class ParameterBuilder implements Annotatable { 11 | 12 | private final MethodBuilder parent; 13 | private final String name; 14 | private final Collection annotations = new HashSet<>(); 15 | private String documentation; 16 | 17 | public ParameterBuilder(MethodBuilder parent, String name) { 18 | this.name = name; 19 | this.parent = parent; 20 | } 21 | 22 | @Override 23 | public ParameterBuilder annotateWith(Collection ann) { 24 | annotations.addAll(ann); 25 | return this; 26 | } 27 | 28 | public AnnotationBuilder annotatedWith() { 29 | return new AnnotationBuilder<>(this); 30 | } 31 | 32 | public ParameterBuilder documentedWith(String provided) { 33 | this.documentation = provided; 34 | return this; 35 | } 36 | 37 | public MethodBuilder end() { 38 | return parent.addParameter(new Parameter(name, documentation, annotations)); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/Project.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | import static org.mockito.Mockito.mock; 7 | import static org.mockito.Mockito.when; 8 | 9 | import java.util.Map; 10 | 11 | import javax.annotation.processing.ProcessingEnvironment; 12 | import javax.annotation.processing.Processor; 13 | import javax.lang.model.element.Element; 14 | import javax.lang.model.element.TypeElement; 15 | import javax.lang.model.util.Elements; 16 | import javax.lang.model.util.Types; 17 | 18 | 19 | public class Project { 20 | 21 | private final TestRoundEnvironment environment; 22 | private final Types types; 23 | private final Elements elements; 24 | private final Map options; 25 | 26 | public Project(TestRoundEnvironment environment, Types types, Elements elements, Map options) { 27 | this.environment = environment; 28 | this.types = types; 29 | this.elements = elements; 30 | this.options = options; 31 | } 32 | 33 | public boolean apply(Processor processor) { 34 | ProcessingEnvironment processingEnvironment = mock(ProcessingEnvironment.class); 35 | when(processingEnvironment.getOptions()).thenReturn(options); 36 | when(processingEnvironment.getTypeUtils()).thenReturn(types); 37 | when(processingEnvironment.getElementUtils()).thenReturn(elements); 38 | processor.init(processingEnvironment); 39 | 40 | return processor.process(environment.getAnnotations(), environment); 41 | } 42 | 43 | public TypeElement getRootElement(String name) { 44 | for (Element element : environment.getRootElements()) { 45 | if (element.getSimpleName().contentEquals(name)) { 46 | return (TypeElement)element; 47 | } 48 | } 49 | return null; 50 | } 51 | 52 | public TypeElement getAnnotation(Element element) { 53 | return environment.getAnnotationsOn(element).iterator().next(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/TestName.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | import javax.lang.model.element.Name; 7 | 8 | 9 | public class TestName implements Name { 10 | 11 | private final String value; 12 | 13 | public TestName(String value) { 14 | this.value = value; 15 | } 16 | 17 | @Override 18 | public int length() { 19 | return value.length(); 20 | } 21 | 22 | @Override 23 | public char charAt(int index) { 24 | return value.charAt(index); 25 | } 26 | 27 | @Override 28 | public CharSequence subSequence(int start, int end) { 29 | return value.subSequence(start, end); 30 | } 31 | 32 | @Override 33 | public boolean contentEquals(CharSequence cs) { 34 | return value.contentEquals(cs.toString()); 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return value; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/Type.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | import java.util.Collection; 7 | 8 | 9 | public class Type extends Documentable { 10 | 11 | private final boolean isInterface; 12 | private final boolean isAbstract; 13 | private final String name; 14 | private final Collection superTypes; 15 | private final Collection annotations; 16 | private final Collection methods; 17 | 18 | public Type(boolean isInterface, boolean isAbstract, String name, Collection superTypes, 19 | String documentation, Collection annotations, Collection methods) { 20 | super(documentation); 21 | this.isInterface = isInterface; 22 | this.isAbstract = isAbstract; 23 | this.name = name; 24 | this.superTypes = superTypes; 25 | this.annotations = annotations; 26 | this.methods = methods; 27 | } 28 | 29 | public boolean isInterface() { 30 | return isInterface; 31 | } 32 | 33 | public boolean isAbstract() { 34 | return isAbstract; 35 | } 36 | 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | public Collection getSuperTypes() { 42 | return superTypes; 43 | } 44 | 45 | public Collection getAnnotations() { 46 | return annotations; 47 | } 48 | 49 | public Collection getMethods() { 50 | return methods; 51 | } 52 | 53 | @Override 54 | public int hashCode() { 55 | int factor = isInterface ? 1 : 31; 56 | return factor * name.hashCode(); 57 | } 58 | 59 | @Override 60 | public boolean equals(Object obj) { 61 | if (!(obj instanceof Type)) { 62 | return false; 63 | } 64 | Type other = (Type)obj; 65 | return isInterface == other.isInterface && name.equals(other.name); 66 | } 67 | 68 | @Override 69 | public String toString() { 70 | return new StringBuilder().append(isInterface ? "interface " : "class ").append(name).toString(); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/extraction/test/TypeBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.extraction.test; 5 | 6 | import java.util.Collection; 7 | import java.util.HashSet; 8 | 9 | 10 | public class TypeBuilder implements Annotatable { 11 | 12 | private final ProjectBuilder parent; 13 | private final boolean isInterface; 14 | private final boolean isAbstract; 15 | private final String name; 16 | private final Collection annotations = new HashSet<>(); 17 | private final Collection methods = new HashSet<>(); 18 | private final Collection superTypes = new HashSet<>(); 19 | private String documentation; 20 | 21 | public TypeBuilder(ProjectBuilder parent, boolean isInterface, boolean isAbstract, String name) { 22 | this.parent = parent; 23 | this.isInterface = isInterface; 24 | this.isAbstract = isAbstract; 25 | this.name = name; 26 | } 27 | 28 | public AnnotationBuilder annotatedWith() { 29 | return new AnnotationBuilder<>(this); 30 | } 31 | 32 | @Override 33 | public TypeBuilder annotateWith(Collection provided) { 34 | this.annotations.addAll(provided); 35 | return this; 36 | } 37 | 38 | public MethodBuilder withMethod(String method) { 39 | return new MethodBuilder(this, method); 40 | } 41 | 42 | public ProjectBuilder end() { 43 | return parent.addType(new Type(isInterface, isAbstract, name, superTypes, documentation, annotations, methods)); 44 | } 45 | 46 | TypeBuilder addMethod(Method method) { 47 | methods.add(method); 48 | return this; 49 | } 50 | 51 | public TypeBuilder derivedFrom(String superType) { 52 | superTypes.add(superType); 53 | return this; 54 | } 55 | 56 | public TypeBuilder documentedWith(String javaDoc) { 57 | this.documentation = javaDoc; 58 | return this; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/generation/spring/ErrorDtoGeneratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.generation.spring; 5 | 6 | import java.util.Arrays; 7 | 8 | import org.junit.Test; 9 | import org.w3c.dom.Document; 10 | 11 | import radl.java.code.JavaCode; 12 | import radl.test.RadlBuilder; 13 | import radl.test.TestUtil; 14 | 15 | 16 | public class ErrorDtoGeneratorTest extends AbstractSpringCodeGeneratorTestCase { 17 | 18 | // #39 Add error conditions to generated API 19 | @Test 20 | public void generatesErrorDtoWhenErrors() { 21 | Document radl = RadlBuilder.aRadlDocument() 22 | .withErrors() 23 | .error(RANDOM.string(12), RANDOM.string(42)) 24 | .end() 25 | .build(); 26 | 27 | JavaCode errorDto = generateType(radl, TYPE_ERROR_DTO); 28 | 29 | TestUtil.assertCollectionEquals("Fields", Arrays.asList("title", "type"), errorDto.fieldNames()); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/java/generation/spring/UrisGeneratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.java.generation.spring; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | import static org.junit.Assert.assertFalse; 8 | import static org.junit.Assert.assertNotNull; 9 | import static org.junit.Assert.assertTrue; 10 | 11 | import java.util.Arrays; 12 | 13 | import org.junit.Test; 14 | import org.w3c.dom.Document; 15 | 16 | import radl.core.code.Code; 17 | import radl.java.code.JavaCode; 18 | import radl.test.RadlBuilder; 19 | import radl.test.TestUtil; 20 | 21 | public class UrisGeneratorTest extends AbstractSpringCodeGeneratorTestCase { 22 | 23 | @Test 24 | public void generatesConstantsForUris() { 25 | String name = aName(); 26 | String billboardUri = aLocalUri(); 27 | String otherUri = aLocalUri(); 28 | Document radl = RadlBuilder.aRadlDocument() 29 | .startingAt(name) 30 | .withResource() 31 | .named(name) 32 | .locatedAt(billboardUri) 33 | .withMethod("GET") 34 | .transitioningTo("Start") 35 | .end() 36 | .end() 37 | .withResource() 38 | .locatedAt(otherUri) 39 | .end() 40 | .build(); 41 | 42 | Iterable sources = radlToCode(radl); 43 | 44 | String field = "URL_BILLBOARD"; 45 | JavaCode api = getType(sources, TYPE_API); 46 | assertFileComments(api); 47 | assertEquals("Fields", Arrays.asList(field).toString(), api.fieldNames().toString()); 48 | assertEquals("Field value #1", quote(billboardUri), api.fieldValue(field)); 49 | 50 | JavaCode uris = getType(sources, TYPE_URIS); 51 | assertFileComments(uris); 52 | assertEquals("# Implementation URIs", 1, uris.fieldNames().size()); 53 | String constant = uris.fieldNames().iterator().next(); 54 | assertTrue("URI constant doesn't fit naming pattern: " + constant, constant.startsWith("URL_")); 55 | assertEquals("URI value", quote(otherUri), uris.fieldValue(constant)); 56 | 57 | JavaCode controller = getType(sources, TestUtil.initCap(name) + "Controller"); 58 | assertFileComments(controller); 59 | assertNotNull("Missing controller", controller); 60 | for (String type : controller.imports()) { 61 | assertFalse("Should not import " + type, type.endsWith("." + TYPE_URIS)); 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/ErrorBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.test; 5 | 6 | import java.util.LinkedHashMap; 7 | import java.util.Map; 8 | 9 | import org.w3c.dom.Document; 10 | 11 | 12 | public class ErrorBuilder { 13 | 14 | private final RadlBuilder parent; 15 | private final Map errors = new LinkedHashMap<>(); 16 | 17 | public ErrorBuilder(RadlBuilder parent) { 18 | this.parent = parent; 19 | } 20 | 21 | public ErrorBuilder error(String name) { 22 | return error(name, null); 23 | } 24 | 25 | public ErrorBuilder error(String name, String documentation) { 26 | return error(name, documentation, Error.UNDEFINED_STATUS_CODE); 27 | } 28 | 29 | public ErrorBuilder error(String name, String documentation, int statusCode) { 30 | errors.put(name, new Error(documentation, statusCode)); 31 | return this; 32 | } 33 | 34 | public ErrorBuilder error(String name, int statusCode) { 35 | return error(name, null, statusCode); 36 | } 37 | 38 | public RadlBuilder end() { 39 | parent.setErrors(errors); 40 | return parent; 41 | } 42 | 43 | public Document build() { 44 | return end().build(); 45 | } 46 | 47 | 48 | public class Error { 49 | 50 | public static final int UNDEFINED_STATUS_CODE = -1; 51 | 52 | private final String documentation; 53 | private final int statusCode; 54 | 55 | public Error(String documentation, int statusCode) { 56 | this.documentation = documentation; 57 | this.statusCode = statusCode; 58 | } 59 | 60 | public String getDocumentation() { 61 | return documentation; 62 | } 63 | 64 | public int getStatusCode() { 65 | return statusCode; 66 | } 67 | 68 | public boolean hasStatusCode() { 69 | return statusCode != UNDEFINED_STATUS_CODE; 70 | } 71 | 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/LinkRelationBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.test; 5 | 6 | import radl.common.xml.DocumentBuilder; 7 | 8 | 9 | public class LinkRelationBuilder { 10 | 11 | private final LinkRelationsBuilder parent; 12 | 13 | public LinkRelationBuilder(LinkRelationsBuilder parent) { 14 | this.parent = parent; 15 | } 16 | 17 | private DocumentBuilder builder() { 18 | return parent.builder(); 19 | } 20 | 21 | public LinkRelationsBuilder end() { 22 | builder().end(); 23 | return parent; 24 | } 25 | 26 | public LinkRelationBuilder implementing(String... transitions) { 27 | builder().element("transitions"); 28 | for (String transition : transitions) { 29 | builder().element("transition") 30 | .attribute("ref", transition) 31 | .end(); 32 | } 33 | builder().end(); 34 | return this; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/LinkRelationsBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.test; 5 | 6 | import org.w3c.dom.Document; 7 | 8 | import radl.common.xml.DocumentBuilder; 9 | 10 | 11 | public class LinkRelationsBuilder { 12 | 13 | private final RadlBuilder parent; 14 | 15 | public LinkRelationsBuilder(RadlBuilder parent) { 16 | this.parent = parent; 17 | builder().element("link-relations"); 18 | } 19 | 20 | DocumentBuilder builder() { 21 | return parent.builder(); 22 | } 23 | 24 | public LinkRelationBuilder withLinkRelation(String name, String specificationUri) { 25 | builder().element("link-relation").attribute("name", name); 26 | if (specificationUri != null) { 27 | builder().element("specification") 28 | .attribute("href", specificationUri) 29 | .end(); 30 | } 31 | return new LinkRelationBuilder(this); 32 | } 33 | 34 | public RadlBuilder end() { 35 | builder().end(); 36 | return parent; 37 | } 38 | 39 | public Document build() { 40 | return end().build(); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/MethodBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.test; 5 | 6 | import radl.common.xml.DocumentBuilder; 7 | 8 | 9 | /** 10 | * Data test builder for RADL methods. 11 | */ 12 | public class MethodBuilder { 13 | 14 | private final ResourceBuilder parent; 15 | 16 | public MethodBuilder(ResourceBuilder parent, String method) { 17 | this.parent = parent; 18 | builder().element("method").attribute("name", method); 19 | } 20 | 21 | public MethodBuilder consuming() { 22 | return message("request"); 23 | } 24 | 25 | private MethodBuilder message(String type) { 26 | builder().element(type).end(); 27 | return this; 28 | } 29 | 30 | public MethodBuilder consuming(String mediaTypeId) { 31 | message("request", mediaTypeId); 32 | return this; 33 | } 34 | 35 | private void message(String type, String mediaTypeId) { 36 | builder().element(type) 37 | .element("representations") 38 | .element("representation") 39 | .attribute("media-type", mediaTypeId) 40 | .end() 41 | .end() 42 | .end(); 43 | } 44 | 45 | private DocumentBuilder builder() { 46 | return parent.builder(); 47 | } 48 | 49 | public MethodBuilder producing() { 50 | return message("response"); 51 | } 52 | 53 | public MethodBuilder producing(String mediaTypeId) { 54 | message("response", mediaTypeId); 55 | return this; 56 | } 57 | 58 | public MethodBuilder and(String method) { 59 | builder().end(); 60 | return new MethodBuilder(parent, method); 61 | } 62 | 63 | public ResourceBuilder end() { 64 | builder().end().end(); 65 | return parent; 66 | } 67 | 68 | public MethodBuilder transitioningTo(String... names) { 69 | builder().element("transitions"); 70 | for (String name : names) { 71 | builder().element("transition") 72 | .attribute("ref", name) 73 | .end(); 74 | } 75 | builder().end(); 76 | return this; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/PropertGroupContainer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.test; 5 | 6 | import radl.common.xml.DocumentBuilder; 7 | 8 | 9 | public interface PropertGroupContainer { 10 | 11 | DocumentBuilder builder(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/PropertyBuilder.java: -------------------------------------------------------------------------------- 1 | package radl.test; 2 | 3 | import radl.common.xml.DocumentBuilder; 4 | 5 | 6 | public class PropertyBuilder { 7 | 8 | private final PropertyGroupBuilder parent; 9 | 10 | public PropertyBuilder(PropertyGroupBuilder parent, String name) { 11 | this.parent = parent; 12 | builder().element("property").attribute("name", name); 13 | } 14 | 15 | DocumentBuilder builder() { 16 | return parent.builder(); 17 | } 18 | 19 | public PropertyGroupBuilder end() { 20 | builder().end(); 21 | return parent; 22 | } 23 | 24 | public PropertyBuilder as(String type) { 25 | builder().attribute("type", type); 26 | return this; 27 | } 28 | 29 | public PropertyBuilder repeating() { 30 | builder().attribute("repeats", "true"); 31 | return this; 32 | } 33 | 34 | public PropertyBuilder meaning(String uri) { 35 | builder().attribute("uri", uri); 36 | return this; 37 | } 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/RandomData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.test; 5 | 6 | import java.security.SecureRandom; 7 | 8 | 9 | /** 10 | * Random pieces of data. Useful for testing, for instance. 11 | */ 12 | public final class RandomData { 13 | 14 | private static final int MIN_STRING_LENGTH = 3; 15 | private static final int MAX_STRING_LENGTH = 64; 16 | private static final int MIN_INTEGER = 0; 17 | private static final int MAX_INTEGER = 1000; 18 | 19 | private final SecureRandom random; 20 | 21 | public RandomData() { 22 | this(new SecureRandom()); 23 | } 24 | 25 | public RandomData(SecureRandom random) { 26 | this.random = random; 27 | } 28 | 29 | public String string() { 30 | return string(integer(MIN_STRING_LENGTH, MAX_STRING_LENGTH)); 31 | } 32 | 33 | public String string(int length) { 34 | StringBuilder result = new StringBuilder(); 35 | for (int i = 0; i < length; i++) { 36 | result.append(lowercaseLetter()); 37 | } 38 | return result.toString(); 39 | } 40 | 41 | public char lowercaseLetter() { 42 | return (char)('a' + integer('z' - 'a' + 1)); 43 | } 44 | 45 | public int integer() { 46 | return integer(MAX_INTEGER); 47 | } 48 | 49 | public int integer(int max) { 50 | return integer(MIN_INTEGER, max); 51 | } 52 | 53 | public int integer(int min, int max) { 54 | ensureMinMax(min, max); 55 | return min + random.nextInt(max - min); 56 | } 57 | 58 | private void ensureMinMax(int min, int max) { 59 | if (min >= max) { 60 | throw new IllegalArgumentException(String.format("Min (%d) must be less than max (%d)", min, max)); 61 | } 62 | } 63 | 64 | public boolean logical() { 65 | return logical(50); 66 | } 67 | 68 | public boolean logical(int percent) { 69 | ensureMinMax(0, percent); 70 | ensureMinMax(percent, 101); 71 | return integer(100) < percent; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/ResourceBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.test; 5 | 6 | import radl.common.xml.DocumentBuilder; 7 | 8 | 9 | /** 10 | * Data test builder for RADL resources. 11 | */ 12 | public class ResourceBuilder { 13 | 14 | private final RadlBuilder parent; 15 | 16 | public ResourceBuilder(RadlBuilder parent) { 17 | this.parent = parent; 18 | if (!"resources".equals(builder().getCurrent().getLocalName())) { 19 | builder().element("resources"); 20 | } 21 | builder().element("resource"); 22 | } 23 | 24 | DocumentBuilder builder() { 25 | return parent.builder(); 26 | } 27 | 28 | public RadlBuilder parent() { 29 | return parent; 30 | } 31 | 32 | public MethodBuilder withMethod(String method) { 33 | ensureName(); 34 | ensureMethods(); 35 | return new MethodBuilder(this, method); 36 | } 37 | 38 | private void ensureName() { 39 | if ("resource".equals(builder().getCurrent().getLocalName()) 40 | && builder().getCurrent().getAttributes().getNamedItemNS(null, "name") == null) { 41 | named(parent.aName()); 42 | } 43 | } 44 | 45 | public ResourceBuilder named(String name) { 46 | builder().attribute("name", name); 47 | return this; 48 | } 49 | 50 | private DocumentBuilder ensureMethods() { 51 | if (!"methods".equals(builder().getCurrent().getLocalName())) { 52 | return builder().element("methods"); 53 | } 54 | return builder(); 55 | } 56 | 57 | public ResourceBuilder locatedAt(String uri) { 58 | return located("uri", uri); 59 | } 60 | 61 | private ResourceBuilder located(String attribute, String uri) { 62 | ensureName(); 63 | builder().element("location").attribute(attribute, uri).end(); 64 | return this; 65 | } 66 | 67 | public ResourceBuilder locatedAtTemplate(String uriTemplate) { 68 | return located("uri-template", uriTemplate); 69 | } 70 | 71 | public RadlBuilder end() { 72 | ensureName(); 73 | builder().end(); 74 | return parent; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/StateBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.test; 5 | 6 | import radl.common.xml.DocumentBuilder; 7 | 8 | 9 | public class StateBuilder { 10 | 11 | private final StatesBuilder parent; 12 | 13 | public StateBuilder(StatesBuilder parent) { 14 | this.parent = parent; 15 | } 16 | 17 | DocumentBuilder builder() { 18 | return parent.builder(); 19 | } 20 | 21 | public StatesBuilder end() { 22 | while (!"states".equals(builder().getCurrent().getLocalName())) { 23 | builder().end(); 24 | } 25 | return parent; 26 | } 27 | 28 | public StateBuilder transitioningTo(String name, String state) { 29 | return withTransition(name, state).end(); 30 | } 31 | 32 | public TransitionBuilder withTransition(String name, String state) { 33 | if (!"transitions".equals(builder().getCurrent().getLocalName())) { 34 | builder().element("transitions"); 35 | } 36 | return new TransitionBuilder(this, name, state); 37 | } 38 | 39 | public StateBuilder containing(String propertyGroup) { 40 | builder().attribute("property-group", propertyGroup); 41 | return this; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/StatesBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.test; 5 | 6 | import radl.common.xml.DocumentBuilder; 7 | 8 | 9 | public class StatesBuilder { 10 | 11 | private final RadlBuilder parent; 12 | 13 | public StatesBuilder(RadlBuilder parent) { 14 | this.parent = parent; 15 | builder().element("states"); 16 | } 17 | 18 | DocumentBuilder builder() { 19 | return parent.builder(); 20 | } 21 | 22 | public StatesBuilder startingAt(String state) { 23 | builder().element("start-state"); 24 | return new StateBuilder(this) 25 | .transitioningTo("Start", state) 26 | .end(); 27 | } 28 | 29 | public StateBuilder withState(String name) { 30 | builder().element("state").attribute("name", name); 31 | return new StateBuilder(this); 32 | } 33 | 34 | public RadlBuilder end() { 35 | builder().end(); 36 | return parent; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/TestUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.test; 5 | 6 | import static org.junit.Assert.assertTrue; 7 | 8 | import java.io.File; 9 | import java.util.ArrayList; 10 | import java.util.Collection; 11 | import java.util.Iterator; 12 | 13 | import org.junit.Assert; 14 | import org.w3c.dom.Document; 15 | 16 | import radl.common.xml.Xml; 17 | 18 | 19 | /** 20 | * Utility methods for use in tests. 21 | */ 22 | public final class TestUtil { 23 | 24 | private static final RandomData RANDOM = new RandomData(); 25 | 26 | private TestUtil() { 27 | // Utility class 28 | } 29 | 30 | public static void assertCollectionEquals(String message, Iterable expected, Iterable actual) { 31 | Iterator expectedItems = expected.iterator(); 32 | Iterator actualItems = actual.iterator(); 33 | while (expectedItems.hasNext()) { 34 | T expectedItem = expectedItems.next(); 35 | assertTrue(message + ": missing item '" + expectedItem + "', got " + actual, actualItems.hasNext()); 36 | 37 | T actualItem = actualItems.next(); 38 | if (!expectedItem.equals(actualItem)) { 39 | Assert.assertEquals(message + ": incorrect item", expectedItem.toString(), actualItem.toString()); 40 | } 41 | } 42 | if (actualItems.hasNext()) { 43 | Collection extraItems = new ArrayList<>(); 44 | while (actualItems.hasNext()) { 45 | extraItems.add(actualItems.next()); 46 | } 47 | Assert.assertEquals("Extra item(s)", "", extraItems.toString()); 48 | } 49 | } 50 | 51 | public static void assertXmlEquals(String message, Document expected, Document actual) { 52 | Assert.assertEquals(message, Xml.toString(expected), Xml.toString(actual)); 53 | } 54 | 55 | public static String initCap(String text) { 56 | return Character.toUpperCase(text.charAt(0)) + text.substring(1); 57 | } 58 | 59 | public static File randomDir(Class caller) { 60 | String name = caller.getSimpleName(); 61 | if (name.endsWith("Test")) { 62 | name = name.substring(0, name.length() - 4); 63 | } 64 | File result = new File("build/" + name); 65 | result.mkdirs(); 66 | return result; 67 | } 68 | 69 | public static File randomFile(Class caller, String extension) { 70 | return new File(randomDir(caller), RANDOM.string(8) + extension); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /java/core/src/test/java/radl/test/TransitionBuilder.java: -------------------------------------------------------------------------------- 1 | package radl.test; 2 | 3 | import radl.common.xml.DocumentBuilder; 4 | 5 | public class TransitionBuilder { 6 | 7 | private final StateBuilder parent; 8 | 9 | public TransitionBuilder(StateBuilder parent, String name, String state) { 10 | this.parent = parent; 11 | builder().element("transition") 12 | .attribute("name", name) 13 | .attribute("to", state); 14 | } 15 | 16 | private DocumentBuilder builder() { 17 | return parent.builder(); 18 | } 19 | 20 | public StateBuilder end() { 21 | builder().end(); 22 | return parent; 23 | } 24 | 25 | public TransitionBuilder withInput(String propertyGroup) { 26 | builder().element("input").attribute("property-group", propertyGroup).end(); 27 | return this; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /java/core/src/test/resources/META-INF/services/radl.core.validation.IssueReporter: -------------------------------------------------------------------------------- 1 | radl.core.validation.TestIssueReporter 2 | radl.core.validation.CheckStyleIssueReporter 3 | -------------------------------------------------------------------------------- /java/core/src/test/resources/radl/core/documentation/radl-test.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin:0; 3 | padding:0 0 0 16em; 4 | } 5 | 6 | h1, 7 | h2{ 8 | color:goldenrod; 9 | } 10 | h3{ 11 | color:purple; 12 | } 13 | 14 | table{ 15 | border-collapse:collapse; 16 | margin-bottom:1em; 17 | width:90% 18 | } 19 | th, 20 | td{ 21 | border:1px solid; 22 | padding:0.35em; 23 | vertical-align:top; 24 | } 25 | th{ 26 | color:White; 27 | background-color:CornflowerBlue; 28 | text-align:left; 29 | border-color:Navy; 30 | } 31 | td{ 32 | border-color:LightGrey; 33 | vertical-align:middle; 34 | } 35 | tr:nth-child(odd){ 36 | background-color:#eeeeef; 37 | padding:16px; 38 | } 39 | 40 | dl{ 41 | margin:16px; 42 | } 43 | dl dl{ 44 | background-color:#eeeeef; 45 | padding:12px; 46 | } 47 | 48 | dt{ 49 | font-weight:bold; 50 | padding-top:9px; 51 | } 52 | dt::after{ 53 | content:":"; 54 | } 55 | dd{ 56 | margin:0; 57 | padding-left:16px; 58 | } 59 | div.nested{ 60 | margin:0; 61 | padding-left:16px; 62 | } 63 | 64 | li.transition{ 65 | list-style-type:none; 66 | } 67 | 68 | .outline{ 69 | vertical-align:top; 70 | padding:1em; 71 | } 72 | .index{ 73 | position:fixed; 74 | top:0; 75 | left:0; 76 | width:16em; 77 | height:100%; 78 | font-size:smaller; 79 | } 80 | .reference{ 81 | height:100%; 82 | } 83 | .buggy{ 84 | background-color:yellow; 85 | } 86 | .http{ 87 | border-radius:2px; 88 | color:white; 89 | display:inline-block; 90 | font-size:0.7em; 91 | padding:7px 0 4px; 92 | text-align:center; 93 | width:50px; 94 | } 95 | .http a{ 96 | color:white; 97 | } 98 | .DELETE{ 99 | background-color:blue; 100 | } 101 | .GET{ 102 | background-color:red; 103 | } 104 | .PATCH{ 105 | background-color:green; 106 | } 107 | .POST{ 108 | background-color:orange; 109 | } 110 | .PUT{ 111 | background-color:deeppink; 112 | } 113 | code{ 114 | background:none repeat scroll 0 0 #f5f5f5; 115 | border:1px solid #ccc; 116 | border-radius:2px; 117 | padding:1px 3px; 118 | } -------------------------------------------------------------------------------- /java/core/src/test/resources/radl/core/xml/sample-part1.radl: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /java/core/src/test/resources/radl/core/xml/sample-part2.radl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | You start interacting with the API via the billboard URI, which is the URI at which the service implementing the API is deployed. This URI varies from deployment to deployment and should be provided to you separately from this documentation. 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Ask the XACML PDP to decide whether access should be granted. You have to provide the XACML request context. 17 | 18 | 19 | 20 | 21 | 22 | 23 | The PDP returns with the XACML response context. 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /java/core/src/test/resources/radl/core/xml/sample-part3.radl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /java/core/src/test/resources/radl/core/xml/sample-part4.radl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /java/core/src/test/resources/radl/core/xml/sample-part5.radl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /java/eclipse/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 Export-Package: radl.eclipse.builder;version="0.5.0.SNAPSHOT";uses:="org.eclipse.core.resources,org.eclipse.core.runtime", radl.eclipse.wizards;version="0.5.0.SNAPSHOT"; uses:="org.eclipse.core.resources, org.eclipse.core.runtime, org.eclipse.jface.viewers, org.eclipse.jface.wizard, org.eclipse.swt.widgets, org.eclipse.ui" Bundle-Name: RADL Eclipse Plug-in Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Require-Bundle: org.eclipse.core.resources,org.eclipse.core.runtime,or g.eclipse.jdt.core,org.eclipse.ui,org.eclipse.ui.ide,org.eclipse.jdt. launching,org.eclipse.jdt.ui,org.eclipse.jface.text,org.eclipse.ui.ed itors Bundle-Vendor: RADL Bundle-Version: 0.9.13 Bundle-ManifestVersion: 2 Bundle-SymbolicName: radl.eclipse; singleton:=true Import-Package: org.eclipse.core.resources,org.eclipse.core.runtime;ve rsion="[3.4,4)";common=split,org.eclipse.jface.dialogs,org.eclipse.jf ace.operation,org.eclipse.jface.viewers,org.eclipse.jface.wizard,org. eclipse.swt.events,org.eclipse.swt.layout,org.eclipse.swt.widgets,org .eclipse.ui,org.eclipse.ui.dialogs,org.eclipse.ui.ide,org.xml.sax.hel pers,org.eclipse.swt,org.xml.sax,javax.xml.parsers -------------------------------------------------------------------------------- /java/eclipse/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/main/java/, src/test/java/ 2 | output.. = classes/ 3 | bin.includes = plugin.xml, META-INF/, . -------------------------------------------------------------------------------- /java/eclipse/gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) EMC Corporation. All rights reserved. 3 | # 4 | 5 | version = 2.0.2 6 | alternateDistribution = true 7 | -------------------------------------------------------------------------------- /java/eclipse/icons/api.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/icons/api.gif -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.core.commands_3.6.0.I20100512-1500.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.core.commands_3.6.0.I20100512-1500.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.core.contenttype_3.4.100.v20100505-1235.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.core.contenttype_3.4.100.v20100505-1235.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.core.databinding.observable_1.3.0.I20100601-0800.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.core.databinding.observable_1.3.0.I20100601-0800.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.core.databinding.property_1.3.0.I20100601-0800.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.core.databinding.property_1.3.0.I20100601-0800.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.core.databinding_1.3.100.I20100601-0800.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.core.databinding_1.3.100.I20100601-0800.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.core.expressions_3.4.200.v20100505.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.core.expressions_3.4.200.v20100505.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.core.filesystem_1.3.0.v20100526-0737.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.core.filesystem_1.3.0.v20100526-0737.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.core.jobs_3.5.0.v20100515.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.core.jobs_3.5.0.v20100515.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.core.resources_3.6.0.v20100526-0737.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.core.resources_3.6.0.v20100526-0737.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.core.runtime_3.6.0.v20100505.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.core.runtime_3.6.0.v20100505.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.equinox.app_1.3.0.v20100512.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.equinox.app_1.3.0.v20100512.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.equinox.common_3.6.0.v20100503.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.equinox.common_3.6.0.v20100503.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.equinox.preferences_3.3.0.v20100503.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.equinox.preferences_3.3.0.v20100503.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.equinox.registry_3.5.0.v20100503.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.equinox.registry_3.5.0.v20100503.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.help_3.5.0.v20100524.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.help_3.5.0.v20100524.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.jdt.core_3.6.0.xx-20100630-0900-e36.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.jdt.core_3.6.0.xx-20100630-0900-e36.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.jdt.launching_3.5.100.v20100526.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.jdt.launching_3.5.100.v20100526.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.jdt.ui_3.6.1.r361_v20100825-0800.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.jdt.ui_3.6.1.r361_v20100825-0800.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.jface.databinding_1.4.0.I20100601-0800.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.jface.databinding_1.4.0.I20100601-0800.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.jface.text_3.6.1.r361_v20100825-0800.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.jface.text_3.6.1.r361_v20100825-0800.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.jface_3.6.1.M20100825-0800.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.jface_3.6.1.M20100825-0800.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.ltk.core.refactoring_3.5.200.v20110505-0800.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.ltk.core.refactoring_3.5.200.v20110505-0800.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.osgi_3.6.0.v20100517.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.osgi_3.6.0.v20100517.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.swt.win32.win32.x86_3.6.0.v3650b.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.swt.win32.win32.x86_3.6.0.v3650b.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.swt_3.6.0.v3650b.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.swt_3.6.0.v3650b.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.text_3.5.0.v20100601-1300.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.text_3.5.0.v20100601-1300.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.ui.ide_3.6.0.I20100601-0800.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.ui.ide_3.6.0.I20100601-0800.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.ui.workbench_3.6.0.I20100603-1100.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.ui.workbench_3.6.0.I20100603-1100.jar -------------------------------------------------------------------------------- /java/eclipse/lib/eclipse/org.eclipse.ui_3.6.0.I20100603-1100.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/java/eclipse/lib/eclipse/org.eclipse.ui_3.6.0.I20100603-1100.jar -------------------------------------------------------------------------------- /java/eclipse/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 11 | 13 | 14 | 15 | 16 | 20 | 21 | 23 | 24 | 25 | 27 | 28 | 29 | 33 | 35 | 36 | 38 | 39 | 40 | 42 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /java/eclipse/src/main/java/radl/eclipse/builder/RadlBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.eclipse.builder; 5 | 6 | import java.util.Map; 7 | 8 | import org.eclipse.core.resources.IProject; 9 | import org.eclipse.core.resources.IResource; 10 | import org.eclipse.core.resources.IResourceDelta; 11 | import org.eclipse.core.resources.IncrementalProjectBuilder; 12 | import org.eclipse.core.runtime.CoreException; 13 | import org.eclipse.core.runtime.IProgressMonitor; 14 | 15 | import radl.core.validation.CompositeValidator; 16 | import radl.core.validation.LintValidator; 17 | import radl.core.validation.RelaxNgValidator; 18 | import radl.core.validation.Validator; 19 | 20 | 21 | /** 22 | * Project builder that validates RADL documents. 23 | */ 24 | public class RadlBuilder extends IncrementalProjectBuilder { 25 | 26 | public static final String BUILDER_ID = "radl.eclipse.radlBuilder"; 27 | 28 | private final RadlValidatingVisitor radlValidatingVisitor; 29 | 30 | public RadlBuilder() { 31 | this(new CompositeValidator(new RelaxNgValidator(), new LintValidator())); 32 | } 33 | 34 | RadlBuilder(Validator validator) { 35 | radlValidatingVisitor = new RadlValidatingVisitor(validator); 36 | } 37 | 38 | @Override 39 | protected IProject[] build(int kind, @SuppressWarnings("rawtypes") Map args, IProgressMonitor monitor) 40 | throws CoreException { 41 | if (kind == FULL_BUILD) { 42 | fullBuild(); 43 | } else { 44 | IResourceDelta delta = getDelta(getProject()); 45 | if (delta == null) { 46 | fullBuild(); 47 | } else { 48 | incrementalBuild(delta); 49 | } 50 | } 51 | return new IProject[0]; 52 | } 53 | 54 | @Override 55 | protected void clean(IProgressMonitor monitor) throws CoreException { 56 | getProject().deleteMarkers(RadlValidatingVisitor.MARKER_TYPE, true, IResource.DEPTH_INFINITE); 57 | } 58 | 59 | private void fullBuild() throws CoreException { 60 | getProject().accept(radlValidatingVisitor); 61 | } 62 | 63 | private void incrementalBuild(IResourceDelta delta) throws CoreException { 64 | delta.accept(radlValidatingVisitor); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /java/gradle/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'groovy' 2 | 3 | dependencies { 4 | compile gradleApi(), localGroovy(), project(':java:core') 5 | } 6 | -------------------------------------------------------------------------------- /java/gradle/gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) EMC Corporation. All rights reserved. 3 | # 4 | 5 | version = 3.0.2 6 | -------------------------------------------------------------------------------- /java/gradle/src/main/groovy/radl/gradle/RadlExtension.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © EMC Corporation. All rights reserved. 3 | */ 4 | package radl.gradle 5 | 6 | 7 | /** 8 | * Gradle extension for RADL specific properties. 9 | */ 10 | class RadlExtension { 11 | 12 | def coreVersion = '1.0.22' 13 | def dirName = 'src/main/radl' 14 | def serviceName 15 | def packagePrefix 16 | def docsDir = 'docs/rest' 17 | def extraSourceDir 18 | def extraClasspath 19 | def skipClasspath = false 20 | def extraProcessors 21 | def keepArgumentsFile = false 22 | def scm = 'default' 23 | def header = 'Generated by RADL.' 24 | def serializeModel = false 25 | def cssUrl 26 | 27 | def preExtracts = [] 28 | def preExtract(clos) { 29 | preExtracts += clos 30 | } 31 | 32 | def generateDirName 33 | def generateSpring = false 34 | def springVersion = '4.2.3.RELEASE' 35 | 36 | } 37 | -------------------------------------------------------------------------------- /java/gradle/src/main/resources/META-INF/gradle-plugins/radl-gradle.properties: -------------------------------------------------------------------------------- 1 | implementation-class=radl.gradle.RadlPlugin 2 | -------------------------------------------------------------------------------- /java/maven/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | 5 | apply plugin: 'maven' 6 | 7 | dependencies { 8 | compile project(':java:core'), 9 | 'org.apache.maven:maven-plugin-api:2.0', 10 | 'org.apache.maven:maven-ant-tasks:2.1.3', 11 | 'org.apache.maven.plugin-tools:maven-plugin-annotations:3.2', 12 | 'org.codehaus.plexus:plexus-utils:3.0.8' 13 | } 14 | 15 | def archiveBase = "radl-$project.name" 16 | 17 | task createPom4Plugin << { 18 | pom { 19 | project { 20 | groupId 'radl' 21 | artifactId archiveBase 22 | version project.version 23 | 24 | inceptionYear '2015' 25 | licenses { 26 | license { 27 | name 'The Apache Software License, Version 2.0' 28 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 29 | distribution 'repo' 30 | } 31 | } 32 | } 33 | whenConfigured { pom -> 34 | pom.dependencies.findAll { it.groupId == 'RADL.java' }.each { dep -> 35 | dep.groupId = 'radl' 36 | dep.artifactId = "radl-$dep.artifactId" 37 | } 38 | } 39 | }.writeTo("$buildDir/resources/main/META-INF/maven/radl/radl-maven/pom.xml") 40 | } 41 | 42 | processResources { 43 | filesMatching('**/plugin*.xml') { 44 | filter { 45 | it.replace('@radl-maven-version@', project.property('version')) 46 | } 47 | filter { 48 | Properties coreProps = new Properties() 49 | coreProps.load(new FileInputStream("$rootDir/java/core/gradle.properties")) 50 | it.replace('@radl-core-version@', coreProps.getProperty('version')) 51 | } 52 | } 53 | } 54 | 55 | assemble.dependsOn createPom4Plugin, processResources -------------------------------------------------------------------------------- /java/maven/gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) EMC Corporation. All rights reserved. 3 | # 4 | 5 | version = 2.0.2 -------------------------------------------------------------------------------- /java/maven/src/main/java/radl/maven/MavenConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | 5 | package radl.maven; 6 | 7 | /** 8 | * Maven plugin configuration parameters 9 | */ 10 | public interface MavenConfig { 11 | 12 | String RADL_DIR_NAME = "radlDirName"; 13 | String RADL_DIR_NAME_DEFAULT = "${project.basedir}/src/main/radl"; 14 | 15 | String DOCS_DIR = "docsDir"; 16 | String DOCS_DIR_DEFAULT = "${project.build.directory}/radl"; 17 | 18 | String ISSUE_FILE = "issueFile"; 19 | String ISSUE_FILE_DEFAULT = DOCS_DIR_DEFAULT + "/radl-issues.xml"; 20 | 21 | String BASE_DIR = "baseDir"; 22 | String BASE_DIR_DEFAULT = "${project.basedir}"; 23 | 24 | String PACKAGE_PREFIX = "packagePrefix"; 25 | String PACKAGE_PREFIX_DEFAULT = "radl.sample.rest.server"; 26 | 27 | String FAIL_ON_VALIDATION_ERRORS = "failOnValidationErrors"; 28 | String FAIL_ON_VALIDATION_ERRORS_DEFAULT = "true"; 29 | 30 | String SRC_SET_DIR = "srcDir"; 31 | String SRC_SET_DIR_DEFAULT = "${project.basedir}/src/main/java"; 32 | 33 | String REL_GEN_SRC_DIR = "relativeGeneratedSourceDir"; 34 | String REL_GEN_SRC_DIR_DEFAULT = "${project.build.directory}/generated-src/java"; 35 | 36 | String REL_GEN_MAN_SRC_DIR = "relativeGeneratedManualSourceDir"; 37 | String REL_GEN_MAN_SRC_DIR_DEFAULT = "${project.build.directory}/generated-src/manual"; 38 | 39 | String SERVICE_NAME = "serviceName"; 40 | String SERVICE_NAME_DEFAULT = "${project.name}"; 41 | 42 | String CSS_URL_NAME = "cssURL"; 43 | String CSS_URL_DEFAULT = ""; 44 | 45 | String HIDE_LOCATION_NAME = "hideLocation"; 46 | String HIDE_LOCATION_DEFAULT = "false"; 47 | 48 | String SCM = "scm"; 49 | String SCM_DEFAULT = "default"; 50 | 51 | String CLASSPATH_SCOPE = "classpathScope"; 52 | String CLASSPATH_SCOPE_DEFAULT = "runtime"; 53 | 54 | String EX_CLASSPATH = "extraClasspath"; 55 | String EX_CLASSPATH_DEFAULT = ""; 56 | 57 | String EX_PROCESSORS = "extraProcessors"; 58 | String EX_PROCESSORS_DEFAULT = ""; 59 | 60 | String HEADER = "header"; 61 | String HEADER_DEFAULT = "Generated by RADL"; 62 | 63 | String KEEP_ARGS_FILE = "keepArgumentsFile"; 64 | String KEEP_ARGS_FILE_DEFAULT = "false"; 65 | 66 | String PRE_EXTRACT = "preExtract"; 67 | String PRE_EXTRACT_DEFAULT = "false"; 68 | 69 | String RADL_CORE_VERSION = "radlCoreVersion"; 70 | String RADL_CORE_VERSION_DEFAULT = ""; 71 | 72 | String SKIP_CLASSPATH = "skipClasspath"; 73 | String SKIP_CLASSPATH_DEFAULT = "false"; 74 | } 75 | -------------------------------------------------------------------------------- /java/maven/src/main/java/radl/maven/util/RadlFileUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | 5 | package radl.maven.util; 6 | 7 | import java.io.File; 8 | import java.io.FilenameFilter; 9 | 10 | import org.apache.maven.plugin.MojoFailureException; 11 | 12 | 13 | /** 14 | * An utility to process RADL files. 15 | */ 16 | public final class RadlFileUtil { 17 | 18 | private static final String RADL_EXT = ".radl"; 19 | 20 | private RadlFileUtil() { 21 | } 22 | 23 | public static File findRadlFile(File dir, String suggestedName) 24 | throws MojoFailureException { 25 | if (dir == null || !dir.isDirectory()) { 26 | throw new MojoFailureException("The RADL directory is incorrect: " + dir); 27 | } 28 | File radlFile = new File(dir, suggestedName + RADL_EXT); 29 | if (!radlFile.exists()) { 30 | // Iterate to find a first .radl file 31 | File[] files = dir.listFiles(new FilenameFilter() { 32 | @Override 33 | public boolean accept(File ignored, String name) { 34 | return name.endsWith(RADL_EXT); 35 | } 36 | }); 37 | if (files != null && files.length > 0) { 38 | radlFile = files[0]; 39 | } 40 | } 41 | if (!radlFile.exists()) { 42 | throw new MojoFailureException("No RADL files (.radl) are found under directory: " + dir); 43 | } 44 | return radlFile; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restful-api-description-language/RADL/9d42c7a46456f856dc4f1370e2204839556c029d/logo.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) EMC Corporation. All rights reserved. 3 | */ 4 | 5 | rootProject.name = 'RADL' 6 | 7 | include 'java:core' 8 | include 'java:gradle' 9 | include 'java:eclipse' 10 | include 'java:maven' 11 | -------------------------------------------------------------------------------- /specification/schema/documentation.rnc: -------------------------------------------------------------------------------- 1 | namespace html = "http://www.w3.org/1999/xhtml" 2 | 3 | ## 4 | ## Copyright © EMC Corporation. All rights reserved. 5 | ## 6 | 7 | documentation = element documentation { inline?, doc-title?, html } 8 | inline = attribute inline { "true" | "false" } 9 | doc-title = element title { text } 10 | html = html-content* 11 | html-content = html-element | text | ref 12 | html-element = element html:* { html-attribute*, html-content* } 13 | html-attribute = attribute * { text? } 14 | -------------------------------------------------------------------------------- /specification/schema/ref.rnc: -------------------------------------------------------------------------------- 1 | datatypes xsd = "http://www.w3.org/2001/XMLSchema-datatypes" 2 | 3 | ## 4 | ## Copyright © EMC Corporation. All rights reserved. 5 | ## 6 | 7 | # ref elements are used in the documentation modules 8 | ref = 9 | element ref { 10 | ((attribute idref { xsd:string } 11 | | attribute uri { xsd:anyURI } 12 | | attribute media-type { xsd:string } 13 | | attribute header { xsd:string } 14 | | attribute mechanism { xsd:string } 15 | | attribute identity-provider { xsd:string } 16 | | attribute scheme { xsd:string } 17 | | attribute scheme-parameter { xsd:string } 18 | | attribute status-code { xsd:string } 19 | | attribute uri-parameter { xsd:string } 20 | | attribute resources { xsd:string } 21 | | attribute resource { xsd:string } 22 | | attribute var { xsd:string } 23 | | attribute property { xsd:string } 24 | | attribute header { xsd:string } 25 | | attribute method { xsd:string }), 26 | text?) 27 | # Uses the name of the referred item if not provided 28 | 29 | } 30 | -------------------------------------------------------------------------------- /specification/tests/README.md: -------------------------------------------------------------------------------- 1 | This directory contains acceptance tests for core RADL functionality: 2 | 3 | - The `validation` directory contains instances that demonstrate our validation beyond the schema 4 | - The `documentation` directory contains tests that demonstrate our documentation generation 5 | -------------------------------------------------------------------------------- /specification/tests/documentation/linksToMediaTypeSpecification/instance.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /specification/tests/documentation/linksToMediaTypeSpecification/test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | http://baz.com/gnu.html 4 |