From 0d620d926fba7707fd53f577f77f075a5543d946 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Thu, 27 Mar 2014 19:43:58 +0100 Subject: [PATCH] Initial Code Contribution - CQ 7916 --- .gitattributes | 1 + .gitignore | 12 + LICENSE-ASL.txt | 202 +++ LICENSE-EPL.txt | 227 +++ README.md | 164 ++ notice.html | 108 ++ org.eclipse.winery.common/.gitignore | 14 + org.eclipse.winery.common/about.html | 143 ++ .../about_files/Apache-LICENSE-2.0.txt | 202 +++ .../about_files/CDDL-v1.1.txt | 129 ++ .../about_files/LICENSE-logback.txt | 15 + .../about_files/LICENSE-slf4j-api.txt | 21 + org.eclipse.winery.common/pom.xml | 90 + .../sonar-project.properties | 24 + .../src/main/java/META-INF/MANIFEST.MF | 3 + .../eclipse/winery/common/ModelUtilities.java | 554 +++++++ .../common/RepositoryFileReference.java | 84 + .../common/StringEncodedAndDecoded.java | 88 + .../common/TOSCADocumentBuilderFactory.java | 73 + .../java/org/eclipse/winery/common/Util.java | 570 +++++++ .../common/beans/NamespaceIdOptionalName.java | 57 + .../winery/common/constants/Defaults.java | 25 + .../winery/common/constants/MimeTypes.java | 26 + .../winery/common/constants/Namespaces.java | 27 + .../winery/common/constants/QNames.java | 23 + .../eclipse/winery/common/ids/GenericId.java | 56 + .../eclipse/winery/common/ids/IdNames.java | 31 + .../org/eclipse/winery/common/ids/IdUtil.java | 104 ++ .../eclipse/winery/common/ids/Namespace.java | 22 + .../org/eclipse/winery/common/ids/XMLId.java | 32 + .../ids/definitions/ArtifactTemplateId.java | 32 + .../ids/definitions/ArtifactTypeId.java | 33 + .../ids/definitions/CapabilityTypeId.java | 33 + .../ids/definitions/EntityTemplateId.java | 41 + .../common/ids/definitions/EntityTypeId.java | 33 + .../EntityTypeImplementationId.java | 26 + .../common/ids/definitions/NodeTypeId.java | 33 + .../definitions/NodeTypeImplementationId.java | 26 + .../ids/definitions/PolicyTemplateId.java | 32 + .../common/ids/definitions/PolicyTypeId.java | 33 + .../ids/definitions/RelationshipTypeId.java | 32 + .../RelationshipTypeImplementationId.java | 26 + .../ids/definitions/RequirementTypeId.java | 32 + .../ids/definitions/ServiceTemplateId.java | 33 + .../ids/definitions/TOSCAComponentId.java | 116 ++ .../TopologyGraphElementEntityTypeId.java | 36 + .../definitions/imports/GenericImportId.java | 64 + .../ids/definitions/imports/XSDImportId.java | 36 + .../common/ids/definitions/package-info.java | 17 + .../winery/common/ids/elements/PlanId.java | 22 + .../winery/common/ids/elements/PlansId.java | 28 + .../common/ids/elements/TOSCAElementId.java | 77 + .../common/ids/elements/package-info.java | 17 + .../common/interfaces/IWineryRepository.java | 140 ++ .../interfaces/IWineryRepositoryCommon.java | 42 + .../QNameAlreadyExistsException.java | 18 + .../common/interfaces/QNameWithName.java | 24 + .../PropertyDefinitionKV.java | 59 + .../PropertyDefinitionKVList.java | 31 + .../WinerysPropertiesDefinition.java | 77 + .../propertydefinitionkv/package-info.java | 29 + .../src/test/java/.gitkeep | 0 .../src/test/java/META-INF/MANIFEST.MF | 3 + .../winery/common/ModelUtilitiesTest.java | 13 + .../org/eclipse/winery/common/TestUtil.java | 48 + org.eclipse.winery.generators.ia/.gitignore | 9 + org.eclipse.winery.generators.ia/about.html | 155 ++ .../about_files/Apache-LICENSE-2.0.txt | 202 +++ .../about_files/CDDL-v1.1.txt | 129 ++ .../about_files/LICENSE-logback.txt | 15 + .../about_files/LICENSE-slf4j-api.txt | 21 + org.eclipse.winery.generators.ia/pom.xml | 103 ++ .../winery/generators/ia/Generator.java | 387 +++++ .../java/AbstractIAService.java.template | 82 + .../java/TemplateService.java.template | 16 + .../resources/template/project/README.txt | 61 + .../main/resources/template/project/pom.xml | 251 +++ .../project/src/main/webapp/WEB-INF/beans.xml | 16 + .../project/src/main/webapp/WEB-INF/web.xml | 33 + .../src/test/java/META-INF/MANIFEST.MF | 3 + .../eclipse/winery/generators/ia/Test.java | 148 ++ .../.gitignore | 14 + .../de.loskutov.anyedit.AnyEditTools.prefs | 16 + .../README.md | 5 + .../about.html | 286 ++++ .../about_files/Apache-LICENSE-2.0.txt | 202 +++ .../about_files/CDDL-v1.1.txt | 129 ++ .../about_files/LICENSE-logback.txt | 15 + .../about_files/LICENSE-slf4j-api.txt | 21 + org.eclipse.winery.repository.client/pom.xml | 160 ++ .../src/main/java/META-INF/MANIFEST.MF | 3 + .../client/IWineryRepositoryClient.java | 69 + .../client/WineryRepositoryClient.java | 746 +++++++++ .../client/WineryRepositoryClientFactory.java | 20 + .../src/test/java/META-INF/MANIFEST.MF | 3 + .../client/TestWineryRepositoryClient.java | 144 ++ org.eclipse.winery.repository/.bowerrc | 3 + org.eclipse.winery.repository/.gitattributes | 6 + org.eclipse.winery.repository/.gitignore | 23 + .../de.loskutov.anyedit.AnyEditTools.prefs | 16 + org.eclipse.winery.repository/README.md | 59 + org.eclipse.winery.repository/about.html | 1037 ++++++++++++ .../about_files/Apache-LICENSE-2.0.txt | 202 +++ .../about_files/CDDL-v1.1.txt | 129 ++ .../about_files/EDL.txt | 13 + .../about_files/LICENSE-ASM.txt | 29 + .../about_files/LICENSE-JSch.txt | 30 + .../about_files/LICENSE-KeyboardJS.txt | 25 + .../about_files/LICENSE-XMLWriter.txt | 27 + .../about_files/LICENSE-biltong.txt | 22 + .../about_files/LICENSE-boostrap.txt | 21 + .../about_files/LICENSE-bootstrap-switch.txt | 176 ++ .../LICENSE-bootstrap3-wysihtml5-bower.txt | 9 + .../about_files/LICENSE-colorPicker.txt | 22 + .../about_files/LICENSE-datatables.txt | 10 + .../about_files/LICENSE-handlebars.txt | 19 + .../about_files/LICENSE-jQuery-UI.txt | 26 + .../about_files/LICENSE-jQuery.txt | 21 + .../about_files/LICENSE-jsPlumb-MIT.txt | 20 + .../about_files/LICENSE-logback.txt | 15 + .../about_files/LICENSE-open-sans.txt | 204 +++ .../about_files/LICENSE-requirejs.txt | 58 + .../about_files/LICENSE-slf4j-api.txt | 21 + .../about_files/LICENSE-slf4j-ext.txt | 24 + .../about_files/LICENSE-wysihtml5.txt | 9 + .../about_files/LICENSE-x-editable.txt | 22 + .../about_files/LICENSE-xmltree.txt | 21 + .../about_files/MPL-v1.1.txt | 470 ++++++ .../about_files/file-icons.txt | 27 + org.eclipse.winery.repository/bower.json | 61 + .../conf/winery.properties.dist | 49 + org.eclipse.winery.repository/pom.xml | 522 ++++++ .../sonar-project.java.properties | 24 + .../sonar-project.twomodules.properties | 29 + .../sonar-project.web.properties | 16 + .../eclipse/winery/repository/Constants.java | 64 + .../winery/repository/JAXBSupport.java | 138 ++ .../org/eclipse/winery/repository/Prefs.java | 293 ++++ .../winery/repository/RestDocFilter.java | 14 + .../org/eclipse/winery/repository/Utils.java | 783 +++++++++ .../backend/AbstractRepository.java | 110 ++ .../repository/backend/BackendUtils.java | 891 ++++++++++ .../backend/IGenericRepository.java | 189 +++ .../repository/backend/IRepository.java | 68 + .../backend/IRepositoryAdministration.java | 43 + .../repository/backend/MockXMLElement.java | 30 + .../winery/repository/backend/Repository.java | 19 + .../backend/ResourceCreationResult.java | 84 + .../backend/constants/Filename.java | 47 + .../backend/constants/MediaTypes.java | 25 + .../backend/filebased/AutoSaveListener.java | 72 + .../backend/filebased/FileUtils.java | 110 ++ .../filebased/FilebasedRepository.java | 592 +++++++ .../backend/filebased/GitBasedRepository.java | 190 +++ .../filebased/OnlyNonHiddenDirectories.java | 27 + .../backend/filebased/OnlyNonHiddenFiles.java | 33 + .../winery/repository/datatypes/FileMeta.java | 110 ++ .../datatypes/TypeWithShortName.java | 60 + .../repository/datatypes/ids/IdNames.java | 30 + .../datatypes/ids/admin/AdminId.java | 55 + .../ids/admin/ConstraintTypesId.java | 26 + .../datatypes/ids/admin/NamespacesId.java | 26 + .../datatypes/ids/admin/PlanLanguagesId.java | 26 + .../datatypes/ids/admin/PlanTypesId.java | 26 + .../datatypes/ids/admin/TypesId.java | 22 + .../elements/ArtifactTemplateDirectoryId.java | 28 + .../ids/elements/SelfServiceMetaDataId.java | 24 + .../ids/elements/VisualAppearanceId.java | 28 + .../datatypes/select2/Select2DataItem.java | 56 + .../datatypes/select2/Select2OptGroup.java | 54 + .../datatypes/select2/package-info.java | 17 + .../repository/export/CSARExporter.java | 296 ++++ .../export/DummyParentForGeneratedXSDRef.java | 43 + ...epositoryFileReferenceForGeneratedXSD.java | 36 + .../repository/export/ExportedState.java | 67 + .../repository/export/TOSCAExportUtil.java | 789 +++++++++ .../repository/importing/CSARImporter.java | 1070 ++++++++++++ .../json/TTopologyTemplateSerializer.java | 81 + .../json/TopologyTemplateModule.java | 24 + .../AbstractComponentInstanceResource.java | 509 ++++++ ...ourceWithNameDerivedFromAbstractFinal.java | 201 +++ ...mponentInstanceWithReferencesResource.java | 52 + .../resources/AbstractComponentsResource.java | 278 ++++ ...ctComponentsWithTypeReferenceResource.java | 71 + .../resources/ConstraintResource.java | 69 + .../resources/ConstraintsResource.java | 39 + .../resources/EntityTypeResource.java | 108 ++ .../resources/GenericComponentPageData.java | 103 ++ .../resources/GenericKeyValueResource.java | 149 ++ .../GenericVisualAppearanceResource.java | 127 ++ .../winery/repository/resources/IHasName.java | 43 + .../resources/IHasTypeReference.java | 39 + ...ourceOrNodeTypeImplementationResource.java | 19 + ...elationshipTypeImplementationResource.java | 23 + ...elationshipTypeImplementationResource.java | 19 + .../resources/InheritanceResource.java | 74 + .../repository/resources/MainResource.java | 156 ++ .../repository/resources/SubMenuData.java | 38 + .../resources/_support/IPersistable.java | 24 + .../collections/CollectionsHelper.java | 42 + .../collections/EntityCollectionResource.java | 206 +++ .../_support/collections/EntityResource.java | 115 ++ .../collections/IIdDetermination.java | 20 + .../EntityWithIdCollectionResource.java | 66 + .../withid/EntityWithIdResource.java | 29 + .../EntityWithoutIdCollectionResource.java | 114 ++ .../withoutid/EntityWithoutIdResource.java | 33 + .../IdDeterminationWithHashCode.java | 36 + .../collections/withoutid/package-info.java | 17 + .../admin/AbstractAdminResource.java | 43 + .../resources/admin/AdminTopResource.java | 57 + .../resources/admin/NamespacesResource.java | 253 +++ .../admin/RepositoryAdminResource.java | 112 ++ .../admin/types/AbstractTypesManager.java | 204 +++ .../admin/types/ConstraintTypesManager.java | 25 + .../admin/types/PlanLanguagesManager.java | 28 + .../admin/types/PlanTypesManager.java | 28 + .../artifacts/DeploymentArtifactResource.java | 84 + .../DeploymentArtifactsResource.java | 87 + .../artifacts/GenericArtifactResource.java | 41 + .../artifacts/GenericArtifactsResource.java | 579 +++++++ .../ImplementationArtifactResource.java | 88 + .../ImplementationArtifactsResource.java | 106 ++ .../documentation/DocumentationResource.java | 43 + .../documentation/DocumentationsResource.java | 60 + .../IEntityTemplateResource.java | 34 + .../entitytemplates/PropertiesResource.java | 66 + .../TEntityTemplateResource.java | 119 ++ .../TEntityTemplatesResource.java | 98 ++ .../ArtifactTemplateResource.java | 307 ++++ .../ArtifactTemplatesResource.java | 22 + .../artifacttemplates/FilesResource.java | 163 ++ .../entitytemplates/package-info.java | 27 + .../PolicyTemplateResource.java | 95 ++ .../PolicyTemplatesResource.java | 23 + .../EntityTypeImplementationResource.java | 29 + .../NodeTypeImplementationResource.java | 105 ++ .../NodeTypeImplementationsResource.java | 17 + .../package-info.java | 19 + ...elationshipTypeImplementationResource.java | 81 + ...lationshipTypeImplementationsResource.java | 18 + .../entitytypes/ImplementationsOfOneType.java | 70 + .../entitytypes/InstanceStatesResource.java | 133 ++ ...opologyGraphElementEntityTypeResource.java | 23 + .../artifacttypes/ArtifactTypeResource.java | 67 + .../artifacttypes/ArtifactTypesResource.java | 90 + .../CapabilityTypeResource.java | 47 + .../CapabilityTypesResource.java | 22 + .../ImplementationsOfOneNodeTypeResource.java | 87 + .../nodetypes/NodeTypeResource.java | 105 ++ .../nodetypes/NodeTypesResource.java | 22 + .../nodetypes/VisualAppearanceResource.java | 84 + .../AbstractReqOrCapDefResource.java | 177 ++ .../CapabilityDefinitionResource.java | 92 ++ .../CapabilityDefinitionsResource.java | 50 + .../RequirementDefinitionResource.java | 89 + .../RequirementDefinitionsResource.java | 45 + ...rementOrCapabilityDefinitionsResource.java | 131 ++ .../resources/entitytypes/package-info.java | 17 + .../policytypes/AppliesToResource.java | 41 + .../policytypes/LanguageResource.java | 28 + .../policytypes/PolicyTypeResource.java | 66 + .../policytypes/PolicyTypesResource.java | 22 + .../entitytypes/properties/JSPData.java | 85 + .../PropertiesDefinitionResource.java | 161 ++ .../PropertyDefinitionKVListResource.java | 41 + .../winery/PropertyDefinitionKVResource.java | 59 + .../WinerysPropertiesDefinitionResource.java | 132 ++ ...ntationsOfOneRelationshipTypeResource.java | 81 + .../RelationshipTypeResource.java | 165 ++ .../RelationshipTypesResource.java | 17 + .../VisualAppearanceResource.java | 291 ++++ .../RequiredCapabilityTypeResource.java | 83 + .../RequirementTypeResource.java | 44 + .../RequirementTypesResource.java | 22 + .../resources/imports/ImportsResource.java | 44 + .../genericimports/GenericImportResource.java | 133 ++ .../GenericImportsResource.java | 39 + .../imports/xsdimports/XSDImportResource.java | 174 ++ .../xsdimports/XSDImportsResource.java | 124 ++ .../interfaces/InterfaceResource.java | 46 + .../interfaces/InterfacesResource.java | 140 ++ .../interfaces/OperationResource.java | 71 + .../interfaces/OperationsResource.java | 69 + .../interfaces/ParameterResource.java | 62 + .../interfaces/ParametersResource.java | 99 ++ .../repository/resources/package-info.java | 27 + .../ServiceTemplateResource.java | 263 +++ .../ServiceTemplatesResource.java | 18 + .../BoundaryDefinitionsJSPData.java | 113 ++ .../BoundaryDefinitionsResource.java | 144 ++ .../PropertyMappingsResource.java | 115 ++ .../interfaces/ExportedInterfaceResource.java | 34 + .../interfaces/ExportedOperationResource.java | 249 +++ .../ExportedOperationsResource.java | 38 + .../interfaces/InterfacesResource.java | 38 + .../interfaces/package-info.java | 16 + .../policies/PoliciesResource.java | 46 + .../policies/PolicyResource.java | 26 + .../policies/package-info.java | 16 + .../reqscaps/CapabilitiesResource.java | 76 + .../reqscaps/CapabilityResource.java | 26 + .../reqscaps/RequirementResource.java | 26 + .../reqscaps/RequirementsResource.java | 85 + .../reqscaps/package-info.java | 18 + .../servicetemplates/plans/PlanResource.java | 169 ++ .../servicetemplates/plans/PlansResource.java | 183 ++ .../plans/PlansResourceData.java | 136 ++ .../selfserviceportal/OptionResource.java | 96 ++ .../selfserviceportal/OptionsResource.java | 131 ++ .../SelfServicePortalResource.java | 223 +++ .../NodeTemplateResource.java | 156 ++ .../NodeTemplatesResource.java | 60 + .../RelationshipTemplateResource.java | 30 + .../RelationshipTemplatesResource.java | 59 + .../TopologyTemplateResource.java | 248 +++ .../resources/tags/TagsResource.java | 63 + .../OpenTOSCAContainerConnection.java | 30 + .../runtimeintegration/package-info.java | 16 + .../src/main/resources/.gitignore | 3 + .../src/main/resources/logback-test.xml | 18 + .../src/main/resources/logback.xml | 15 + .../src/main/resources/mime-types.properties | 19 + .../src/main/templates/Version.java | 7 + .../src/main/webapp/WEB-INF/.gitignore | 3 + .../src/main/webapp/WEB-INF/appengine-web.xml | 20 + .../src/main/webapp/WEB-INF/functions.tld | 153 ++ .../src/main/webapp/WEB-INF/jetty-web.xml | 7 + .../src/main/webapp/WEB-INF/tags/about.tag | 65 + .../WEB-INF/tags/addComponentInstance.tag | 147 ++ .../WEB-INF/tags/colorpickerloading.tag | 52 + .../webapp/WEB-INF/tags/common/.gitignore | 3 + .../webapp/WEB-INF/tags/componentinstance.tag | 162 ++ .../tags/componentinstancewithName.tag | 33 + ...stancewithNameDerivedFromAbstractFinal.tag | 45 + .../WEB-INF/tags/constraints/constraint.tag | 83 + .../webapp/WEB-INF/tags/entitytemplate.tag | 43 + .../main/webapp/WEB-INF/tags/entitytype.tag | 49 + .../nodetypes/reqandcapdefs/reqandcapdefs.tag | 333 ++++ .../main/webapp/WEB-INF/tags/genericpage.tag | 344 ++++ .../main/webapp/WEB-INF/tags/imageUpload.tag | 42 + .../webapp/WEB-INF/tags/namespaceChooser.tag | 52 + .../tags/parameters/parametersHTML.tag | 38 + .../tags/parameters/parametersInput.tag | 20 + .../WEB-INF/tags/parameters/parametersJS.tag | 163 ++ .../tags/parameters/parametersOutput.tag | 20 + .../validnodetypeendingsselect.tag | 43 + .../boundarydefinitions/browseForReqOrCap.tag | 161 ++ ...owseForServiceTemplatePropertyReqOrCap.tag | 166 ++ .../boundarydefinitions/browseForX.tag | 49 + .../WEB-INF/tags/simpleSingleFileUpload.tag | 114 ++ .../src/main/webapp/WEB-INF/tags/submenu.tag | 26 + .../WEB-INF/tags/topologyTemplateRenderer.tag | 206 +++ .../tags/typeswithshortnameasselect.tag | 48 + .../src/main/webapp/WEB-INF/web.xml | 93 ++ .../webapp/css/topologyTemplateRenderer.css | 49 + .../topologyTemplateRendererFullscreen.css | 30 + .../CapSelection.css | 15 + .../NodeTemplateSelection.css | 13 + .../RelationshipTemplateSelection.css | 13 + .../ReqSelection.css | 15 + .../propertySelection.css | 15 + .../css/topologytemplaterendering/small.css | 37 + .../src/main/webapp/css/winery-repository.css | 868 ++++++++++ .../src/main/webapp/images/back_disabled.png | Bin 0 -> 1361 bytes .../src/main/webapp/images/back_enabled.png | Bin 0 -> 1379 bytes .../main/webapp/images/back_enabled_hover.png | Bin 0 -> 1375 bytes .../images/containers/admin/FrameBottom.jpg | Bin 0 -> 9642 bytes .../images/containers/admin/FrameMiddle.jpg | Bin 0 -> 1579 bytes .../images/containers/admin/FrameTop.jpg | Bin 0 -> 30099 bytes .../admin/styledTabMenuButtonCenter.jpg | Bin 0 -> 1625 bytes .../admin/styledTabMenuButtonLeft.jpg | Bin 0 -> 1549 bytes .../admin/styledTabMenuButtonRight.jpg | Bin 0 -> 1799 bytes .../images/containers/nt/FrameBottom.jpg | Bin 0 -> 14574 bytes .../images/containers/nt/FrameMiddle.jpg | Bin 0 -> 1579 bytes .../webapp/images/containers/nt/FrameTop.jpg | Bin 0 -> 38952 bytes .../images/containers/nt/FrameTopLarge.jpg | Bin 0 -> 31898 bytes .../images/containers/rt/FrameBottom.jpg | Bin 0 -> 16269 bytes .../images/containers/rt/FrameMiddle.jpg | Bin 0 -> 1579 bytes .../webapp/images/containers/rt/FrameTop.jpg | Bin 0 -> 42281 bytes .../images/containers/rt/FrameTopLarge.jpg | Bin 0 -> 33776 bytes .../images/containers/st/FrameBottom.jpg | Bin 0 -> 16696 bytes .../images/containers/st/FrameMiddle.jpg | Bin 0 -> 1579 bytes .../webapp/images/containers/st/FrameTop.jpg | Bin 0 -> 43839 bytes .../webapp/images/entityBox/admin/center.jpg | Bin 0 -> 494 bytes .../webapp/images/entityBox/admin/left.jpg | Bin 0 -> 4377 bytes .../webapp/images/entityBox/admin/right.jpg | Bin 0 -> 1257 bytes .../webapp/images/entityBox/deleteButton.jpg | Bin 0 -> 2061 bytes .../images/entityBox/deleteButtonHover.jpg | Bin 0 -> 3011 bytes .../webapp/images/entityBox/editButton.jpg | Bin 0 -> 1299 bytes .../images/entityBox/editButtonHover.jpg | Bin 0 -> 2350 bytes .../webapp/images/entityBox/exportButton.jpg | Bin 0 -> 1321 bytes .../images/entityBox/exportButtonHover.jpg | Bin 0 -> 2459 bytes .../images/entityBox/nodeType/center.jpg | Bin 0 -> 586 bytes .../webapp/images/entityBox/nodeType/left.jpg | Bin 0 -> 6588 bytes .../images/entityBox/nodeType/right.jpg | Bin 0 -> 1729 bytes .../entityBox/relationshipType/center.jpg | Bin 0 -> 584 bytes .../entityBox/relationshipType/left.jpg | Bin 0 -> 7282 bytes .../entityBox/relationshipType/right.jpg | Bin 0 -> 1676 bytes .../entityBox/serviceTemplate/center.jpg | Bin 0 -> 601 bytes .../images/entityBox/serviceTemplate/left.jpg | Bin 0 -> 7774 bytes .../entityBox/serviceTemplate/right.jpg | Bin 0 -> 1838 bytes .../src/main/webapp/images/favicon.ico | Bin 0 -> 1150 bytes .../main/webapp/images/forward_disabled.png | Bin 0 -> 1363 bytes .../main/webapp/images/forward_enabled.png | Bin 0 -> 1380 bytes .../webapp/images/forward_enabled_hover.png | Bin 0 -> 1379 bytes .../main/webapp/images/header_background.png | Bin 0 -> 36799 bytes .../images/jquery-fileupload/loading.gif | Bin 0 -> 3897 bytes .../images/jquery-fileupload/progressbar.gif | Bin 0 -> 3323 bytes .../webapp/images/overviewShadowBottom.jpg | Bin 0 -> 1401 bytes .../webapp/images/overviewShadowMiddle.jpg | Bin 0 -> 345 bytes .../main/webapp/images/overviewShadowTop.jpg | Bin 0 -> 1306 bytes .../images/relationshiptype/DiamondSource.png | Bin 0 -> 261 bytes .../images/relationshiptype/DiamondTarget.png | Bin 0 -> 270 bytes .../relationshiptype/PlainArrowSource.png | Bin 0 -> 260 bytes .../relationshiptype/PlainArrowTarget.png | Bin 0 -> 255 bytes .../images/relationshiptype/circleSource.png | Bin 0 -> 242 bytes .../images/relationshiptype/circleTarget.png | Bin 0 -> 255 bytes .../images/relationshiptype/dotted2Line.png | Bin 0 -> 247 bytes .../images/relationshiptype/dottedLine.png | Bin 0 -> 414 bytes .../relationshiptype/doubleArrowSource.png | Bin 0 -> 337 bytes .../relationshiptype/doubleArrowTarget.png | Bin 0 -> 343 bytes .../images/relationshiptype/noneSource.png | Bin 0 -> 141 bytes .../images/relationshiptype/noneTarget.png | Bin 0 -> 146 bytes .../images/relationshiptype/plainLine.png | Bin 0 -> 139 bytes .../relationshiptype/simpleArrowSource.png | Bin 0 -> 265 bytes .../relationshiptype/simpleArrowTarget.png | Bin 0 -> 274 bytes .../images/relationshiptype/squareSource.png | Bin 0 -> 193 bytes .../images/relationshiptype/squareTarget.png | Bin 0 -> 198 bytes .../webapp/images/searchBoxBackground.jpg | Bin 0 -> 5574 bytes .../src/main/webapp/images/sort_asc.png | Bin 0 -> 1118 bytes .../main/webapp/images/sort_asc_disabled.png | Bin 0 -> 1050 bytes .../src/main/webapp/images/sort_both.png | Bin 0 -> 1136 bytes .../src/main/webapp/images/sort_desc.png | Bin 0 -> 1127 bytes .../main/webapp/images/sort_desc_disabled.png | Bin 0 -> 1045 bytes .../images/styledTabMenuButtonCenter.jpg | Bin 0 -> 1625 bytes .../webapp/images/styledTabMenuButtonLeft.jpg | Bin 0 -> 1549 bytes .../images/styledTabMenuButtonRight.jpg | Bin 0 -> 1799 bytes .../src/main/webapp/js/.gitignore | 3 + .../js/boundaryDefinitionsXSelection.js | 96 ++ .../main/webapp/js/jquery.fileupload-audio.js | 12 + .../main/webapp/js/jquery.fileupload-image.js | 12 + .../webapp/js/jquery.fileupload-validate.js | 12 + .../main/webapp/js/jquery.fileupload-video.js | 12 + .../src/main/webapp/js/nextselect.js | 144 ++ .../main/webapp/js/winery-support-non-AMD.js | 223 +++ .../src/main/webapp/js/winery-support.js | 112 ++ .../src/main/webapp/jsp/admin/adminindex.jsp | 41 + .../src/main/webapp/jsp/admin/namespaces.jsp | 108 ++ .../src/main/webapp/jsp/admin/repository.jsp | 101 ++ .../src/main/webapp/jsp/admin/types/types.jsp | 105 ++ .../main/webapp/jsp/artifacts/artifacts.jsp | 141 ++ .../src/main/webapp/jsp/componentnaming.jspf | 28 + .../src/main/webapp/jsp/documentation.jsp | 87 + .../artifacttemplates/artifacttemplate.jsp | 32 + .../artifacttemplates/files.jsp | 18 + .../policytemplates/policytemplate.jsp | 29 + .../webapp/jsp/entitytemplates/properties.jsp | 92 ++ .../nodetypeimplementation.jsp | 33 + .../relationshiptypeimplementation.jsp | 29 + .../artifacttypes/artifacttype.jsp | 26 + .../capabilitytypes/capabilitytype.jsp | 17 + .../jsp/entitytypes/implementations.jsp | 63 + .../webapp/jsp/entitytypes/instancestates.jsp | 86 + .../jsp/entitytypes/nodetypes/nodetype.jsp | 44 + .../nodetypes/reqandcapdefs/capdefs.jsp | 17 + .../nodetypes/reqandcapdefs/reqdefs.jsp | 17 + .../nodetypes/visualappearance.jsp | 85 + .../jsp/entitytypes/policytypes/appliesto.jsp | 25 + .../jsp/entitytypes/policytypes/language.jsp | 21 + .../entitytypes/policytypes/policytype.jsp | 32 + .../properties/propertiesDefinition.jsp | 320 ++++ .../relationshiptypes/relationshiptype.jsp | 44 + .../relationshiptypes/validendings.jsp | 39 + .../relationshiptypes/visualappearance.jsp | 207 +++ .../requiredcapabilitytype.jsp | 56 + .../requirementtypes/requirementtype.jsp | 30 + .../main/webapp/jsp/genericcomponentpage.jsp | 209 +++ .../src/main/webapp/jsp/hashloading.jsp | 140 ++ .../jsp/imports/xsdimports/xsdimport.jsp | 50 + .../src/main/webapp/jsp/inheritance.jsp | 55 + .../main/webapp/jsp/interfaces/interfaces.jsp | 489 ++++++ .../src/main/webapp/jsp/otherElements.jsp | 44 + .../boundarydefinitions.jsp | 1080 ++++++++++++ .../jsp/servicetemplates/plans/plans.jsp | 199 +++ .../selfservicemetadata.jsp | 256 +++ .../jsp/servicetemplates/servicetemplate.jsp | 43 + .../topologytemplates/topologytemplate.jsp | 23 + .../topologytemplateview.jsp | 67 + .../webapp/jsp/setupTriggerRemoveByDELKey.jsp | 28 + .../src/main/webapp/jsp/shared/.gitignore | 3 + .../src/main/webapp/jsp/tags/tags.jsp | 14 + .../src/main/webapp/jsp/test.jsp | 33 + .../src/main/webapp/jsp/xmlSource.jsp | 20 + .../src/psd/Sorting icons.psd | Bin 0 -> 27490 bytes .../src/psd/header_background_plain.png | Bin 0 -> 36026 bytes .../eclipse/winery/librarytests/DateTest.java | 33 + .../librarytests/InheritanceIllustration.java | 48 + .../winery/repository/PrefsTestEnabled.java | 32 + .../PrefsTestEnabledGitBackedRepository.java | 30 + ...sTestEnabledUsingConfiguredRepository.java | 28 + .../TestWithRepositoryConnection.java | 27 + .../eclipse/winery/repository/UtilsTest.java | 26 + .../repository/export/TestToscaExporter.java | 81 + .../importing/TestCSARImporter.java | 48 + ...nentInstanceResourceDefinitionsBacked.java | 54 + .../repository/resources/TestResource.java | 22 + .../TestArtifactTemplateResource.java | 43 + .../TestCapabilityTypeResource.java | 53 + .../TestRequirementDefinitions.java | 144 ++ .../src/test/resources/.gitignore | 1 + .../src/test/resources/logback-test.xml | 15 + org.eclipse.winery.topologymodeler/.bowerrc | 3 + .../.gitattributes | 1 + org.eclipse.winery.topologymodeler/.gitignore | 23 + .../de.loskutov.anyedit.AnyEditTools.prefs | 16 + org.eclipse.winery.topologymodeler/README.md | 44 + org.eclipse.winery.topologymodeler/about.html | 604 +++++++ .../about_files/Apache-LICENSE-2.0.txt | 202 +++ .../about_files/CDDL-v1.1.txt | 129 ++ .../about_files/LICENSE-KeyboardJS.txt | 25 + .../about_files/LICENSE-XMLWriter.txt | 27 + .../about_files/LICENSE-biltong.txt | 22 + .../about_files/LICENSE-boostrap.txt | 21 + .../about_files/LICENSE-jQuery-UI.txt | 26 + .../about_files/LICENSE-jQuery.txt | 21 + .../about_files/LICENSE-jsPlumb-MIT.txt | 20 + .../about_files/LICENSE-logback.txt | 15 + .../about_files/LICENSE-requirejs.txt | 58 + .../about_files/LICENSE-slf4j-api.txt | 21 + .../about_files/LICENSE-x-editable.txt | 22 + .../about_files/MPL-v1.1.txt | 470 ++++++ org.eclipse.winery.topologymodeler/bower.json | 45 + org.eclipse.winery.topologymodeler/pom.xml | 193 +++ .../sonar-project.js.properties | 13 + .../sonar-project.web.properties | 13 + .../winery/topologymodeler/WineryUtil.java | 87 + .../src/main/resources/.gitignore | 1 + .../main/webapp/WEB-INF/common-functions.tld | 70 + .../src/main/webapp/WEB-INF/functions.tld | 36 + .../src/main/webapp/WEB-INF/tags/about.tag | 58 + .../WEB-INF/tags/common/QNameChooser.tag | 50 + .../tags/common/artifactcreationdialog.tag | 443 +++++ .../tags/common/artifacttemplateselection.tag | 41 + .../WEB-INF/tags/common/id_name_type.tag | 36 + .../common/orioneditor/orioneditorarea.tag | 110 ++ .../WEB-INF/tags/common/policies/policies.tag | 54 + .../tags/common/policies/policydiag.tag | 205 +++ .../WEB-INF/tags/common/spinnerwithinphty.tag | 92 ++ .../tags/common/templates/CSSForTypes.tag | 50 + ...defineCreateConnectorEndpointsFunction.tag | 42 + .../nodetemplates/nodeTemplateRenderer.tag | 266 +++ .../templates/nodetemplates/reqscaps/caps.tag | 33 + .../templates/nodetemplates/reqscaps/reqs.tag | 33 + .../nodetemplates/reqscaps/reqsorcaps.tag | 63 + .../tags/common/templates/properties.tag | 103 ++ .../tags/common/templates/propertiesBasic.tag | 110 ++ ...ConnectionTypesAndConnectNodeTemplates.tag | 204 +++ .../tags/common/templates/toggleButtons.tag | 131 ++ .../src/main/webapp/WEB-INF/tags/idInput.tag | 43 + .../webapp/WEB-INF/tags/namespaceChooser.tag | 52 + .../src/main/webapp/WEB-INF/tags/palette.tag | 207 +++ .../propertiesOfOneNodeTemplate.tag | 147 ++ .../reqscaps/addorupdatereqorcap.tag | 248 +++ .../propertiesOfOneRelationshipTemplate.tag | 179 ++ .../src/main/webapp/WEB-INF/web.xml | 21 + .../src/main/webapp/css/palette.css | 105 ++ .../src/main/webapp/css/propertiesview.css | 76 + .../src/main/webapp/css/topologymodeler.css | 286 ++++ .../webapp/css/topologytemplatecontent.css | 421 +++++ .../src/main/webapp/css/winery-common.css | 138 ++ .../src/main/webapp/favicon.png | Bin 0 -> 674 bytes .../src/main/webapp/images/xml.png | Bin 0 -> 475 bytes .../src/main/webapp/index.jsp | 1469 +++++++++++++++++ .../webapp/js/artifacttemplateselection.js | 82 + .../main/webapp/js/jquery.fileupload-audio.js | 13 + .../main/webapp/js/jquery.fileupload-image.js | 13 + .../webapp/js/jquery.fileupload-validate.js | 13 + .../main/webapp/js/jquery.fileupload-video.js | 13 + .../js/winery-common-topologyrendering.js | 143 ++ .../src/main/webapp/js/winery-common.js | 263 +++ .../main/webapp/js/winery-sugiyamaLayouter.js | 634 +++++++ .../main/webapp/js/winery-support-common.js | 330 ++++ .../webapp/js/winery-topologymodeler-AMD.js | 208 +++ .../main/webapp/js/winery-topologymodeler.js | 309 ++++ .../src/main/webapp/jsp/shared/README.md | 1 + .../src/main/webapp/jsp/shared/dialogs.jsp | 83 + .../src/main/webapp/logback.xml | 15 + .../src/test/java/.gitkeep | 0 pom.xml | 78 + 590 files changed, 50689 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 LICENSE-ASL.txt create mode 100644 LICENSE-EPL.txt create mode 100644 README.md create mode 100644 notice.html create mode 100644 org.eclipse.winery.common/.gitignore create mode 100644 org.eclipse.winery.common/about.html create mode 100644 org.eclipse.winery.common/about_files/Apache-LICENSE-2.0.txt create mode 100644 org.eclipse.winery.common/about_files/CDDL-v1.1.txt create mode 100644 org.eclipse.winery.common/about_files/LICENSE-logback.txt create mode 100644 org.eclipse.winery.common/about_files/LICENSE-slf4j-api.txt create mode 100644 org.eclipse.winery.common/pom.xml create mode 100644 org.eclipse.winery.common/sonar-project.properties create mode 100644 org.eclipse.winery.common/src/main/java/META-INF/MANIFEST.MF create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ModelUtilities.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/RepositoryFileReference.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/StringEncodedAndDecoded.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/TOSCADocumentBuilderFactory.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/Util.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/beans/NamespaceIdOptionalName.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/Defaults.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/MimeTypes.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/Namespaces.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/QNames.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/GenericId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/IdNames.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/IdUtil.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/Namespace.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/XMLId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ArtifactTemplateId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ArtifactTypeId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/CapabilityTypeId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTemplateId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTypeId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTypeImplementationId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/NodeTypeId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/NodeTypeImplementationId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/PolicyTemplateId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/PolicyTypeId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RelationshipTypeId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RelationshipTypeImplementationId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RequirementTypeId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ServiceTemplateId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/TOSCAComponentId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/TopologyGraphElementEntityTypeId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/imports/GenericImportId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/imports/XSDImportId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/package-info.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/PlanId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/PlansId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/TOSCAElementId.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/package-info.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/IWineryRepository.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/IWineryRepositoryCommon.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/QNameAlreadyExistsException.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/QNameWithName.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/PropertyDefinitionKV.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/PropertyDefinitionKVList.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/WinerysPropertiesDefinition.java create mode 100644 org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/package-info.java create mode 100644 org.eclipse.winery.common/src/test/java/.gitkeep create mode 100644 org.eclipse.winery.common/src/test/java/META-INF/MANIFEST.MF create mode 100644 org.eclipse.winery.common/src/test/java/org/eclipse/winery/common/ModelUtilitiesTest.java create mode 100644 org.eclipse.winery.common/src/test/java/org/eclipse/winery/common/TestUtil.java create mode 100644 org.eclipse.winery.generators.ia/.gitignore create mode 100644 org.eclipse.winery.generators.ia/about.html create mode 100644 org.eclipse.winery.generators.ia/about_files/Apache-LICENSE-2.0.txt create mode 100644 org.eclipse.winery.generators.ia/about_files/CDDL-v1.1.txt create mode 100644 org.eclipse.winery.generators.ia/about_files/LICENSE-logback.txt create mode 100644 org.eclipse.winery.generators.ia/about_files/LICENSE-slf4j-api.txt create mode 100644 org.eclipse.winery.generators.ia/pom.xml create mode 100644 org.eclipse.winery.generators.ia/src/main/java/org/eclipse/winery/generators/ia/Generator.java create mode 100644 org.eclipse.winery.generators.ia/src/main/resources/template/java/AbstractIAService.java.template create mode 100644 org.eclipse.winery.generators.ia/src/main/resources/template/java/TemplateService.java.template create mode 100644 org.eclipse.winery.generators.ia/src/main/resources/template/project/README.txt create mode 100644 org.eclipse.winery.generators.ia/src/main/resources/template/project/pom.xml create mode 100644 org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/beans.xml create mode 100644 org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/web.xml create mode 100644 org.eclipse.winery.generators.ia/src/test/java/META-INF/MANIFEST.MF create mode 100644 org.eclipse.winery.generators.ia/src/test/java/org/eclipse/winery/generators/ia/Test.java create mode 100644 org.eclipse.winery.repository.client/.gitignore create mode 100644 org.eclipse.winery.repository.client/.settings/de.loskutov.anyedit.AnyEditTools.prefs create mode 100644 org.eclipse.winery.repository.client/README.md create mode 100644 org.eclipse.winery.repository.client/about.html create mode 100644 org.eclipse.winery.repository.client/about_files/Apache-LICENSE-2.0.txt create mode 100644 org.eclipse.winery.repository.client/about_files/CDDL-v1.1.txt create mode 100644 org.eclipse.winery.repository.client/about_files/LICENSE-logback.txt create mode 100644 org.eclipse.winery.repository.client/about_files/LICENSE-slf4j-api.txt create mode 100644 org.eclipse.winery.repository.client/pom.xml create mode 100644 org.eclipse.winery.repository.client/src/main/java/META-INF/MANIFEST.MF create mode 100644 org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/IWineryRepositoryClient.java create mode 100644 org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/WineryRepositoryClient.java create mode 100644 org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/WineryRepositoryClientFactory.java create mode 100644 org.eclipse.winery.repository.client/src/test/java/META-INF/MANIFEST.MF create mode 100644 org.eclipse.winery.repository.client/src/test/java/org/eclipse/winery/repository/client/TestWineryRepositoryClient.java create mode 100644 org.eclipse.winery.repository/.bowerrc create mode 100644 org.eclipse.winery.repository/.gitattributes create mode 100644 org.eclipse.winery.repository/.gitignore create mode 100644 org.eclipse.winery.repository/.settings/de.loskutov.anyedit.AnyEditTools.prefs create mode 100644 org.eclipse.winery.repository/README.md create mode 100644 org.eclipse.winery.repository/about.html create mode 100644 org.eclipse.winery.repository/about_files/Apache-LICENSE-2.0.txt create mode 100644 org.eclipse.winery.repository/about_files/CDDL-v1.1.txt create mode 100644 org.eclipse.winery.repository/about_files/EDL.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-ASM.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-JSch.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-KeyboardJS.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-XMLWriter.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-biltong.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-boostrap.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-bootstrap-switch.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-bootstrap3-wysihtml5-bower.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-colorPicker.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-datatables.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-handlebars.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-jQuery-UI.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-jQuery.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-jsPlumb-MIT.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-logback.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-open-sans.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-requirejs.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-slf4j-api.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-slf4j-ext.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-wysihtml5.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-x-editable.txt create mode 100644 org.eclipse.winery.repository/about_files/LICENSE-xmltree.txt create mode 100644 org.eclipse.winery.repository/about_files/MPL-v1.1.txt create mode 100644 org.eclipse.winery.repository/about_files/file-icons.txt create mode 100644 org.eclipse.winery.repository/bower.json create mode 100644 org.eclipse.winery.repository/conf/winery.properties.dist create mode 100644 org.eclipse.winery.repository/pom.xml create mode 100644 org.eclipse.winery.repository/sonar-project.java.properties create mode 100644 org.eclipse.winery.repository/sonar-project.twomodules.properties create mode 100644 org.eclipse.winery.repository/sonar-project.web.properties create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Constants.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/JAXBSupport.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Prefs.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/RestDocFilter.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Utils.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/AbstractRepository.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/BackendUtils.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IGenericRepository.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IRepository.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IRepositoryAdministration.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/MockXMLElement.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/Repository.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/ResourceCreationResult.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/constants/Filename.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/constants/MediaTypes.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/AutoSaveListener.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/FileUtils.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/FilebasedRepository.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/GitBasedRepository.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/OnlyNonHiddenDirectories.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/OnlyNonHiddenFiles.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/FileMeta.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/TypeWithShortName.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/IdNames.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/AdminId.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/ConstraintTypesId.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/NamespacesId.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/PlanLanguagesId.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/PlanTypesId.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/TypesId.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/ArtifactTemplateDirectoryId.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/SelfServiceMetaDataId.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/VisualAppearanceId.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/Select2DataItem.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/Select2OptGroup.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/package-info.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/CSARExporter.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/DummyParentForGeneratedXSDRef.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/DummyRepositoryFileReferenceForGeneratedXSD.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/ExportedState.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/TOSCAExportUtil.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/importing/CSARImporter.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/json/TTopologyTemplateSerializer.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/json/TopologyTemplateModule.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceWithReferencesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentsWithTypeReferenceResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/ConstraintResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/ConstraintsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/EntityTypeResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericComponentPageData.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericKeyValueResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericVisualAppearanceResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/IHasName.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/IHasTypeReference.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTemplateResourceOrNodeTypeImplementationResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTypeImplementationResourceOrRelationshipTypeImplementationResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/InheritanceResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/MainResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/SubMenuData.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/IPersistable.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/CollectionsHelper.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/EntityCollectionResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/EntityResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/IIdDetermination.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withid/EntityWithIdCollectionResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withid/EntityWithIdResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/EntityWithoutIdCollectionResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/EntityWithoutIdResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/IdDeterminationWithHashCode.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/package-info.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/AbstractAdminResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/AdminTopResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/NamespacesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/RepositoryAdminResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/AbstractTypesManager.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/ConstraintTypesManager.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/PlanLanguagesManager.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/PlanTypesManager.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/DeploymentArtifactResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/DeploymentArtifactsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/GenericArtifactResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/GenericArtifactsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/ImplementationArtifactResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/ImplementationArtifactsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/documentation/DocumentationResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/documentation/DocumentationsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/IEntityTemplateResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/PropertiesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/TEntityTemplateResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/TEntityTemplatesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/ArtifactTemplateResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/ArtifactTemplatesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/FilesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/package-info.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/policytemplates/PolicyTemplateResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/policytemplates/PolicyTemplatesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/EntityTypeImplementationResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/nodetypeimplementations/NodeTypeImplementationResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/nodetypeimplementations/NodeTypeImplementationsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/package-info.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/relationshiptypeimplementations/RelationshipTypeImplementationResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/relationshiptypeimplementations/RelationshipTypeImplementationsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/ImplementationsOfOneType.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/InstanceStatesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/TopologyGraphElementEntityTypeResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/artifacttypes/ArtifactTypeResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/artifacttypes/ArtifactTypesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/CapabilityTypeResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/CapabilityTypesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/ImplementationsOfOneNodeTypeResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/NodeTypeResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/NodeTypesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/VisualAppearanceResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/AbstractReqOrCapDefResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/CapabilityDefinitionResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/CapabilityDefinitionsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementDefinitionResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementDefinitionsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementOrCapabilityDefinitionsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/package-info.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/AppliesToResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/LanguageResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/PolicyTypeResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/PolicyTypesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/JSPData.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/PropertiesDefinitionResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/PropertyDefinitionKVListResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/PropertyDefinitionKVResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/WinerysPropertiesDefinitionResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/ImplementationsOfOneRelationshipTypeResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/RelationshipTypeResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/RelationshipTypesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/VisualAppearanceResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequiredCapabilityTypeResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequirementTypeResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequirementTypesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/ImportsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/genericimports/GenericImportResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/genericimports/GenericImportsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/xsdimports/XSDImportResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/xsdimports/XSDImportsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/InterfaceResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/InterfacesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/OperationResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/OperationsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/ParameterResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/ParametersResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/package-info.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/ServiceTemplateResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/ServiceTemplatesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/BoundaryDefinitionsJSPData.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/BoundaryDefinitionsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/PropertyMappingsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedInterfaceResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedOperationResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedOperationsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/InterfacesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/package-info.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/PoliciesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/PolicyResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/package-info.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/CapabilitiesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/CapabilityResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/RequirementResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/RequirementsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/package-info.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlanResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlansResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlansResourceData.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/OptionResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/OptionsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/SelfServicePortalResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/NodeTemplateResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/NodeTemplatesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/RelationshipTemplateResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/RelationshipTemplatesResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/TopologyTemplateResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/tags/TagsResource.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/runtimeintegration/OpenTOSCAContainerConnection.java create mode 100644 org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/runtimeintegration/package-info.java create mode 100644 org.eclipse.winery.repository/src/main/resources/.gitignore create mode 100644 org.eclipse.winery.repository/src/main/resources/logback-test.xml create mode 100644 org.eclipse.winery.repository/src/main/resources/logback.xml create mode 100644 org.eclipse.winery.repository/src/main/resources/mime-types.properties create mode 100644 org.eclipse.winery.repository/src/main/templates/Version.java create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/.gitignore create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/appengine-web.xml create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/functions.tld create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/jetty-web.xml create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/about.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/addComponentInstance.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/colorpickerloading.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/common/.gitignore create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstance.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstancewithName.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstancewithNameDerivedFromAbstractFinal.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/constraints/constraint.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytemplate.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytype.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytypes/nodetypes/reqandcapdefs/reqandcapdefs.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/genericpage.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/imageUpload.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/namespaceChooser.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersHTML.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersInput.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersJS.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersOutput.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/relationshiptype/validnodetypeendingsselect.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForReqOrCap.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForServiceTemplatePropertyReqOrCap.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForX.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/simpleSingleFileUpload.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/submenu.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/topologyTemplateRenderer.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/typeswithshortnameasselect.tag create mode 100644 org.eclipse.winery.repository/src/main/webapp/WEB-INF/web.xml create mode 100644 org.eclipse.winery.repository/src/main/webapp/css/topologyTemplateRenderer.css create mode 100644 org.eclipse.winery.repository/src/main/webapp/css/topologyTemplateRendererFullscreen.css create mode 100644 org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/CapSelection.css create mode 100644 org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/NodeTemplateSelection.css create mode 100644 org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/RelationshipTemplateSelection.css create mode 100644 org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/ReqSelection.css create mode 100644 org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/propertySelection.css create mode 100644 org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/small.css create mode 100644 org.eclipse.winery.repository/src/main/webapp/css/winery-repository.css create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/back_disabled.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/back_enabled.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/back_enabled_hover.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/admin/FrameBottom.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/admin/FrameMiddle.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/admin/FrameTop.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/admin/styledTabMenuButtonCenter.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/admin/styledTabMenuButtonLeft.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/admin/styledTabMenuButtonRight.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/nt/FrameBottom.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/nt/FrameMiddle.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/nt/FrameTop.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/nt/FrameTopLarge.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/rt/FrameBottom.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/rt/FrameMiddle.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/rt/FrameTop.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/rt/FrameTopLarge.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/st/FrameBottom.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/st/FrameMiddle.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/containers/st/FrameTop.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/admin/center.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/admin/left.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/admin/right.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/deleteButton.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/deleteButtonHover.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/editButton.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/editButtonHover.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/exportButton.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/exportButtonHover.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/nodeType/center.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/nodeType/left.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/nodeType/right.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/relationshipType/center.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/relationshipType/left.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/relationshipType/right.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/serviceTemplate/center.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/serviceTemplate/left.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/entityBox/serviceTemplate/right.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/favicon.ico create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/forward_disabled.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/forward_enabled.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/forward_enabled_hover.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/header_background.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/jquery-fileupload/loading.gif create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/jquery-fileupload/progressbar.gif create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/overviewShadowBottom.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/overviewShadowMiddle.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/overviewShadowTop.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/DiamondSource.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/DiamondTarget.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/PlainArrowSource.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/PlainArrowTarget.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/circleSource.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/circleTarget.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/dotted2Line.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/dottedLine.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/doubleArrowSource.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/doubleArrowTarget.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/noneSource.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/noneTarget.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/plainLine.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/simpleArrowSource.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/simpleArrowTarget.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/squareSource.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/squareTarget.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/searchBoxBackground.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/sort_asc.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/sort_asc_disabled.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/sort_both.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/sort_desc.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/sort_desc_disabled.png create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/styledTabMenuButtonCenter.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/styledTabMenuButtonLeft.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/images/styledTabMenuButtonRight.jpg create mode 100644 org.eclipse.winery.repository/src/main/webapp/js/.gitignore create mode 100644 org.eclipse.winery.repository/src/main/webapp/js/boundaryDefinitionsXSelection.js create mode 100644 org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-audio.js create mode 100644 org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-image.js create mode 100644 org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-validate.js create mode 100644 org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-video.js create mode 100644 org.eclipse.winery.repository/src/main/webapp/js/nextselect.js create mode 100644 org.eclipse.winery.repository/src/main/webapp/js/winery-support-non-AMD.js create mode 100644 org.eclipse.winery.repository/src/main/webapp/js/winery-support.js create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/admin/adminindex.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/admin/namespaces.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/admin/repository.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/admin/types/types.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/artifacts/artifacts.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/componentnaming.jspf create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/documentation.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/artifacttemplates/artifacttemplate.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/artifacttemplates/files.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/policytemplates/policytemplate.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/properties.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypeimplementations/nodetypeimplementations/nodetypeimplementation.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypeimplementations/relationshiptypeimplementations/relationshiptypeimplementation.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/artifacttypes/artifacttype.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/capabilitytypes/capabilitytype.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/implementations.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/instancestates.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/nodetype.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/reqandcapdefs/capdefs.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/reqandcapdefs/reqdefs.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/visualappearance.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/appliesto.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/language.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/policytype.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/properties/propertiesDefinition.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/relationshiptype.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/validendings.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/visualappearance.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/requirementtypes/requiredcapabilitytype.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/requirementtypes/requirementtype.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/genericcomponentpage.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/hashloading.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/imports/xsdimports/xsdimport.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/inheritance.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/interfaces/interfaces.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/otherElements.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/boundarydefinitions/boundarydefinitions.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/plans/plans.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/selfservicemetadata/selfservicemetadata.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/servicetemplate.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/topologytemplates/topologytemplate.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/topologytemplates/topologytemplateview.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/setupTriggerRemoveByDELKey.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/shared/.gitignore create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/tags/tags.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/test.jsp create mode 100644 org.eclipse.winery.repository/src/main/webapp/jsp/xmlSource.jsp create mode 100644 org.eclipse.winery.repository/src/psd/Sorting icons.psd create mode 100644 org.eclipse.winery.repository/src/psd/header_background_plain.png create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/librarytests/DateTest.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/librarytests/InheritanceIllustration.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/PrefsTestEnabled.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/PrefsTestEnabledGitBackedRepository.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/PrefsTestEnabledUsingConfiguredRepository.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/TestWithRepositoryConnection.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/UtilsTest.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/export/TestToscaExporter.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/importing/TestCSARImporter.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/TestAbstractComponentInstanceResourceDefinitionsBacked.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/TestResource.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/TestArtifactTemplateResource.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/TestCapabilityTypeResource.java create mode 100644 org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/TestRequirementDefinitions.java create mode 100644 org.eclipse.winery.repository/src/test/resources/.gitignore create mode 100644 org.eclipse.winery.repository/src/test/resources/logback-test.xml create mode 100644 org.eclipse.winery.topologymodeler/.bowerrc create mode 100644 org.eclipse.winery.topologymodeler/.gitattributes create mode 100644 org.eclipse.winery.topologymodeler/.gitignore create mode 100644 org.eclipse.winery.topologymodeler/.settings/de.loskutov.anyedit.AnyEditTools.prefs create mode 100644 org.eclipse.winery.topologymodeler/README.md create mode 100644 org.eclipse.winery.topologymodeler/about.html create mode 100644 org.eclipse.winery.topologymodeler/about_files/Apache-LICENSE-2.0.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/CDDL-v1.1.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/LICENSE-KeyboardJS.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/LICENSE-XMLWriter.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/LICENSE-biltong.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/LICENSE-boostrap.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/LICENSE-jQuery-UI.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/LICENSE-jQuery.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/LICENSE-jsPlumb-MIT.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/LICENSE-logback.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/LICENSE-requirejs.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/LICENSE-slf4j-api.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/LICENSE-x-editable.txt create mode 100644 org.eclipse.winery.topologymodeler/about_files/MPL-v1.1.txt create mode 100644 org.eclipse.winery.topologymodeler/bower.json create mode 100644 org.eclipse.winery.topologymodeler/pom.xml create mode 100644 org.eclipse.winery.topologymodeler/sonar-project.js.properties create mode 100644 org.eclipse.winery.topologymodeler/sonar-project.web.properties create mode 100644 org.eclipse.winery.topologymodeler/src/main/java/org/eclipse/winery/topologymodeler/WineryUtil.java create mode 100644 org.eclipse.winery.topologymodeler/src/main/resources/.gitignore create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/common-functions.tld create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/functions.tld create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/about.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/QNameChooser.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/artifactcreationdialog.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/artifacttemplateselection.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/id_name_type.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/orioneditor/orioneditorarea.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/policies/policies.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/policies/policydiag.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/spinnerwithinphty.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/CSSForTypes.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/defineCreateConnectorEndpointsFunction.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/nodeTemplateRenderer.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/caps.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/reqs.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/reqsorcaps.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/properties.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/propertiesBasic.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/registerConnectionTypesAndConnectNodeTemplates.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/toggleButtons.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/idInput.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/namespaceChooser.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/palette.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/propertiesOfOneNodeTemplate.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/reqscaps/addorupdatereqorcap.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/relationshiptemplates/propertiesOfOneRelationshipTemplate.tag create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/web.xml create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/css/palette.css create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/css/propertiesview.css create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/css/topologymodeler.css create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/css/topologytemplatecontent.css create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/css/winery-common.css create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/favicon.png create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/images/xml.png create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/index.jsp create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/js/artifacttemplateselection.js create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-audio.js create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-image.js create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-validate.js create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-video.js create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-common-topologyrendering.js create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-common.js create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-sugiyamaLayouter.js create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-support-common.js create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-topologymodeler-AMD.js create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-topologymodeler.js create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/jsp/shared/README.md create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/jsp/shared/dialogs.jsp create mode 100644 org.eclipse.winery.topologymodeler/src/main/webapp/logback.xml create mode 100644 org.eclipse.winery.topologymodeler/src/test/java/.gitkeep create mode 100644 pom.xml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..d64359bc1a --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +gradlew eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..698d54e230 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +.gradle/ +.idea/ +.project +.settings/org.eclipse.m2e.core.prefs +bin/ +build/ +release.properties +**/*.iml +**/hs_err_pid*.log +**/pom.xml.* +**/rebel.xml +target/ \ No newline at end of file diff --git a/LICENSE-ASL.txt b/LICENSE-ASL.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/LICENSE-ASL.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE-EPL.txt b/LICENSE-EPL.txt new file mode 100644 index 0000000000..5d80026f8e --- /dev/null +++ b/LICENSE-EPL.txt @@ -0,0 +1,227 @@ +Eclipse Public License - v 1.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF + THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + + 1. DEFINITIONS + + "Contribution" means: + + a) in the case of the initial Contributor, the initial code and + documentation distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + + i) changes to the Program, and + + ii) additions to the Program; + + where such changes and/or additions to the Program originate from and + are distributed by that particular Contributor. A Contribution + 'originates' from a Contributor if it was added to the Program by such + Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include additions to the Program which: (i) are + separate modules of software distributed in conjunction with the + Program under their own license agreement, and (ii) are not derivative + works of the Program. + + "Contributor" means any person or entity that distributes the Program. + + "Licensed Patents" mean patent claims licensable by a Contributor which + are necessarily infringed by the use or sale of its Contribution alone + or when combined with the Program. + + "Program" means the Contributions distributed in accordance with this + Agreement. + + "Recipient" means anyone who receives the Program under this Agreement, + including all Contributors. + + 2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare derivative works of, publicly display, + publicly perform, distribute and sublicense the Contribution of such + Contributor, if any, and such derivative works, in source code and + object code form. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, if + any, in source code and object code form. This patent license shall + apply to the combination of the Contribution and the Program if, at the + time the Contribution is added by the Contributor, such addition of the + Contribution causes such combination to be covered by the Licensed + Patents. The patent license shall not apply to any other combinations + which include the Contribution. No hardware per se is licensed + hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. Each + Contributor disclaims any liability to Recipient for claims brought by + any other entity based on infringement of intellectual property rights + or otherwise. As a condition to exercising the rights and licenses + granted hereunder, each Recipient hereby assumes sole responsibility to + secure any other intellectual property rights needed, if any. For + example, if a third party patent license is required to allow Recipient + to distribute the Program, it is Recipient's responsibility to acquire + that license before distributing the Program. + + d) Each Contributor represents that to its knowledge it has sufficient + copyright rights in its Contribution, if any, to grant the copyright + license set forth in this Agreement. + + 3. REQUIREMENTS + + A Contributor may choose to distribute the Program in object code form + under its own license agreement, provided that: + + a) it complies with the terms and conditions of this Agreement; and + + b) its license agreement: + + i) effectively disclaims on behalf of all Contributors all warranties + and conditions, express and implied, including warranties or conditions + of title and non-infringement, and implied warranties or conditions of + merchantability and fitness for a particular purpose; + + ii) effectively excludes on behalf of all Contributors all liability + for damages, including direct, indirect, special, incidental and + consequential damages, such as lost profits; + + iii) states that any provisions which differ from this Agreement are + offered by that Contributor alone and not by any other party; and + + iv) states that source code for the Program is available from such + Contributor, and informs licensees how to obtain it in a reasonable + manner on or through a medium customarily used for software exchange. + + When the Program is made available in source code form: + + a) it must be made available under this Agreement; and + + b) a copy of this Agreement must be included with each copy of the + Program. + + Contributors may not remove or alter any copyright notices contained + within the Program. + + Each Contributor must identify itself as the originator of its + Contribution, if any, in a manner that reasonably allows subsequent + Recipients to identify the originator of the Contribution. + + 4. COMMERCIAL DISTRIBUTION + + Commercial distributors of software may accept certain responsibilities + with respect to end users, business partners and the like. While this + license is intended to facilitate the commercial use of the Program, + the Contributor who includes the Program in a commercial product + offering should do so in a manner which does not create potential + liability for other Contributors. Therefore, if a Contributor includes + the Program in a commercial product offering, such Contributor + ("Commercial Contributor") hereby agrees to defend and indemnify every + other Contributor ("Indemnified Contributor") against any losses, + damages and costs (collectively "Losses") arising from claims, lawsuits + and other legal actions brought by a third party against the + Indemnified Contributor to the extent caused by the acts or omissions + of such Commercial Contributor in connection with its distribution of + the Program in a commercial product offering. The obligations in this + section do not apply to any claims or Losses relating to any actual or + alleged intellectual property infringement. In order to qualify, an + Indemnified Contributor must: a) promptly notify the Commercial + Contributor in writing of such claim, and b) allow the Commercial + Contributor to control, and cooperate with the Commercial Contributor + in, the defense and any related settlement negotiations. The + Indemnified Contributor may participate in any such claim at its own + expense. + + For example, a Contributor might include the Program in a commercial + product offering, Product X. That Contributor is then a Commercial + Contributor. If that Commercial Contributor then makes performance + claims, or offers warranties related to Product X, those performance + claims and warranties are such Commercial Contributor's responsibility + alone. Under this section, the Commercial Contributor would have to + defend claims against the other Contributors related to those + performance claims and warranties, and if a court requires any other + Contributor to pay any damages as a result, the Commercial Contributor + must pay those damages. + + 5. NO WARRANTY + + EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS + PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR + FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible + for determining the appropriateness of using and distributing the + Program and assumes all risks associated with its exercise of rights + under this Agreement , including but not limited to the risks and costs + of program errors, compliance with applicable laws, damage to or loss + of data, programs or equipment, and unavailability or interruption of + operations. + + 6. DISCLAIMER OF LIABILITY + + EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR + ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING + WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR + DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED + HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + 7. GENERAL + + If any provision of this Agreement is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability of + the remainder of the terms of this Agreement, and without further + action by the parties hereto, such provision shall be reformed to the + minimum extent necessary to make such provision valid and enforceable. + + If Recipient institutes patent litigation against any entity (including + a cross-claim or counterclaim in a lawsuit) alleging that the Program + itself (excluding combinations of the Program with other software or + hardware) infringes such Recipient's patent(s), then such Recipient's + rights granted under Section 2(b) shall terminate as of the date such + litigation is filed. + + All Recipient's rights under this Agreement shall terminate if it fails + to comply with any of the material terms or conditions of this + Agreement and does not cure such failure in a reasonable period of time + after becoming aware of such noncompliance. If all Recipient's rights + under this Agreement terminate, Recipient agrees to cease use and + distribution of the Program as soon as reasonably practicable. However, + Recipient's obligations under this Agreement and any licenses granted + by Recipient relating to the Program shall continue and survive. + + Everyone is permitted to copy and distribute copies of this Agreement, + but in order to avoid inconsistency the Agreement is copyrighted and + may only be modified in the following manner. The Agreement Steward + reserves the right to publish new versions (including revisions) of + this Agreement from time to time. No one other than the Agreement + Steward has the right to modify this Agreement. The Eclipse Foundation + is the initial Agreement Steward. The Eclipse Foundation may assign the + responsibility to serve as the Agreement Steward to a suitable separate + entity. Each new version of the Agreement will be given a + distinguishing version number. The Program (including Contributions) + may always be distributed subject to the version of the Agreement under + which it was received. In addition, after a new version of the + Agreement is published, Contributor may elect to distribute the Program + (including its Contributions) under the new version. Except as + expressly stated in Sections 2(a) and 2(b) above, Recipient receives no + rights or licenses to the intellectual property of any Contributor + under this Agreement, whether expressly, by implication, estoppel or + otherwise. All rights in the Program not expressly granted under this + Agreement are reserved. + + This Agreement is governed by the laws of the State of New York and the + intellectual property laws of the United States of America. No party to + this Agreement will bring a legal action under this Agreement more than + one year after the cause of action arose. Each party waives its rights + to a jury trial in any resulting litigation. diff --git a/README.md b/README.md new file mode 100644 index 0000000000..512afc6898 --- /dev/null +++ b/README.md @@ -0,0 +1,164 @@ +# Winery +Winery is a Web-based environment to graphically model TOSCA topologies and plans managing these topologies. +It is an Eclipse project and thus support is available through it's project page https://projects.eclipse.org/projects/soa.winery. +Winery is also part of the OpenTOSCA ecosystem where more information is available at http://www.opentosca.org. + +**The code and the linked libraries are NOT approved by Eclipse Legal. Dependencies are fetched from external mirrors and not from an Eclipse repository.** + +## Runtime Requirements +* Java 7 +* Servlet 3.0 capable container (e.g., Tomcat 7) + +## Development Information + +Winery uses maven and [bower] for fetching dependencies and building. +Bower has to be installed manually as described in the next section. + +## Install bower + +1. Install [nodejs]. Just use the latest version to get the latest node package manager (npm). +1. Run `npm install -g bower` +1. Ensure that `git` is in your path: Some javascript libraries are fetched via git. + +## Making the wars +Run `mvn clean package`. +In case [bower] fails, try to investigate using `mvn package -X`. +You can start bower manually in `org.eclipse.winery.repository` and `org.eclipse.winery.topologymodeler` by issuing `bower install`. + +## Branches +The `master` branch is always compiling and all tests should go through. +It contains the most recent improvements. +All other branches are real development branches and might event not compile. + +There are no explicit branches for stable versions as winery is currently in development-only mode. + +## Projects + +### Model projects +Each of these projects are versioned separatedly. + +* org.eclipse.winery.model.csar.toscametafile: model for TOSCA meta files contained in a CSAR +* org.eclipse.winery.model.selfservice: model for the self service portal +* org.eclipse.winery.model.tosca: model for TOCSA + +### Support projects +* org.eclipse.winery.highlevelrestapi: support library to REST calls + +### Winery itself +Versioned together to ease development. + +* org.eclipse.winery.common: Used in repository and topology modeler +* org.eclipse.winery.generators.ia: Implementation Artifact Generator, used as component in the repository +* org.eclipse.winery.repository: the repository including a JSP-based UI +* org.eclipse.winery.repository.client: Java-client for the repository +* org.eclipse.winery.topologymodeler: Graph-based modeler for topology templates + +## Next steps +Winery currently is far from being a production ready modeling tool. +The next steps are: + +* UI design improvements +** Have Orion support `XML` as language. See also [Bug 421284][bug421284] +* Add more usability features to the topology modeler +* Remove non-required files from components/ directory to reduce the file size of the WAR file +** This has to be done by submitting patches to `bower.json` of the upstream libraries +* Develop a plugin-system for user-defined editors. For instance, a constraint has a type. If a type is known to Winery, it can present a specific plugin to edit the type content instead of a generic XML editor. +* Rework file storage. Currently, files are stored along with their definitions. A new storage should store all files in one place and use an SHA1 id to uniquely identify the file. Then, it does not make any difference if storing a WAR, an XSD, or an WSDL. +* Add a real DAO layer to enable querying the available TOSCA contents using SQL or similar query language + +Currently, `.jsp` files package HTML and JS. +We plan to use frameworks such as [TerrificJS] to provide a better modularity. +This follows Nicholas Zakas' "[Scalable JavaScript Application Architecture]". + +## Known issues +* XSD Type declarations are not directly supported +** Declared types are converted to imports during a CSAR Import +** Editing of XSDs is not possible +* **The XSD of OASIS TOSCA v1.0 has been modified** +** An Implementation Artifact may carry a `name` attribute +** The contents of properties of Boundary Definitions are processed in `lax` mode + +## Eclipse setup +This howto is based on [Eclipse Standard 4.3]. +First of all, genreate a war to have all dependencies fetched by maven. + +### Required plugins +** JST Server Adapters Extensions +** Eclipse Java EE Developer Tools +** Eclipse Java Web Developer Tools +** [m2e-wtp]: Maven Integration for WTP +** [AnyEdit][http://andrei.gmxhome.de/anyedit/] for ensuring that tabs are always used +*** Configure: Window -> Preferences -> General / Editors / AnyEdit Tools -> "Auto - Convert EXCLUSION file list" -> "Add filter" -> "*.java", "Convert...": 4 spaces for a tab + +### Optional Plugins +** [Eclipse Code Recommenders][http://www.eclipse.org/recommenders/] +** [VJET JavaScript IDE][http://www.eclipse.org/proposals/webtools.vjet/] + +### Make Winery projects known to Eclipse +1. Import all projects +** Use "Existing Maven Projects". `mvn eclips:m2eclipse` currently does not enable "maven" in eclipse. +2. For each project: right click, –> Team –> Share Project –> Git –> Next –> check "Use or create repository in parent folder of project" –> Finish + +### Setup Tomcat +1. Open servers window: Window -> Show View -> Other -> Server -> Servers +2. New server wizard... -> Apache -> Tomcat v7.0 Server -> Next -> Winery -> Add -> Finish +3. Rename the Server to "Apache Tomcat v7.0" + +Now you can see the Tomcat v7.0 Server at localhost [Stopped, Republish] in your server window. +Select it and click on the green play button in the window. + +Now winery can be viewed at http://localhost:8080/winery/ + +### Configure Winery (optional) +The repository location can be changed: +Copy `winery.properties` to `path-to-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\winery`. + +### Trouble shooting +* In case some JavaScript libraries cannot be found by the browser, execute `bower prune`, `bower install`, `bower update` in both `org.eclipse.winery.repository` and `org.eclipse.winery.topologymodeler`. +* See [README.md of the repository](org.eclipse.winery.repository/README.md) +* See [README.md of the topology modeler](org.eclipse.winery.topologymodeler/README.md) + +#### Libraries + +* Do NOT update to jQuery 2.1.0. When using with firefox, line 5571 in jquery.js fails: `divStyle is null`. That means `window.getComputedStyle( div, null );` returned null, too. +* Do NOT update to jsPlumb 1.5.5. The new connection type determination does not play well together with Winery's usage of jsPlumb. + +## Acknowledgements +The initial code contribution has been supported by the [Federal Ministry of Economics and Technology] as part of the [CloudCycle project] (01MD11023). + +## License +Copyright (c) 2012-2014 University of Stuttgart. + +All rights reserved. This program and the accompanying materials +are made available under the terms of the [Eclipse Public License v1.0] +and the [Apache License v2.0] which both accompany this distribution, +and are available at http://www.eclipse.org/legal/epl-v10.html +and http://www.apache.org/licenses/LICENSE-2.0 + +Contributors: +* Oliver Kopp - initial API and implementation + +## Literature + +### About TOSCA +* Binz, T., Breiter, G., Leymann, F., Spatzier, T.: Portable Cloud Services Using TOSCA. IEEE Internet Computing 16(03), 80{85 (May 2012) +* Topology and Orchestration Specification for Cloud Applications Version 1.0. 25 November 2013. OASIS Standard. http://docs.oasis-open.org/tosca/TOSCA/v1.0/os/TOSCA-v1.0-os.html +* OASIS: Topology and Orchestration Specfication for Cloud Applications (TOSCA) Primer Version 1.0 (2013) + +See http://www.opentosca.org/#publications for a list of publications in the OpenTOSCA ecosystem. + +### Programming +* Joshua Bloch. Effective Java, 2nd edition. Addison-Wesley + + [bug421284]: https://bugs.eclipse.org/bugs/show_bug.cgi?id=421284 + [bower]: https://github.com/bower/bower + [nodejs]: http://nodejs.org/download/ + [Eclipse Public License v1.0]: http://www.eclipse.org/legal/epl-v10.html + [Eclipse Standard 4.3]: http://www.eclipse.org/downloads/ + [Apache License v2.0]: http://www.apache.org/licenses/LICENSE-2.0.html + [Federal Ministry of Economics and Technology]: http://www.bmwi.de/EN/root.html + [CloudCycle project]: http://www.cloudcycle.org/en/ + [m2eclipse]: http://eclipse.org/m2e/ + {m2e-wtp]: http://eclipse.org/m2e-wtp/ + [TerrificJS]: http://terrifically.org/ + [Scalable JavaScript Application Architecture]: http://www.slideshare.net/nzakas/scalable-javascript-application-architecture-2012 diff --git a/notice.html b/notice.html new file mode 100644 index 0000000000..f19c483b9c --- /dev/null +++ b/notice.html @@ -0,0 +1,108 @@ + + + + + +Eclipse Foundation Software User Agreement + + + +

Eclipse Foundation Software User Agreement

+

February 1, 2011

+ +

Usage Of Content

+ +

THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

+ +

Applicable Licenses

+ +

Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

+ +

Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code + repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").

+ + + +

The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

+ + + +

Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

+ +

THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

+ + + +

IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

+ + +

Use of Provisioning Technology

+ +

The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse + Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or + other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to + install, extend and update Eclipse-based products. Information about packaging Installable Software is available at http://eclipse.org/equinox/p2/repository_packaging.html + ("Specification").

+ +

You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the + applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology + in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the + Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:

+ +
    +
  1. A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology + on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based + product.
  2. +
  3. During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be + accessed and copied to the Target Machine.
  4. +
  5. Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable + Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target + Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern + the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such + indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.
  6. +
+ +

Cryptography

+ +

Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

+ +

Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.

+ + diff --git a/org.eclipse.winery.common/.gitignore b/org.eclipse.winery.common/.gitignore new file mode 100644 index 0000000000..4cac871a1d --- /dev/null +++ b/org.eclipse.winery.common/.gitignore @@ -0,0 +1,14 @@ +/.gradle +.classpath +.project +.settings/org.eclipse.core.resources.prefs +.settings/org.eclipse.jdt.core.prefs +.settings/org.eclipse.m2e.core.prefs +.settings/org.eclipse.wst.common.component +.settings/org.eclipse.wst.common.project.facet.core.xml +.settings/org.eclipse.wst.validation.prefs +/.sonar +/bin +/build +/src/main/resources/rebel.xml +/target diff --git a/org.eclipse.winery.common/about.html b/org.eclipse.winery.common/about.html new file mode 100644 index 0000000000..a235f0bf96 --- /dev/null +++ b/org.eclipse.winery.common/about.html @@ -0,0 +1,143 @@ + + + + +About + + +

About This Content

+ +

January 24, 2014

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in (“Content”). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 (“EPL”) +and Apache License Version 2.0. +A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html +and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php. +You may elect to redistribute this code under either of these licenses. +For purposes of the EPL, “Program” will mean the Content. +

+ +

+If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party (“Redistributor”) and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor’s license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL and Apache License 2.0 still apply to any source code +in the Content and such source code may be obtained at http://www.eclipse.org. +

+ +

Third Party Content

+ +

Java Libraries

+ +
Apache Commons IO – Version 2.1
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-io/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Apache Commons Lang3 – Version 3.1
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-lang/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
JSP Standard Tag Library – Version 1.2
+ + + + + + + + + +
URLhttps://jstl.java.net/
LicenseCDDL and GPL with classpath exception (https://jersey.java.net/license.html). + The Eclipse Foundation elects to include this software in this distribution under the CDDL license. + A copy of the license is available at CDDL-v1.1.txt.
+ +
Logback Classic – Version 1.1.1
+ + + + + + + + + +
URLhttp://logback.qos.ch/
LicenseEPL/LGPL dual license. + EPL: http://www.eclipse.org/legal/epl-v10.html. + LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1. + A copy of the license is contained in the file LICENSE-logback.txt and is also available at http://logback.qos.ch/license.html. + The Eclipse Foundation elects to include this software in this distribution under the EPL license.
+ +
Logback Core – Version 1.1.1
+ + + + + + + + + +
URLhttp://logback.qos.ch/
LicenseEPL/LGPL dual license. + EPL: http://www.eclipse.org/legal/epl-v10.html. + LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1. + A copy of the license is contained in the file LICENSE-logback.txt and is also available at http://logback.qos.ch/license.html. + The Eclipse Foundation elects to include this software in this distribution under the EPL license.
+ +
SLF4J: slf4j-api – Version 1.7.6
+ + + + + + + + + +
URLhttp://www.slf4j.org/
LicenseMIT. A copy of the license is contained in the file LICENSE-slf4j-api.txt and is also available at http://www.slf4j.org/license.html
+ +
SLF4J: jcl-over-slf4j – Version 1.7.6
+ + + + + + + + + +
URLhttp://www.slf4j.org/legacy.html
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Winery: org.eclipse.winery.model.tosca – Version 0.1.20
+ + + + + + + + + +
URLhttp://eclipse.org/winery/
LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
+ + + \ No newline at end of file diff --git a/org.eclipse.winery.common/about_files/Apache-LICENSE-2.0.txt b/org.eclipse.winery.common/about_files/Apache-LICENSE-2.0.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/org.eclipse.winery.common/about_files/Apache-LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/org.eclipse.winery.common/about_files/CDDL-v1.1.txt b/org.eclipse.winery.common/about_files/CDDL-v1.1.txt new file mode 100644 index 0000000000..7cc8719b3b --- /dev/null +++ b/org.eclipse.winery.common/about_files/CDDL-v1.1.txt @@ -0,0 +1,129 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL - Version 1.1) +1. Definitions. + + 1.1. “Contributor” means each individual or entity that creates or contributes to the creation of Modifications. + + 1.2. “Contributor Version” means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. + + 1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. + + 1.4. “Executable” means the Covered Software in any form other than Source Code. + + 1.5. “Initial Developer” means the individual or entity that first makes Original Software available under this License. + + 1.6. “Larger Work” means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. + + 1.7. “License” means this document. + + 1.8. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. + + 1.9. “Modifications” means the Source Code and Executable form of any of the following: + + A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; + + B. Any new file that contains any part of the Original Software or previous Modification; or + + C. Any new file that is contributed or otherwise made available under the terms of this License. + + 1.10. “Original Software” means the Source Code and Executable form of computer software code that is originally released under this License. + + 1.11. “Patent Claims” means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. + + 1.12. “Source Code” means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. + + 1.13. “You” (or “Your”) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, “You” includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients’ rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient’s rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. + +4. Versions of the License. + + 4.1. New Versions. + + Oracle is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. + +5. DISCLAIMER OF WARRANTY. + +COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as “Participant”) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. + + 6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. + + 6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY’S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. +8. U.S. GOVERNMENT END USERS. + +The Covered Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer software” (as that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software documentation” as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. +9. MISCELLANEOUS. + +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction’s conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys’ fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. +10. RESPONSIBILITY FOR CLAIMS. + +As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. \ No newline at end of file diff --git a/org.eclipse.winery.common/about_files/LICENSE-logback.txt b/org.eclipse.winery.common/about_files/LICENSE-logback.txt new file mode 100644 index 0000000000..b4fe24e02a --- /dev/null +++ b/org.eclipse.winery.common/about_files/LICENSE-logback.txt @@ -0,0 +1,15 @@ +Logback LICENSE +--------------- + +Logback: the reliable, generic, fast and flexible logging framework. +Copyright (C) 1999-2012, QOS.ch. All rights reserved. + +This program and the accompanying materials are dual-licensed under +either the terms of the Eclipse Public License v1.0 as published by +the Eclipse Foundation + + or (per the licensee's choosing) + +under the terms of the GNU Lesser General Public License version 2.1 +as published by the Free Software Foundation. + diff --git a/org.eclipse.winery.common/about_files/LICENSE-slf4j-api.txt b/org.eclipse.winery.common/about_files/LICENSE-slf4j-api.txt new file mode 100644 index 0000000000..37050c9568 --- /dev/null +++ b/org.eclipse.winery.common/about_files/LICENSE-slf4j-api.txt @@ -0,0 +1,21 @@ + Copyright (c) 2004-2013 QOS.ch + All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.common/pom.xml b/org.eclipse.winery.common/pom.xml new file mode 100644 index 0000000000..e5fa562ca1 --- /dev/null +++ b/org.eclipse.winery.common/pom.xml @@ -0,0 +1,90 @@ + + + + 4.0.0 + + org.eclipse.winery + winery + 0.1.37-SNAPSHOT + + org.eclipse.winery.common + + UTF-8 + + + + ch.qos.logback + logback-classic + 1.1.1 + compile + + + org.eclipse.winery + org.eclipse.winery.model.tosca + 0.1.20 + compile + + + org.slf4j + jcl-over-slf4j + 1.7.6 + compile + + + jstl + jstl + 1.2 + compile + + + commons-io + commons-io + 2.1 + compile + + + commons-logging + commons-logging + + + + + org.apache.commons + commons-lang3 + 3.1 + compile + + + junit + junit + 4.11 + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + + + + + diff --git a/org.eclipse.winery.common/sonar-project.properties b/org.eclipse.winery.common/sonar-project.properties new file mode 100644 index 0000000000..09b7e2fb4b --- /dev/null +++ b/org.eclipse.winery.common/sonar-project.properties @@ -0,0 +1,24 @@ +# required metadata +sonar.projectKey=org.eclipse.winery.common +sonar.projectName=org.eclipse.winery.common +sonar.projectVersion=0.1.2 + +# path to source directories (required) +sonar.sources=src/main/java + +# path to test source directories (optional) +#sonar.tests= + +# path to project binaries (optional), for example directory of Java bytecode +#sonar.binaries=binDir + +# optional comma-separated list of paths to libraries. Only path to JAR file and path to directory of classes are supported. +#sonar.libraries=org.eclipse.jgit-2.1.0.201209190230-r.jar + +# The value of the property must be the key of the language. +sonar.language=java + +# enforece Java 1.7 to enable analysis of diamon operator by PMD +sonar.java.source=1.7 + +sonar.sourceEncoding=UTF-8 diff --git a/org.eclipse.winery.common/src/main/java/META-INF/MANIFEST.MF b/org.eclipse.winery.common/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ModelUtilities.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ModelUtilities.java new file mode 100644 index 0000000000..f9944b820c --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ModelUtilities.java @@ -0,0 +1,554 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common; + +import java.lang.reflect.Method; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.constants.Namespaces; +import org.eclipse.winery.common.constants.QNames; +import org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKV; +import org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKVList; +import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions; +import org.eclipse.winery.model.tosca.TCapability; +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.model.tosca.TEntityType; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TNodeTemplate; +import org.eclipse.winery.model.tosca.TNodeTemplate.Capabilities; +import org.eclipse.winery.model.tosca.TNodeTemplate.Requirements; +import org.eclipse.winery.model.tosca.TNodeType; +import org.eclipse.winery.model.tosca.TPlan; +import org.eclipse.winery.model.tosca.TPlans; +import org.eclipse.winery.model.tosca.TRelationshipTemplate; +import org.eclipse.winery.model.tosca.TRelationshipType; +import org.eclipse.winery.model.tosca.TRequirement; +import org.eclipse.winery.model.tosca.TServiceTemplate; +import org.eclipse.winery.model.tosca.TTopologyTemplate; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +public class ModelUtilities { + + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ModelUtilities.class); + + + /** + * This is a special method for Winery. Winery allows to define a property + * definition by specifying name/type values. Instead of parsing the + * extensible elements returned TDefinitions, this method is a convenience + * method to access this information + * + * @param t the entitytype to read the properties definition from + * @return a WinerysPropertiesDefinition object, which includes a map of + * name/type-pairs denoting the associated property definitions. A + * default element name and namespace is added if it is not defined + * in the underlying XML. null if no Winery specific KV properties + * are defined for the given entity type + */ + public static WinerysPropertiesDefinition getWinerysPropertiesDefinition(TEntityType et) { + // similar implementation as org.eclipse.winery.repository.resources.entitytypes.properties.PropertiesDefinitionResource.getListFromEntityType(TEntityType) + WinerysPropertiesDefinition res = null; + for (Object o : et.getAny()) { + if (o instanceof WinerysPropertiesDefinition) { + res = (WinerysPropertiesDefinition) o; + } + } + + if (res != null) { + // we put defaults if elementname and namespace have not been set + + if (res.getElementName() == null) { + res.setElementName("Properties"); + } + + if (res.getNamespace() == null) { + // we use the targetnamespace of the original element + String ns = et.getTargetNamespace(); + if (!ns.endsWith("/")) { + ns += "/"; + } + ns += "propertiesdefinition/winery"; + res.setNamespace(ns); + } + } + + return res; + } + + /** + * This is a special method for Winery. Winery allows to define a property + * by specifying name/value values. Instead of parsing the XML contained in + * TNodeType, this method is a convenience method to access this information + * + * The return type "Properties" is used because of the key/value properties. + * + * @param template the node template to get the associated properties + */ + public static Properties getPropertiesKV(TEntityTemplate template) { + Properties properties = new Properties(); + org.eclipse.winery.model.tosca.TEntityTemplate.Properties tprops = template.getProperties(); + if (tprops != null) { + // no checking for validity, just reading + Element el = (Element) tprops.getAny(); + if (el == null) { + // somehow invalid .tosca. We return empty properties instead of throwing a NPE + return properties; + } + NodeList childNodes = el.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.item(i); + if (item instanceof Element) { + String key = item.getLocalName(); + String value = item.getTextContent(); + properties.put(key, value); + } + } + } + return properties; + } + + /** + * This is a special method for Winery. Winery allows to define a property + * by specifying name/value values. We convert the given Properties to XML. + * + * @param wpd the Winery's properties definition of the type of the given + * template (i.e., wpd = + * getWinerysPropertiesDefinition(template.getType())) + * @param template the node template to set the associated properties + */ + public static void setPropertiesKV(WinerysPropertiesDefinition wpd, TEntityTemplate template, Properties properties) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db; + try { + db = dbf.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + ModelUtilities.logger.debug(e.getMessage(), e); + throw new IllegalStateException("Could not instantiate document builder", e); + } + Document doc = db.newDocument(); + + Element root = doc.createElementNS(wpd.getNamespace(), wpd.getElementName()); + doc.appendChild(root); + + // we produce the serialization in the same order the XSD would be generated (because of the usage of xsd:sequence) + for (PropertyDefinitionKV prop : wpd.getPropertyDefinitionKVList()) { + // we always write the element tag as the XSD forces that + Element element = doc.createElementNS(wpd.getNamespace(), prop.getKey()); + root.appendChild(element); + String value = properties.getProperty(prop.getKey()); + if (value != null) { + Text text = doc.createTextNode(value); + element.appendChild(text); + } + } + + org.eclipse.winery.model.tosca.TEntityTemplate.Properties tprops = new org.eclipse.winery.model.tosca.TEntityTemplate.Properties(); + tprops.setAny(doc.getDocumentElement()); + template.setProperties(tprops); + } + + /** + * Generates a XSD when Winery's K/V properties are used. This method is put + * here instead of WinerysPropertiesDefinitionResource to avoid generating + * the subresource + * + * public because of the usage by TOSCAEXportUtil + * + * @return empty Document, if Winery's Properties Definition is not fully + * filled (e.g., no wrapping element defined) + */ + public static Document getWinerysPropertiesDefinitionXSDAsDocument(WinerysPropertiesDefinition wpd) { + /* + * This is a quick hack: an XML schema container is created for each + * element. Smarter solution: create a hash from namespace to XML schema + * element and re-use that for each new element + * Drawback of "smarter" solution: not a single XSD file any more + */ + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder; + try { + docBuilder = docFactory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + ModelUtilities.logger.debug(e.getMessage(), e); + throw new IllegalStateException("Could not instantiate document builder", e); + } + Document doc = docBuilder.newDocument(); + + if (!ModelUtilities.allRequiredFieldsNonNull(wpd)) { + // wpd not fully filled -> valid XSD cannot be provided + // fallback: add comment and return "empty" document + Comment comment = doc.createComment("Required fields are missing in Winery's key/value properties definition."); + doc.appendChild(comment); + return doc; + } + + // create XSD schema container + Element schemaElement = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "schema"); + doc.appendChild(schemaElement); + schemaElement.setAttribute("elementFormDefault", "qualified"); + schemaElement.setAttribute("attributeFormDefault", "unqualified"); + schemaElement.setAttribute("targetNamespace", wpd.getNamespace()); + + // create XSD element itself + Element el = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "element"); + schemaElement.appendChild(el); + el.setAttribute("name", wpd.getElementName()); + Element el2 = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "complexType"); + el.appendChild(el2); + el = el2; + el2 = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "sequence"); + el.appendChild(el2); + el = el2; + + // currently, "xsd" is a hardcoded prefix in the type definition + el.setAttribute("xmlns:xsd", XMLConstants.W3C_XML_SCHEMA_NS_URI); + + for (PropertyDefinitionKV prop : wpd.getPropertyDefinitionKVList()) { + el2 = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "element"); + el.appendChild(el2); + el2.setAttribute("name", prop.getKey()); + // prop.getType has the prefix included + el2.setAttribute("type", prop.getType()); + } + + return doc; + } + + /** + * Removes an existing Winery's Properties definition. If no such definition + * exists, the TEntityType is not modified + */ + public static void removeWinerysPropertiesDefinition(TEntityType et) { + for (Iterator iterator = et.getAny().iterator(); iterator.hasNext();) { + Object o = iterator.next(); + if (o instanceof WinerysPropertiesDefinition) { + iterator.remove(); + break; + } + } + } + + public static void replaceWinerysPropertiesDefinition(TEntityType et, WinerysPropertiesDefinition wpd) { + ModelUtilities.removeWinerysPropertiesDefinition(et); + et.getAny().add(wpd); + } + + public static String getBorderColor(TNodeType nt) { + String borderColor = nt.getOtherAttributes().get(QNames.QNAME_BORDER_COLOR); + if (borderColor == null) { + borderColor = Util.getColor(nt.getName()); + } + return borderColor; + } + + public static String getColor(TRelationshipType rt) { + String color = rt.getOtherAttributes().get(QNames.QNAME_COLOR); + if (color == null) { + color = Util.getColor(rt.getName()); + } + return color; + } + + /** + * Returns the Properties. If no properties exist, the element is created + * + * @return + */ + public static org.eclipse.winery.model.tosca.TBoundaryDefinitions.Properties getProperties(TBoundaryDefinitions defs) { + org.eclipse.winery.model.tosca.TBoundaryDefinitions.Properties properties = defs.getProperties(); + if (properties == null) { + properties = new org.eclipse.winery.model.tosca.TBoundaryDefinitions.Properties(); + defs.setProperties(properties); + } + return properties; + } + + /** + * Special method to get the name of an extensible element as the TOSCA + * specification does not have a separate super type for elements with a + * name + * + * {@link + * org.eclipse.winery.common.Util.instanceSupportsNameAttribute(Class)} is related + * + * @param e the extensible element offering a name attribute (besides an id + * attribute) + * @return the name of the extensible element + * @throws IllegalStateException if e does not offer the method "getName" + */ + public static String getName(TExtensibleElements e) { + Method method; + Object res; + try { + method = e.getClass().getMethod("getName"); + res = method.invoke(e); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + return (String) res; + } + + /** + * Returns the name of the given element. If the name does not exist or is + * empty, the id is returned + * + * {@see getName} + * + * @return the name if there is a name field, if not, the id is returned. In + * case there is a Name field, + */ + public static String getNameWithIdFallBack(TExtensibleElements ci) { + Method method; + String res = null; + try { + method = ci.getClass().getMethod("getName"); + res = (String) method.invoke(ci); + } catch (Exception e) { + } + if (StringUtils.isEmpty(res)) { + try { + method = ci.getClass().getMethod("getId"); + res = (String) method.invoke(ci); + } catch (Exception e2) { + throw new IllegalStateException(e2); + } + } + return res; + } + + /** + * Special method to set the name of an extensible element as the TOSCA + * specification does not have a separate super type for elements with a + * name + * + * @param e the extensible element offering a name attribute (besides an id + * attribute) + * @param name the new name + * @throws IllegalStateException if e does not offer the method "getName" + */ + public static void setName(TExtensibleElements e, String name) { + Method method; + try { + method = e.getClass().getMethod("setName", String.class); + method.invoke(e, name); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + + public static boolean allRequiredFieldsNonNull(WinerysPropertiesDefinition wpd) { + boolean valid = wpd.getNamespace() != null; + valid = valid && (wpd.getElementName() != null); + if (valid) { + PropertyDefinitionKVList propertyDefinitionKVList = wpd.getPropertyDefinitionKVList(); + valid = (propertyDefinitionKVList != null); + if (valid) { + for (PropertyDefinitionKV def : propertyDefinitionKVList) { + valid = valid && (def.getKey() != null); + valid = valid && (def.getType() != null); + } + } + } + return valid; + } + + /** + * @return null if no explicit left is set + */ + public static String getLeft(TNodeTemplate nodeTemplate) { + Map otherAttributes = nodeTemplate.getOtherAttributes(); + String left = otherAttributes.get(new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "x")); + return left; + } + + /** + * @return null if no explicit left is set + */ + public static String getTop(TNodeTemplate nodeTemplate) { + Map otherAttributes = nodeTemplate.getOtherAttributes(); + String top = otherAttributes.get(new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "y")); + return top; + } + + /** + * locates targetObjectRef inside a topology template + * + * @param topologyTemplate the topology template to search in + * @param targetObjectRef the object ref as String + * + * @return null if not found, otherwise the entity template in the topology + */ + public static TEntityTemplate findNodeTemplateOrRequirementOfNodeTemplateOrCapabilityOfNodeTemplateOrRelationshipTemplate(TTopologyTemplate topologyTemplate, String targetObjectRef) { + // We cannot use XMLs id pointing capabilities as we work on the Java model + // Other option: modify the stored XML directly. This is more error prune than walking through the whole topology + for (TEntityTemplate t : topologyTemplate.getNodeTemplateOrRelationshipTemplate()) { + if (t instanceof TNodeTemplate) { + if (t.getId().equals(targetObjectRef)) { + return t; + } + TNodeTemplate nt = (TNodeTemplate) t; + + Requirements requirements = nt.getRequirements(); + if (requirements != null) { + for (TRequirement req : requirements.getRequirement()) { + if (req.getId().equals(targetObjectRef)) { + return req; + } + } + } + + Capabilities capabilities = nt.getCapabilities(); + if (capabilities != null) { + for (TCapability cap : capabilities.getCapability()) { + if (cap.getId().equals(targetObjectRef)) { + return cap; + } + } + } + + } else { + assert (t instanceof TRelationshipTemplate); + if (t.getId().equals(targetObjectRef)) { + return t; + } + } + } + + // no return hit inside the loop: nothing was found + return null; + } + + /** + * Returns the id of the given element + * + * The TOSCA specification does NOT always put an id field. In the case of + * EntityTypes and EntityTypeImplementations, there is no id, but a name + * field + * + * This method abstracts from that fact. + */ + public static String getId(TExtensibleElements ci) { + Method method; + Object res; + try { + method = ci.getClass().getMethod("getId"); + res = method.invoke(ci); + } catch (Exception e) { + // If no "getId" method is there, we try "getName" + try { + method = ci.getClass().getMethod("getName"); + res = method.invoke(ci); + } catch (Exception e2) { + throw new IllegalStateException(e2); + } + } + return (String) res; + } + + /** + * Resolves a given id as requirement in the given ServiceTemplate + * + * @return null if not found + */ + public static TRequirement resolveRequirement(TServiceTemplate serviceTemplate, String reference) { + TRequirement resolved = null; + for (TEntityTemplate tmpl : serviceTemplate.getTopologyTemplate().getNodeTemplateOrRelationshipTemplate()) { + if (tmpl instanceof TNodeTemplate) { + TNodeTemplate n = (TNodeTemplate) tmpl; + Requirements requirements = n.getRequirements(); + if (requirements != null) { + for (TRequirement req : n.getRequirements().getRequirement()) { + if (req.getId().equals(reference)) { + resolved = req; + } + } + } + } + } + return resolved; + } + + public static TCapability resolveCapability(TServiceTemplate serviceTemplate, String reference) { + TCapability resolved = null; + for (TEntityTemplate tmpl : serviceTemplate.getTopologyTemplate().getNodeTemplateOrRelationshipTemplate()) { + if (tmpl instanceof TNodeTemplate) { + TNodeTemplate n = (TNodeTemplate) tmpl; + Capabilities capabilities = n.getCapabilities(); + if (capabilities != null) { + for (TCapability cap : n.getCapabilities().getCapability()) { + if (cap.getId().equals(reference)) { + resolved = cap; + } + } + } + } + } + return resolved; + } + + public static TNodeTemplate resolveNodeTemplate(TServiceTemplate serviceTemplate, String reference) { + TNodeTemplate resolved = null; + for (TEntityTemplate tmpl : serviceTemplate.getTopologyTemplate().getNodeTemplateOrRelationshipTemplate()) { + if (tmpl instanceof TNodeTemplate) { + TNodeTemplate n = (TNodeTemplate) tmpl; + if (n.getId().equals(reference)) { + resolved = n; + } + } + } + return resolved; + } + + public static TRelationshipTemplate resolveRelationshipTemplate(TServiceTemplate serviceTemplate, String reference) { + TRelationshipTemplate resolved = null; + for (TEntityTemplate tmpl : serviceTemplate.getTopologyTemplate().getNodeTemplateOrRelationshipTemplate()) { + if (tmpl instanceof TRelationshipTemplate) { + TRelationshipTemplate n = (TRelationshipTemplate) tmpl; + if (n.getId().equals(reference)) { + resolved = n; + } + } + } + return resolved; + } + + public static TPlan resolvePlan(TServiceTemplate serviceTemplate, String reference) { + TPlan resolved = null; + TPlans plans = serviceTemplate.getPlans(); + if (plans == null) { + return null; + } + for (TPlan p : plans.getPlan()) { + if (p.getId().equals(reference)) { + resolved = p; + } + } + return resolved; + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/RepositoryFileReference.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/RepositoryFileReference.java new file mode 100644 index 0000000000..68fb22f315 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/RepositoryFileReference.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common; + +import org.eclipse.winery.common.ids.GenericId; + +/** + * Holds a reference to a file "object" stored in the repository + * + * Directories are NOT supported as we would have to reflect parent + * relationships there, too. + * + * One has to create TOSCAelementId-objects for directories (e.g., scc-data) + */ +public class RepositoryFileReference implements Comparable { + + protected final GenericId parent; + protected final String fileName; + + + /** + * @param parent the id of the toscaElement the file is nested in + * @param fileName the file name. Must not contain any illegal + * characters. java.nio.Path cannot be used as Path is tied to a + * FileSystem + */ + public RepositoryFileReference(GenericId parent, String fileName) { + if (parent == null) { + throw new IllegalArgumentException("Parent must not be null."); + } + if (fileName == null) { + throw new IllegalArgumentException("Filename must not be null."); + } + this.parent = parent; + this.fileName = fileName; + } + + public GenericId getParent() { + return this.parent; + } + + public String getFileName() { + return this.fileName; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof RepositoryFileReference) { + RepositoryFileReference otherRef = (RepositoryFileReference) obj; + return (otherRef.fileName.equals(this.fileName)) && (otherRef.getParent().equals(this.getParent())); + } else { + return false; + } + } + + @Override + public int hashCode() { + return this.getParent().hashCode() ^ this.getFileName().hashCode(); + } + + @Override + public int compareTo(RepositoryFileReference o) { + int res; + res = this.parent.compareTo(o.parent); + if (res == 0) { + res = this.fileName.compareTo(o.fileName); + } + return res; + } + + @Override + public String toString() { + return this.getParent().toString() + "/" + this.getFileName(); + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/StringEncodedAndDecoded.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/StringEncodedAndDecoded.java new file mode 100644 index 0000000000..cac7a44a06 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/StringEncodedAndDecoded.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common; + + + +/** + * Meta class to handle things, where a String (URI, NCName, ...) may be + * URLencoded + */ +public class StringEncodedAndDecoded implements Comparable { + + private String decoded = null; + private String encoded = null; + + + /** + * @param uri the URI to store + * @param URLencoded true iff the given URI is URLencoded + */ + public StringEncodedAndDecoded(String uri, boolean URLencoded) { + if (URLencoded) { + this.encoded = uri; + } else { + this.decoded = uri; + } + } + + public String getDecoded() { + if (this.decoded == null) { + this.decoded = Util.URLdecode(this.encoded); + } + return this.decoded; + } + + public String getEncoded() { + if (this.encoded == null) { + this.encoded = Util.URLencode(this.decoded); + } + return this.encoded; + } + + @Override + public int hashCode() { + return this.getDecoded().hashCode(); + } + + /** + * @return the URL path fragment to be used in an URL + */ + public String getPathFragment() { + return this.getEncoded(); + } + + @Override + public String toString() { + return this.getDecoded(); + } + + @Override + public int compareTo(StringEncodedAndDecoded o) { + return this.getDecoded().compareTo(o.getDecoded()); + } + + /** + * Compares with the given object
+ * Equality checking is made based on the decoded String + */ + @Override + public boolean equals(Object o) { + if (o instanceof String) { + return this.getDecoded().equals(o); + } else if (o instanceof StringEncodedAndDecoded) { + return ((StringEncodedAndDecoded) o).getDecoded().equals(this.getDecoded()); + } else { + return false; + } + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/TOSCADocumentBuilderFactory.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/TOSCADocumentBuilderFactory.java new file mode 100644 index 0000000000..74a0e26748 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/TOSCADocumentBuilderFactory.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common; + +import java.net.URL; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; + +/** + * Class to produce DocumentBuilders with a pre-loaded TOSCA XSD. + * + * In a separate class as TOSCA XSD loading takes a few seconds + */ +public class TOSCADocumentBuilderFactory { + + private static final Logger logger = LoggerFactory.getLogger(TOSCADocumentBuilderFactory.class); + + public static final TOSCADocumentBuilderFactory INSTANCE = new TOSCADocumentBuilderFactory(); + private final DocumentBuilderFactory factory; + + + public TOSCADocumentBuilderFactory() { + this.factory = DocumentBuilderFactory.newInstance(); + + this.factory.setNamespaceAware(true); + + // we do not need DTD validation + this.factory.setValidating(false); + + // we do XSD validation + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema; + URL resource = this.getClass().getResource("/TOSCA-v1.0.xsd"); + try { + // takes a few seconds to load + schema = schemaFactory.newSchema(resource); + this.factory.setSchema(schema); + } catch (SAXException e) { + // TODO: load xml.xsd in offline mode + TOSCADocumentBuilderFactory.logger.error("Schema could not be initalized", e); + TOSCADocumentBuilderFactory.logger.debug("We continue nevertheless to enable offline usage"); + } + } + + public DocumentBuilder getTOSCADocumentBuilder() { + DocumentBuilder db; + try { + db = this.factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new IllegalStateException("document builder could not be initalized", e); + } + return db; + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/Util.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/Util.java new file mode 100644 index 0000000000..dc37586eea --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/Util.java @@ -0,0 +1,570 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common; + +import java.io.ByteArrayOutputStream; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.List; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlSchema; +import javax.xml.namespace.QName; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.commons.lang3.StringUtils; +import org.apache.taglibs.standard.functions.Functions; +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.definitions.EntityTemplateId; +import org.eclipse.winery.common.ids.definitions.EntityTypeId; +import org.eclipse.winery.common.ids.definitions.EntityTypeImplementationId; +import org.eclipse.winery.common.ids.definitions.PolicyTemplateId; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.common.ids.definitions.imports.GenericImportId; +import org.eclipse.winery.common.ids.definitions.imports.XSDImportId; +import org.eclipse.winery.common.ids.elements.TOSCAElementId; +import org.eclipse.winery.model.tosca.TEntityType; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Element; + +public class Util { + + private static final Logger logger = LoggerFactory.getLogger(Util.class); + + public static final String FORBIDDEN_CHARACTER_REPLACEMENT = "_"; + + + public static String URLdecode(String s) { + try { + return URLDecoder.decode(s, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException(); + } + } + + public static String URLencode(String s) { + try { + return URLEncoder.encode(s, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException(); + } + } + + public static String DoubleURLencode(String s) { + return Util.URLencode(Util.URLencode(s)); + } + + /** + * Encodes the namespace and the localname of the given qname, separated by + * "/" + * + * @return "/" + */ + public static String DoubleURLencode(QName qname) { + String ns = Util.DoubleURLencode(qname.getNamespaceURI()); + String localName = Util.DoubleURLencode(qname.getLocalPart()); + return ns + "/" + localName; + } + + public static boolean isRelativeURI(String uri) { + URI u; + try { + u = new URI(uri); + } catch (URISyntaxException e) { + Util.logger.debug(e.getMessage(), e); + // fallback + return false; + } + return !u.isAbsolute(); + } + + /** + * @param c the element directly nested below a definitions element in XML + */ + public static String getURLpathFragmentForCollection(Class c) { + String res = c.getName().toLowerCase(); + int lastDot = res.lastIndexOf('.'); + // classname is something like .T. We are only interested + // in "". Therefore "+2" from the dot onwards + res = res.substring(lastDot + 2); + res = res + "s"; + return res; + } + + public static String getEverythingBetweenTheLastDotAndBeforeId(Class cls) { + String res = cls.getName(); + // Everything between the last "." and before "Id" is the Type + int dotIndex = res.lastIndexOf('.'); + assert (dotIndex >= 0); + return res.substring(dotIndex + 1, res.length() - "Id".length()); + } + + public static String getTypeForElementId(Class idClass) { + return Util.getEverythingBetweenTheLastDotAndBeforeId(idClass); + } + + /** + * @return Singular type name for the given id. E.g., "ServiceTemplateId" + * gets "ServiceTemplate" + */ + public static String getTypeForComponentId(Class idClass) { + return Util.getEverythingBetweenTheLastDotAndBeforeId(idClass); + } + + /** + * Returns the root path fragment for the given + * AbstractComponentIntanceResource + * + * With trailing slash + * + * @return [ComponentName]s/ + */ + public static String getRootPathFragment(Class idClass) { + // quick handling of imports special case + // in the package naming, all other component instances have a this intermediate location, but not in the URLs + // The package handling is in {@link org.eclipse.winery.repository.Utils.getIntermediateLocationStringForType(String, String)} + String res; + if (GenericImportId.class.isAssignableFrom(idClass)) { + // this fires if idClass is a sub class from ImportCollectionId + // special treatment for imports + res = "imports/"; + if (XSDImportId.class.isAssignableFrom(idClass)) { + res = res + "http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema/"; + } else { + throw new IllegalStateException("Not possible to determine local storage for generic imports class"); + } + // we have the complete root path fragment + return res; + } else { + res = ""; + } + res = res + Util.getTypeForComponentId(idClass); + res = res.toLowerCase(); + res = res + "s"; + res = res + "/"; + return res; + } + + /** + * + * @param repositoryUrl the URL to the repository + * @param element the element directly nested below a definitions element in + * XML + * @param qname the QName of the element + * @return an a HTML element pointing to the given id + */ + public static String qname2href(String repositoryUrl, Class element, QName qname) { + if (StringUtils.isEmpty(repositoryUrl)) { + throw new IllegalArgumentException("Repository URL must not be empty."); + } + if (element == null) { + throw new IllegalArgumentException("Element class must not be null."); + } + if (qname == null) { + return "(none)"; + } + String absoluteURL = repositoryUrl + "/" + Util.getURLpathFragmentForCollection(element) + "/" + Util.DoubleURLencode(qname.getNamespaceURI()) + "/" + Util.DoubleURLencode(qname.getLocalPart()); + String res = "" + Functions.escapeXml(qname.getLocalPart()) + ""; + return res; + } + + /** + * Returns a visual rendering of minInstances + * + * @param minInstances the value to render + */ + public static String renderMinInstances(Integer minInstances) { + if ((minInstances == null) || (minInstances == 1)) { + // == null: default value: display nothing -- *never* happens: + // the function *always* returns 1 even, if no explicit value is set. Therefore, we also display "" if the default value 1 is set + return ""; + } else { + return Integer.toString(minInstances); + } + } + + /** + * Returns a visual rendering of maxInstances + * + * @param maxInstances the value to render + */ + public static String renderMaxInstances(String maxInstances) { + if ((maxInstances == null) || (maxInstances.equals("1"))) { + // default value display nothing + // "1" is returned even if no explicit value has been set. + return ""; + } else if (maxInstances.equals("unbounded")) { + return "∞"; + } else { + // maxInstance is a plain integer + // return as is + return maxInstances; + } + } + + /** + * @return the local name of a Class representing a TOSCA element + */ + private static String getLocalName(@SuppressWarnings("rawtypes") Class clazz) { + String localName = clazz.getName(); + // a class defined within another class is written as superclass$class. E.g., EntityTemplate$Properties + // We use the real class name + int pos = localName.lastIndexOf('$'); + if (pos == -1) { + pos = localName.lastIndexOf('.'); + } + localName = localName.substring(pos + 1); + if (localName.equals("TDocumentation")) { + // special case for documentation: the local name starts with a lower case letter + localName = "documentation"; + } else if (localName.startsWith("T")) { + localName = localName.substring(1); + } + return localName; + } + + public static JAXBElement getJAXBElement(Class clazz, T obj) { + String namespace = null; + XmlRootElement xmlRootElement = clazz.getAnnotation(XmlRootElement.class); + if (xmlRootElement != null) { + namespace = xmlRootElement.namespace(); + if ("##default".equals(namespace)) { + XmlSchema xmlSchema = clazz.getPackage().getAnnotation(XmlSchema.class); + if (xmlSchema != null) { + namespace = xmlSchema.namespace(); + } else { + // trigger default handling + namespace = null; + } + } + } + if (namespace == null) { + // fallback non-specified namespaces + namespace = org.eclipse.winery.common.constants.Namespaces.TOSCA_NAMESPACE; + } + String localName = Util.getLocalName(clazz); + QName qname = new QName(namespace, localName); + JAXBElement rootElement = new JAXBElement(qname, clazz, obj); + return rootElement; + } + + /** + * Method similar to {@link + * org.eclipse.winery.repository.Utils.getXMLAsString(Class, Object)}. + * + * Differences: + *
    + *
  • XML processing instruction is not included in the header
  • + *
  • JAXBcontext is created at each call
  • + *
+ */ + public static String getXMLAsString(Class clazz, T obj) throws Exception { + // copied from Utils java, but we create an own JAXBcontext here + // JAXBSupport cannot be used as this relies on a MockElement, which we do not want to factor out to winery.common + + JAXBContext context; + try { + // For winery classes, eventually the package+jaxb.index method could be better. See http://stackoverflow.com/a/3628525/873282 + // @formatter:off + context = JAXBContext.newInstance( + TEntityType.class); + // @formatter:on + } catch (JAXBException e) { + throw new IllegalStateException(e); + } + + JAXBElement rootElement = Util.getJAXBElement(clazz, obj); + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + m.setProperty(Marshaller.JAXB_FRAGMENT, true); + // m.setProperty("com.sun.xml.bind.namespacePrefixMapper", JAXBSupport.prefixMapper); + + StringWriter w = new StringWriter(); + try { + m.marshal(rootElement, w); + } catch (JAXBException e) { + throw new IllegalStateException(e); + } + String res = w.toString(); + return res; + } + + public static String getXMLAsString(Element el) { + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer t; + try { + t = tf.newTransformer(); + } catch (TransformerConfigurationException e) { + throw new IllegalStateException("Could not instantiate Transformer", e); + } + t.setOutputProperty(OutputKeys.INDENT, "yes"); + Source source = new DOMSource(el); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + Result target = new StreamResult(os); + try { + t.transform(source, target); + } catch (TransformerException e) { + Util.logger.debug(e.getMessage(), e); + throw new IllegalStateException("Could not transform dom node to string", e); + } + return os.toString(); + } + + /** + * Determines whether the instance belonging to the given id supports the + * "name" attribute. This cannot be done using the super class as the TOSCA + * specification treats that differently in the case of EntityTemplates + * + * NOTE: The respective subclasses of AbstractComponentInstanceResource have + * to implement {@link org.eclipse.winery.repository.resources.IHasName} + * + * @param id the id to test + * @return true if the TOSCA model class belonging to the given id supports + * the method "getName()" in addition to "getId()" + */ + public static boolean instanceSupportsNameAttribute(Class idClass) { + if (ServiceTemplateId.class.isAssignableFrom(idClass)) { + return true; + } else if ((EntityTypeId.class.isAssignableFrom(idClass)) || (EntityTypeImplementationId.class.isAssignableFrom(idClass))) { + // name is available, but no id attribute + return false; + } else if (GenericImportId.class.isAssignableFrom(idClass)) { + return false; + } else { + assert (EntityTemplateId.class.isAssignableFrom(idClass)); + if (ArtifactTemplateId.class.isAssignableFrom(idClass)) { + return true; + } else if (PolicyTemplateId.class.isAssignableFrom(idClass)) { + return true; + } else { + throw new IllegalStateException("Unimplemented branch to determine if getName() exists"); + } + } + } + + public static String getLastURIPart(String loc) { + int posSlash = loc.lastIndexOf('/'); + String fileName = loc.substring(posSlash + 1); + return fileName; + } + + /** + * Determines a color belonging to the given name + */ + public static String getColor(String name) { + int hash = name.hashCode(); + // trim to 3*8=24 bits + hash = hash & 0xFFFFFF; + // check if color is more than #F0F0F0, i.e., too light + if (((hash & 0xF00000) >= 0xF00000) && (((hash & 0x00F000) >= 0x00F000) && ((hash & 0x0000F0) >= 0x0000F0))) { + // set one high bit to zero for each channel. That makes the overall color darker + hash = hash & 0xEFEFEF; + } + String colorStr = String.format("#%06x", hash); + return colorStr; + } + + /** + * Determines the name of the CSS class used for relationshipTypes at + * nodeTemplateRenderer.tag + */ + public static String makeCSSName(String namespace, String localName) { + // according to http://stackoverflow.com/a/79022/873282 everything is allowed + // However, {namespace}id does NOT work + String res = namespace + "_" + localName; + res = res.replaceAll("[^\\w\\d_]", "_"); + return res; + } + + /** + * @see {@link org.eclipse.winery.common.Util.makeCSSName(String, String)} + */ + public static String makeCSSName(QName qname) { + return Util.makeCSSName(qname.getNamespaceURI(), qname.getLocalPart()); + } + + public static SortedMap> convertQNameListToNamespaceToLocalNameList(List list) { + SortedMap> res = new TreeMap<>(); + for (QName qname : list) { + SortedSet localNameSet = res.get(qname.getNamespaceURI()); + if (localNameSet == null) { + localNameSet = new TreeSet<>(); + res.put(qname.getNamespaceURI(), localNameSet); + } + localNameSet.add(qname.getLocalPart()); + } + return res; + } + + public static String namespaceToJavaPackage(String namespace) { + URI uri; + try { + uri = new URI(namespace); + } catch (URISyntaxException e) { + Util.logger.debug(e.getMessage(), e); + return "uri.invalid"; + } + StringBuilder sb = new StringBuilder(); + + String host = uri.getHost(); + if (host != null) { + Util.addReversed(sb, host, "\\."); + } + + String path = uri.getPath(); + if (!path.equals("")) { + if (path.startsWith("/")) { + // remove first slash + path = path.substring(1); + } + + // and then handle the string + Util.addAsIs(sb, path, "/"); + } + + // remove the final dot + sb.replace(sb.length() - 1, sb.length(), ""); + + return Util.cleanName(sb.toString()); + } + + private static String cleanName(String s) { + // TODO: Integrate with other name cleaning functions. "." should not be replaced as it is used as separator in the java package name + // @formatter:off + return s.replace(":", Util.FORBIDDEN_CHARACTER_REPLACEMENT) + .replace("/", Util.FORBIDDEN_CHARACTER_REPLACEMENT) + .replace(" ", Util.FORBIDDEN_CHARACTER_REPLACEMENT) + .replace("-", Util.FORBIDDEN_CHARACTER_REPLACEMENT); + // @formatter:on + } + + + /* + * Valid chars: See + *
    + *
  • http://www.w3.org/TR/REC-xml-names/#NT-NCName
  • + *
  • http://www.w3.org/TR/REC-xml/#NT-Name
  • + *
+ */ + // NameCharRange \u10000-\ueffff is not supported by Java + private static final String NCNameStartChar_RegExp = "[A-Z_a-z\u00c0-\u00d6\u00d8\u00f6\u00f8\u02ff\u0370\u037d\u037f-\u1fff\u200c-\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]"; + private static final String NCNameChar_RegExp = Util.NCNameStartChar_RegExp + "|[-\\.0-9\u00B7\u0300-\u036F\u203F-\u2040]"; + private static final Pattern NCNameStartChar_Pattern = Pattern.compile(Util.NCNameStartChar_RegExp); + private static final Pattern NCNameChar_RegExp_Pattern = Pattern.compile(Util.NCNameChar_RegExp); + + + /** + * Removes all non-NCName characters from the given string and returns the + * result + * + * This function should be consistent with + * org.eclipse.winery.common.Util.cleanName(String) + * + * TODO: This method seems to be equal to {@link + * org.eclipse.winery.repository.Utils.createXMLidAsString(String)}. These + * methods should be merged. + * + */ + public static String makeNCName(String text) { + if (StringUtils.isEmpty(text)) { + return text; + } + + StringBuffer res = new StringBuffer(); + + // handle start + String start = text.substring(0, 1); + Matcher m = Util.NCNameStartChar_Pattern.matcher(start); + if (m.matches()) { + res.append(start); + } else { + // not a valid character + res.append("_"); + } + + // handle remaining characters; + for (int i = 1; i < text.length(); i++) { + String s = text.substring(i, i + 1); + m = Util.NCNameChar_RegExp_Pattern.matcher(s); + if (m.matches()) { + res.append(s); + } else { + // not a valid character + res.append("_"); + } + } + + return res.toString(); + } + + private static void addAsIs(StringBuilder sb, String s, String separator) { + if (s.isEmpty()) { + return; + } + String[] split = s.split(separator); + for (int i = 0; i < split.length; i++) { + sb.append(split[i]); + sb.append("."); + } + } + + private static void addReversed(StringBuilder sb, String s, String separator) { + String[] split = s.split(separator); + for (int i = split.length - 1; i >= 0; i--) { + sb.append(split[i]); + sb.append("."); + } + } + + /** + * Bridge to client.getType(). Just calls client getType(), used by + * functions.tld. + * + * We suppress compiler warnings as JSP 2.0 do not offer support for + * generics, but we're using JSP 2.0... + * + * @param client the repository client to use + * @param qname the QName to resolve + * @param clazz the class the QName is describing + * @return {@inheritDoc} + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public static org.eclipse.winery.model.tosca.TEntityType getType(org.eclipse.winery.common.interfaces.IWineryRepository client, javax.xml.namespace.QName qname, java.lang.Class clazz) { + return client.getType(qname, clazz); + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/beans/NamespaceIdOptionalName.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/beans/NamespaceIdOptionalName.java new file mode 100644 index 0000000000..872cb042b8 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/beans/NamespaceIdOptionalName.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.beans; + +/** + * Bean containing + *
    + *
  • namespace
  • + *
  • id
  • + *
  • name
  • + *
+ * The name field is optional + */ +public class NamespaceIdOptionalName { + + private String namespace; + private String id; + private String name = null; + + + public NamespaceIdOptionalName() { + + } + + public String getNamespace() { + return this.namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/Defaults.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/Defaults.java new file mode 100644 index 0000000000..a3e13680b4 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/Defaults.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.constants; + +public class Defaults { + + public static final String DEFAULT_RT_HOVER_COLOR = "black"; + + // files are in src/main/webapp/images/relationshiptype + // convention: below the prefix, then the filename is either ...Left.png or ...Right.png + public static final String DEFAULT_RT_ARROWHEAD_SOURCE = "none"; + public static final String DEFAULT_RT_ARROWHEAD_TARGET = "PlainArrow"; + + public static final String DEFAULT_RT_DASH = "plain"; + public static final String DEFAULT_RT_LINEWIDTH = "1"; +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/MimeTypes.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/MimeTypes.java new file mode 100644 index 0000000000..f79593ccc2 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/MimeTypes.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.constants; + +/** + * See also {@link org.eclipse.winery.repository.backend.constants.MediaTypes} + */ +public class MimeTypes { + + public static final String MIMETYPE_TOSCA_DEFINITIONS = "application/vnd.oasis.tosca.definitions"; + + // text/xsd is NOT used for XSD as text/xml is rendered correctly in browsers + public static final String MIMETYPE_XSD = "text/xml"; + + public static final String MIMETYPE_ZIP = "application/zip"; + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/Namespaces.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/Namespaces.java new file mode 100644 index 0000000000..5767563da6 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/Namespaces.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.constants; + +/** + * Defines namespace constants not available in Java7's XMLConstants + */ +public class Namespaces { + + public static final String TOSCA_NAMESPACE = "http://docs.oasis-open.org/tosca/ns/2011/12"; + public static final String TOSCA_WINERY_EXTENSIONS_NAMESPACE = "http://www.opentosca.org/winery/extensions/tosca/2013/02/12"; + + // XML Schema namespace is defined at Java7's XMLConstants.W3C_XML_SCHEMA_NS_URI + + public static final String URI_BPMN20_MODEL = "http://www.omg.org/spec/BPMN/20100524/MODEL"; + public static final String URI_BPEL20_ABSTRACT = "http://docs.oasis-open.org/wsbpel/2.0/process/abstract"; + public static final String URI_BPEL20_EXECUTABLE = "http://docs.oasis-open.org/wsbpel/2.0/process/executable"; +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/QNames.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/QNames.java new file mode 100644 index 0000000000..dcc5de0ad1 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/constants/QNames.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.constants; + +import javax.xml.namespace.QName; + +public class QNames { + + public static final QName QNAME_BORDER_COLOR = new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "bordercolor"); + public static final QName QNAME_COLOR = new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "color"); + + // Boolean flag to indicate that the import is generated via the Winery Properties Defintion + public static final QName QNAME_WINERYS_PROPERTIES_DEFINITION_ATTRIBUTE = new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "wpd"); +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/GenericId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/GenericId.java new file mode 100644 index 0000000000..756137e002 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/GenericId.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids; + +/** + * Superclass for all IDs appearing in Winery. These are: + *
    + *
  • All IDs of elements directly nested in a Definitions element
  • + *
  • Subelements of those
  • + *
+ * + * We assume that TOSCAcomponentId is always the root node of nested IDs + * + */ +public abstract class GenericId implements Comparable { + + private final XMLId xmlId; + + + protected GenericId(XMLId xmlId) { + this.xmlId = xmlId; + } + + /** + * @return null if (this instanceof TOSCAcomponentId). In that case, the + * element is already the root element + */ + public abstract GenericId getParent(); + + /** + * @return the XML id of this thing + */ + public XMLId getXmlId() { + return this.xmlId; + } + + @Override + public abstract boolean equals(Object obj); + + @Override + public abstract int hashCode(); + + @Override + public String toString() { + return this.getClass().toString() + " / " + this.getXmlId().toString(); + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/IdNames.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/IdNames.java new file mode 100644 index 0000000000..fb1af16f3b --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/IdNames.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids; + +/** + * The names of ids, used to set XMLids for collections of things + */ +public class IdNames { + + public static final String DEPLOYMENTARTIFACTS = "deploymentartifacts"; + public static final String INSTANCESTATES = "instancestates"; + public static final String INTERFACES = "interfaces"; // used at node type + public static final String INPUTPARAMETERS = "inputParameters"; + public static final String IMPLEMENTATIONARTIFACTS = "implementationartifacts"; + public static final String NODETEMPLATES = "nodetemplates"; + public static final String OUTPUTPARAMETERS = "outputParameters"; + public static final String PROPERTIES = "properties"; + public static final String RELATIONSHIPTEMPLATES = "relationshiptemplates"; + public static final String SOURCEINTERFACES = "sourceinterfaces"; + public static final String TARGETINTERFACES = "targetinterfaces"; + public static final String TOPOLOGYTEMPATE = "topologytemplate"; +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/IdUtil.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/IdUtil.java new file mode 100644 index 0000000000..90970f191c --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/IdUtil.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids; + +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.common.ids.elements.TOSCAElementId; + +/** + * Helper methods for Winery's Id system + */ +public class IdUtil { + + /** + * Returns the namespace where the given Id is nested in. As the id is not a + * TOSCAComponentId, it cannot be directly asked for its parent. Merely, the + * parent has to be asked for its namespace. The parent, in turn, if it is + * no TOSCAComponentId has to ask his parent. + * + * @param id the id refering to an element, where the namespace has to be + * checked for + * @return the namespace of the element denoted by id + */ + public static Namespace getNamespace(GenericId id) { + if (id instanceof TOSCAComponentId) { + return ((TOSCAComponentId) id).getNamespace(); + } else { + return IdUtil.getNamespace(id.getParent()); + } + } + + /** + * Executes the real conversion to a path fragment + * + * @param id the id to transform to a path + * @param doubleEncode true if each sub fragment should be double encoded, + * false if it should be encoded only once + * @return + */ + private static String getPathFragment(final GenericId id, final boolean doubleEncode) { + String toInsert; + if (id instanceof TOSCAComponentId) { + // @return "[ComponentName]s/{namespace}/{id}/" + TOSCAComponentId tId = (TOSCAComponentId) id; + String res = Util.getRootPathFragment(tId.getClass()); + toInsert = tId.getNamespace().getEncoded(); + if (doubleEncode) { + toInsert = Util.URLencode(toInsert); + } + res = res + toInsert + "/"; + toInsert = tId.getXmlId().getEncoded(); + if (doubleEncode) { + toInsert = Util.URLencode(toInsert); + } + res = res + toInsert + "/"; + return res; + } else if (id instanceof TOSCAElementId) { + toInsert = id.getXmlId().getEncoded(); + if (doubleEncode) { + toInsert = Util.URLencode(toInsert); + } + return IdUtil.getPathFragment(id.getParent()) + toInsert + "/"; + } else { + throw new IllegalStateException("Unknown subclass of GenericId " + id.getClass()); + } + } + + /** + * Returns the fragment of the path belonging to the id + * + * For instance, an Id of type ServiceTemplateId has + * servicetemplates/{encoded ns}/{encoded name}/ + * + * @param id the element to return the path fragment for + * @return the path fragment. This is not intended to be used + * inside a URL + */ + public static String getPathFragment(GenericId id) { + return IdUtil.getPathFragment(id, false); + } + + /** + * Returns the fragment of the URL path belonging to the id + * + * For instance, an Id of type ServiceTemplateId has + * servicetemplates/{double encoded ns}/{double encoded name}/ + * + * @param id the element to return the path fragment for + * @return the path fragment to be used inside an URL + */ + public static String getURLPathFragment(GenericId id) { + return IdUtil.getPathFragment(id, true); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/Namespace.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/Namespace.java new file mode 100644 index 0000000000..1966b21202 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/Namespace.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids; + +import org.eclipse.winery.common.StringEncodedAndDecoded; + +public class Namespace extends StringEncodedAndDecoded { + + public Namespace(String uri, boolean URLencoded) { + super(uri, URLencoded); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/XMLId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/XMLId.java new file mode 100644 index 0000000000..67bfb9f8da --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/XMLId.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids; + +import org.eclipse.winery.common.StringEncodedAndDecoded; + +/** + * Handles an ID given in the XML + * + * We need to have this class as IDs are also passed at URIs at requests. To + * ease handling, we use StringEncodedAndDecoded + * + * There is no check for valid XMLids (AKA allowed NCname characters). This is + * OK as, for instance, properties make use of this fact and store the name as + * ID + */ +public class XMLId extends StringEncodedAndDecoded { + + public XMLId(String id, boolean URLencoded) { + super(id, URLencoded); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ArtifactTemplateId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ArtifactTemplateId.java new file mode 100644 index 0000000000..d74c98672b --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ArtifactTemplateId.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public class ArtifactTemplateId extends EntityTemplateId { + + public ArtifactTemplateId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public ArtifactTemplateId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + + public ArtifactTemplateId(QName qname) { + super(qname); + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ArtifactTypeId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ArtifactTypeId.java new file mode 100644 index 0000000000..80de6a9eac --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ArtifactTypeId.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public class ArtifactTypeId extends EntityTypeId { + + public ArtifactTypeId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public ArtifactTypeId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + + public ArtifactTypeId(QName qname) { + this(new Namespace(qname.getNamespaceURI(), false), new XMLId(qname.getLocalPart(), false)); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/CapabilityTypeId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/CapabilityTypeId.java new file mode 100644 index 0000000000..18268c9f9c --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/CapabilityTypeId.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public final class CapabilityTypeId extends EntityTypeId { + + public CapabilityTypeId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public CapabilityTypeId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + + public CapabilityTypeId(QName qname) { + super(qname); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTemplateId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTemplateId.java new file mode 100644 index 0000000000..731a156970 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTemplateId.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +/** + * ArtifactTemplates and PolicyTemplates are directly nested in a + * Definitions element. RelationshipTemplates and NodeTemplates are not. When + * approaching an EntityTemplateId, it is a thing directly nested in a + * Definitions element. + * + * The others have TOSCAelementID as parent + */ +public abstract class EntityTemplateId extends TOSCAComponentId { + + public EntityTemplateId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public EntityTemplateId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + + public EntityTemplateId(QName qname) { + super(qname); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTypeId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTypeId.java new file mode 100644 index 0000000000..6378baf202 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTypeId.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public abstract class EntityTypeId extends TOSCAComponentId { + + public EntityTypeId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public EntityTypeId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + + public EntityTypeId(QName type) { + super(type); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTypeImplementationId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTypeImplementationId.java new file mode 100644 index 0000000000..cc10800b33 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/EntityTypeImplementationId.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public abstract class EntityTypeImplementationId extends TOSCAComponentId { + + public EntityTypeImplementationId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public EntityTypeImplementationId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/NodeTypeId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/NodeTypeId.java new file mode 100644 index 0000000000..d1410c0cb9 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/NodeTypeId.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public final class NodeTypeId extends TopologyGraphElementEntityTypeId { + + public NodeTypeId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public NodeTypeId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + + public NodeTypeId(QName type) { + super(type); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/NodeTypeImplementationId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/NodeTypeImplementationId.java new file mode 100644 index 0000000000..48ab36a891 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/NodeTypeImplementationId.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public final class NodeTypeImplementationId extends EntityTypeImplementationId { + + public NodeTypeImplementationId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public NodeTypeImplementationId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/PolicyTemplateId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/PolicyTemplateId.java new file mode 100644 index 0000000000..ff9e4b837e --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/PolicyTemplateId.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public final class PolicyTemplateId extends EntityTemplateId { + + public PolicyTemplateId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public PolicyTemplateId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + + public PolicyTemplateId(QName qname) { + super(qname); + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/PolicyTypeId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/PolicyTypeId.java new file mode 100644 index 0000000000..48d4a4cd03 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/PolicyTypeId.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public final class PolicyTypeId extends EntityTypeId { + + public PolicyTypeId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public PolicyTypeId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + + public PolicyTypeId(QName qname) { + super(qname); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RelationshipTypeId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RelationshipTypeId.java new file mode 100644 index 0000000000..1648b097b6 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RelationshipTypeId.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public final class RelationshipTypeId extends TopologyGraphElementEntityTypeId { + + public RelationshipTypeId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public RelationshipTypeId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + public RelationshipTypeId(QName qname) { + super(qname); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RelationshipTypeImplementationId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RelationshipTypeImplementationId.java new file mode 100644 index 0000000000..61c02387f2 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RelationshipTypeImplementationId.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public final class RelationshipTypeImplementationId extends EntityTypeImplementationId { + + public RelationshipTypeImplementationId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public RelationshipTypeImplementationId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RequirementTypeId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RequirementTypeId.java new file mode 100644 index 0000000000..4b01833a64 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/RequirementTypeId.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public final class RequirementTypeId extends EntityTypeId { + + public RequirementTypeId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public RequirementTypeId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + + public RequirementTypeId(QName qname) { + super(qname); + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ServiceTemplateId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ServiceTemplateId.java new file mode 100644 index 0000000000..46f462c6c6 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/ServiceTemplateId.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +public final class ServiceTemplateId extends TOSCAComponentId { + + public ServiceTemplateId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public ServiceTemplateId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + + public ServiceTemplateId(QName qname) { + super(qname); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/TOSCAComponentId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/TOSCAComponentId.java new file mode 100644 index 0000000000..e9ce856747 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/TOSCAComponentId.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +/** + * Identifies a TOSCA component. Each component is required to be identified + * subclasses this class + * + * A TOSCAcomponentId has a namespace and an id within that namespace. In XML, + * the ID might be serialized as NCName (in the case of EntityTypes and + * EntityTemplates) and as xs:id (in the case of EntityTypeImplementations) + * + * Components are elements, which may appear directly nested in TDefinitions: + *
    + *
  • ServiceTemplates,
  • + *
  • EntityTypes,
  • EntityTypeImplementations, + *
  • EntityTemplates
  • + *
+ */ +public abstract class TOSCAComponentId extends GenericId { + + private final Namespace namespace; + + + public TOSCAComponentId(Namespace namespace, XMLId xmlId) { + super(xmlId); + this.namespace = namespace; + } + + /** + * Creates a new id based on strings. This constructor is required for + * {@link AbstractComponentsResource} + * + * @param ns the namespace to be used + * @param id the id to be used + * @param URLencoded true: both Strings are URLencoded, false: both Strings + * are not URLencoded + */ + public TOSCAComponentId(String ns, String id, boolean URLencoded) { + this(new Namespace(ns, URLencoded), new XMLId(id, URLencoded)); + } + + public TOSCAComponentId(QName qname) { + this(qname.getNamespaceURI(), qname.getLocalPart(), false); + } + + public QName getQName() { + QName qname = new QName(this.getNamespace().getDecoded(), this.getXmlId().getDecoded()); + return qname; + } + + public Namespace getNamespace() { + return this.namespace; + } + + @Override + public int hashCode() { + return this.namespace.hashCode() ^ this.getXmlId().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof TOSCAComponentId)) { + return false; + } else { + TOSCAComponentId other = (TOSCAComponentId) obj; + return this.getXmlId().equals(other.getXmlId()) && this.namespace.equals(other.namespace); + } + } + + @Override + public String toString() { + QName qn = this.getQName(); + return this.getClass().toString() + " / " + qn.toString(); + } + + @Override + public GenericId getParent() { + return null; + } + + @Override + public int compareTo(GenericId o1) { + if (o1 instanceof TOSCAComponentId) { + TOSCAComponentId o = (TOSCAComponentId) o1; + int res = this.getXmlId().compareTo(o.getXmlId()); + if (res == 0) { + res = this.getNamespace().compareTo(o.getNamespace()); + } + return res; + } else { + // comparing TOSCAcomponentIDs with non-TOSCAcomponentIDs is not + // possible + throw new IllegalStateException(); + } + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/TopologyGraphElementEntityTypeId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/TopologyGraphElementEntityTypeId.java new file mode 100644 index 0000000000..9eceb42fb0 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/TopologyGraphElementEntityTypeId.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +/** + * An instance of this class is either a NodeTypeId or a RelationShipTypeId + */ +public abstract class TopologyGraphElementEntityTypeId extends EntityTypeId { + + public TopologyGraphElementEntityTypeId(Namespace namespace, XMLId xmlId) { + super(namespace, xmlId); + } + + public TopologyGraphElementEntityTypeId(String ns, String id, boolean URLencoded) { + super(ns, id, URLencoded); + } + + public TopologyGraphElementEntityTypeId(QName type) { + super(type); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/imports/GenericImportId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/imports/GenericImportId.java new file mode 100644 index 0000000000..3b81236c1d --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/imports/GenericImportId.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions.imports; + +import org.apache.commons.io.FilenameUtils; +import org.eclipse.winery.model.tosca.TImport; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; + +/** + * class for import ids (not used for definitions) + * + * // Convention: id of import is filename without extension + */ +public class GenericImportId extends TOSCAComponentId { + + private final String type; + + + /** + * @param type the importType (e.g., MimeTypes.MIMETYPE_XSD) + */ + public GenericImportId(Namespace namespace, XMLId xmlId, String type) { + super(namespace, xmlId); + this.type = type; + } + + public GenericImportId(String ns, String id, boolean encoded, String type) { + super(ns, id, encoded); + this.type = type; + } + + /** + * Generates an ImportId based on an TImport object The import has to be an + * import created by winery. This method uses the convention that the id is + * derived from the location + * + * @param i the TImport element to derive an id from + */ + public GenericImportId(TImport i) { + this(i.getNamespace(), GenericImportId.getId(i), false, i.getImportType()); + } + + private static String getId(TImport i) { + String fileName = Util.getLastURIPart(i.getLocation()); + String id = FilenameUtils.removeExtension(fileName); + return id; + } + + public String getType() { + return this.type; + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/imports/XSDImportId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/imports/XSDImportId.java new file mode 100644 index 0000000000..940e8d3354 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/imports/XSDImportId.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.definitions.imports; + +import javax.xml.XMLConstants; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; + +/** + * Models an import of type XML Schema Definition + * + * Required for a special treatment in {@link + * org.eclipse.winery.repository.Utils. + * getAllXSDefinitionsForTypeAheadSelection(short)} + */ +public class XSDImportId extends GenericImportId { + + public XSDImportId(String ns, String id, boolean encoded) { + super(ns, id, encoded, XMLConstants.W3C_XML_SCHEMA_NS_URI); + } + + public XSDImportId(Namespace ns, XMLId id) { + super(ns, id, XMLConstants.W3C_XML_SCHEMA_NS_URI); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/package-info.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/package-info.java new file mode 100644 index 0000000000..ac34b4978b --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/definitions/package-info.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +/** + * This package contains ids for all components, which are directly nested in a + * definitions element. See CSPRD01, Section 4.1 + */ +package org.eclipse.winery.common.ids.definitions; + diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/PlanId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/PlanId.java new file mode 100644 index 0000000000..49c2c2aa68 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/PlanId.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.elements; + +import org.eclipse.winery.common.ids.XMLId; + +public class PlanId extends TOSCAElementId { + + public PlanId(PlansId parent, XMLId xmlId) { + super(parent, xmlId); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/PlansId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/PlansId.java new file mode 100644 index 0000000000..bd703ddc01 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/PlansId.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.elements; + +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; + +/** + * Pseudo-Id for plans nested in one service template + * + * results in the path "plans/" + */ +public class PlansId extends TOSCAElementId { + + public PlansId(ServiceTemplateId parent) { + super(parent, new XMLId("plans", true)); + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/TOSCAElementId.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/TOSCAElementId.java new file mode 100644 index 0000000000..139a567ef1 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/TOSCAElementId.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.ids.elements; + +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.common.ids.XMLId; + +/** + * Models an ID of a TOSCA element, which is NOT a TOSCAcomponentId + * + * It has a parent and an xmlId + */ +public abstract class TOSCAElementId extends GenericId { + + private final GenericId parent; + + + public TOSCAElementId(GenericId parent, XMLId xmlId) { + super(xmlId); + this.parent = parent; + } + + @Override + public GenericId getParent() { + return this.parent; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof TOSCAElementId) { + TOSCAElementId otherId = (TOSCAElementId) obj; + // the XML id has to be equal and the parents have to be equal + return (otherId.getXmlId().equals(this.getXmlId())) && (otherId.getParent().equals(this.getParent())); + } else { + return false; + } + } + + @Override + public int compareTo(GenericId o1) { + if (o1 instanceof TOSCAElementId) { + TOSCAElementId o = (TOSCAElementId) o1; + if (this.getParent().equals(o.getParent())) { + return this.getXmlId().compareTo(o.getXmlId()); + } else { + return this.getParent().compareTo(o.getParent()); + } + } else { + // comparing TOSCAcomponentIDs with non-TOSCAcomponentIDs is not + // possible + throw new IllegalStateException(); + } + } + + @Override + public int hashCode() { + return this.getParent().hashCode() ^ this.getXmlId().hashCode(); + } + + @Override + public String toString() { + String res; + res = this.getClass().toString() + " / " + this.getXmlId().getDecoded(); + res += "\n"; + res += "parent: " + this.getParent().toString(); + return res; + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/package-info.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/package-info.java new file mode 100644 index 0000000000..0fd2942418 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/ids/elements/package-info.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +/** + * This package contains ids for all TOSCA element, which are NOT + * directly nested in a definitions element. + */ +package org.eclipse.winery.common.ids.elements; + diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/IWineryRepository.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/IWineryRepository.java new file mode 100644 index 0000000000..227259616d --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/IWineryRepository.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.interfaces; + +import java.util.Collection; +import java.util.List; +import java.util.SortedSet; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.model.tosca.TDefinitions; +import org.eclipse.winery.model.tosca.TEntityType; +import org.eclipse.winery.model.tosca.TTopologyTemplate; +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; + +/** + * This interface is used by the repository client to get access to the + * repository. + * + * This interface should be removed and the client should be able to use + * "IWineryRepositoryCommon" only. + */ +public interface IWineryRepository extends IWineryRepositoryCommon { + + /** + * Returns all namespaces used by all known TOSCA components and namespaces + * where a prefix is defined for + * + * String is used as return type as Java's QName also uses String as + * parameter to denote a namespace + */ + public SortedSet getNamespaces(); + + /** + * Returns a list of the QNames of all available types. Types can be node + * types, service templates, artifact types, artifact templates. + * + * This method obsoletes methods like "getQNameListOfAllArtifactTypes": One + * just has to call getQNameListOfAllTypes(TArtifactType.class) + * + * @return List of QNames of all types + */ + List getQNameListOfAllTypes(Class type); + + /** + * Get the TEntityType belonging to the given QName + * + * @return null if there is no data on the server + */ + T getType(QName qname, Class type); + + /** + * Queries the repository for instances of the given type. Returns pairs of + * QNames and names. The names are added as some component instances do + * carry a name. + * + * If the component instance does not carry an explicit name, the localName + * of the QName is used as name. + * + * @param type the type to get all instances of + * @return a collection of QName/name pairs + */ + Collection getListOfAllInstances(Class type); + + /** + * Returns the associated name for the given id. + * + * Since not all TOSCA entities have names, this method may only be used for + * entities supporting names. If it is used for entities not having a name, + * null is returned. + * + * @param id references the entity to query for a name + * @return the name or null if no name is available + */ + String getName(GenericId id); + + /** + * Returns a list of all available types. Types can be node types, service + * templates, artifact types. Note that artifact templates are + * TEntityTemplates and thus cannot be retrieved by this method. + * + * This method obsoletes methods like "getAllArtifactTypes": One just has to + * call getallTypes(TArtifactType.class) + * + * @return List of all types + */ + Collection getAllTypes(Class type); + + /** + * @return List of all types with associated elements (such as deployment + * artifacts). Each type is nested in a separate Definitions Element + */ + Collection getAllTypesWithAssociatedElements(Class type); + + /** + * Returns the topology template associated to the given service template + * + * @param serviceTemplate a QName of the sericeTemplate with full namespace + * @return null if nothing is found + */ + TTopologyTemplate getTopologyTemplate(QName serviceTemplate); + + /** + * Replaces (or creates) the provided topology template + * + * @param serviceTemplate the service template the given topolgoy template + * belongs to + * @param topologyTemplate the topology template to use + */ + void setTopologyTemplate(QName serviceTemplate, TTopologyTemplate topologyTemplate) throws Exception; + + /** + * Returns a reference to the artifact type registered for the given file + * extensions. Returns null if no such artifact type exists. + * + * @param extension the file extension to look up. + * @return Reference in the form of a QName to the artifact type matching + * the given file extension. + */ + QName getArtifactTypeQNameForExtension(String extension); + + /** + * Creates the specified artifact template + * + * @param qname the namespace and name of the artifact template + * @param artifactType the artifact type of the artifact template + * @throws QNameAlreadyExistsException if the given QName already exists + */ + void createArtifactTemplate(QName qname, QName artifactType) throws QNameAlreadyExistsException; +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/IWineryRepositoryCommon.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/IWineryRepositoryCommon.java new file mode 100644 index 0000000000..722148905c --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/IWineryRepositoryCommon.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.interfaces; + +import java.io.IOException; + +import org.eclipse.winery.common.ids.GenericId; + +/** + * Enables access to the winery repository via Ids defined in package + * {@link org.eclipse.winery.common.ids} + * + * Methods are moved from + * {@link org.eclipse.winery.repository.backend.IGenericRepository} to here as + * soon there is an implementation for them. The ultimate goal is to eliminate + * IGenericRepository + * + * These methods are shared between {@link IWineryRepository} and + * {@link org.eclipse.winery.repository.backend.IRepository} + */ +public interface IWineryRepositoryCommon { + + /** + * Deletes the TOSCA element and all sub elements referenced by the + * given id from the repository + * + * We assume that each id is a directory + * + * @param id + */ + public void forceDelete(GenericId id) throws IOException; + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/QNameAlreadyExistsException.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/QNameAlreadyExistsException.java new file mode 100644 index 0000000000..d089935c07 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/QNameAlreadyExistsException.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.interfaces; + +public class QNameAlreadyExistsException extends Exception { + + private static final long serialVersionUID = 1L; + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/QNameWithName.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/QNameWithName.java new file mode 100644 index 0000000000..96c2e430c9 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/interfaces/QNameWithName.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.interfaces; + +import javax.xml.namespace.QName; + +/** + * This class is used to pass around QNames with associated names in string + * format + */ +public class QNameWithName { + + public QName qname; + public String name; +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/PropertyDefinitionKV.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/PropertyDefinitionKV.java new file mode 100644 index 0000000000..f8cc236c6f --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/PropertyDefinitionKV.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.propertydefinitionkv; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "PropertyDefinition") +public class PropertyDefinitionKV { + + private String key; + private String type; + + + public PropertyDefinitionKV() { + super(); + } + + public PropertyDefinitionKV(String key, String type) { + super(); + this.setKey(key); + this.setType(type); + } + + public String getKey() { + return this.key; + } + + public void setKey(String key) { + if (key == null) { + throw new IllegalArgumentException(); + } + this.key = key; + } + + public String getType() { + return this.type; + } + + public void setType(String type) { + if (type == null) { + throw new IllegalArgumentException(); + } + this.type = type; + } + + @Override + public int hashCode() { + return this.key.hashCode(); + } +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/PropertyDefinitionKVList.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/PropertyDefinitionKVList.java new file mode 100644 index 0000000000..445bda641c --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/PropertyDefinitionKVList.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.propertydefinitionkv; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "PropertyDefinitions") +public class PropertyDefinitionKVList extends ArrayList { + + private static final long serialVersionUID = -6442041855597987094L; + + + @XmlElement(name = "PropertyDefinition") + public List getPropertyDefinitionKVs() { + return this; + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/WinerysPropertiesDefinition.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/WinerysPropertiesDefinition.java new file mode 100644 index 0000000000..548e87b85f --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/WinerysPropertiesDefinition.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common.propertydefinitionkv; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.eclipse.winery.common.constants.Namespaces; + +/** + * This is Winery's main extension element for a key/value based properties + * definition + */ +@XmlRootElement(name = "PropertiesDefinition") +public class WinerysPropertiesDefinition { + + private String namespace; + private String elementName; + private PropertyDefinitionKVList propertyDefinitionKVList; + private Boolean isDerivedFromXSD = Boolean.FALSE; + + + @XmlAttribute(name = "namespace") + public String getNamespace() { + return this.namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + @XmlAttribute(name = "elementname") + public String getElementName() { + return this.elementName; + } + + public void setElementName(String localName) { + this.elementName = localName; + } + + @XmlElement(name = "properties") + public PropertyDefinitionKVList getPropertyDefinitionKVList() { + return this.propertyDefinitionKVList; + } + + public void setPropertyDefinitionKVList(PropertyDefinitionKVList propertyDefinitionKVList) { + this.propertyDefinitionKVList = propertyDefinitionKVList; + } + + /** + * @return null if not derived from XSD, "Boolean.TRUE" otherwise. This + * leads JAXB to write the attribute only if derivedFromXSD is true + */ + @XmlAttribute(name = "derivedFromXSD", namespace = Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE) + public Boolean getIsDerivedFromXSD() { + if ((this.isDerivedFromXSD != null) && (this.isDerivedFromXSD)) { + return Boolean.TRUE; + } else { + return null; + } + } + + public void setIsDerivedFromXSD(Boolean isDerivedFromXSD) { + this.isDerivedFromXSD = isDerivedFromXSD; + } + +} diff --git a/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/package-info.java b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/package-info.java new file mode 100644 index 0000000000..169e755919 --- /dev/null +++ b/org.eclipse.winery.common/src/main/java/org/eclipse/winery/common/propertydefinitionkv/package-info.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +/** + * This package defines the data structures for key/value property handling + * + * The XML Schema is generated based on the user configuration. The namespace + * for the schema is the namespace of the respective type with + * {@code /propertiesdefinition/} appended, where {@code } + * is the local name of the entity type, where the properties definition is + * defined. + * + */ +@XmlSchema(namespace = Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, elementFormDefault = XmlNsForm.QUALIFIED) +package org.eclipse.winery.common.propertydefinitionkv; + +import javax.xml.bind.annotation.XmlNsForm; +import javax.xml.bind.annotation.XmlSchema; + +import org.eclipse.winery.common.constants.Namespaces; + diff --git a/org.eclipse.winery.common/src/test/java/.gitkeep b/org.eclipse.winery.common/src/test/java/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/org.eclipse.winery.common/src/test/java/META-INF/MANIFEST.MF b/org.eclipse.winery.common/src/test/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/org.eclipse.winery.common/src/test/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/org.eclipse.winery.common/src/test/java/org/eclipse/winery/common/ModelUtilitiesTest.java b/org.eclipse.winery.common/src/test/java/org/eclipse/winery/common/ModelUtilitiesTest.java new file mode 100644 index 0000000000..650241d982 --- /dev/null +++ b/org.eclipse.winery.common/src/test/java/org/eclipse/winery/common/ModelUtilitiesTest.java @@ -0,0 +1,13 @@ +package org.eclipse.winery.common; + +import org.junit.Test; + +public class ModelUtilitiesTest { + + @Test + public void setPropertiesKV() { + // TODO: add some test here + // The test is difficult as a node type has to be generated with a wineryspropertiesdefinition, ... + } + +} diff --git a/org.eclipse.winery.common/src/test/java/org/eclipse/winery/common/TestUtil.java b/org.eclipse.winery.common/src/test/java/org/eclipse/winery/common/TestUtil.java new file mode 100644 index 0000000000..8c0c92409b --- /dev/null +++ b/org.eclipse.winery.common/src/test/java/org/eclipse/winery/common/TestUtil.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.common; + +import org.junit.Assert; +import org.junit.Test; + +public class TestUtil { + + @Test + public void testNamespaceToJavaPackageFullURL() { + Assert.assertEquals("org.example.www.tosca.nodetypes", Util.namespaceToJavaPackage("http://www.example.org/tosca/nodetypes")); + } + + @Test + public void testNamespaceToJavaPackageURLWithHostOnly() { + Assert.assertEquals("org.example.www", Util.namespaceToJavaPackage("http://www.example.org/")); + } + + @Test + public void testNamespaceToJavaPackageURLWithHostOnlyAndNoFinalSlash() { + Assert.assertEquals("org.example.www", Util.namespaceToJavaPackage("http://www.example.org")); + } + + @Test + public void testNamespaceToJavaPackageURLWithNoHost() { + Assert.assertEquals("plainNCname", Util.namespaceToJavaPackage("plainNCname")); + } + + @Test + public void testNCNameFromURL() { + Assert.assertEquals("http___www.example.org", Util.makeNCName("http://www.example.org")); + } + + @Test + public void testNCNameFromNCName() { + Assert.assertEquals("NCName", Util.makeNCName("NCName")); + } +} diff --git a/org.eclipse.winery.generators.ia/.gitignore b/org.eclipse.winery.generators.ia/.gitignore new file mode 100644 index 0000000000..bfe7d2ab63 --- /dev/null +++ b/org.eclipse.winery.generators.ia/.gitignore @@ -0,0 +1,9 @@ +.classpath +/.gradle +.settings +.project +/.sonar +/bin +/build +/src/main/resources/rebel.xml +/target diff --git a/org.eclipse.winery.generators.ia/about.html b/org.eclipse.winery.generators.ia/about.html new file mode 100644 index 0000000000..c7f2012429 --- /dev/null +++ b/org.eclipse.winery.generators.ia/about.html @@ -0,0 +1,155 @@ + + + + +About + + +

About This Content

+ +

January 24, 2014

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in (“Content”). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 (“EPL”) +and Apache License Version 2.0. +A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html +and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php. +You may elect to redistribute this code under either of these licenses. +For purposes of the EPL, “Program” will mean the Content. +

+ +

+If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party (“Redistributor”) and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor’s license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL and Apache License 2.0 still apply to any source code +in the Content and such source code may be obtained at http://www.eclipse.org. +

+ +

Third Party Content

+ +

Java Libraries

+ +
Apache Commons IO – Version 2.1
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-io/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Apache Commons Lang3 – Version 3.1
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-lang/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
JSP Standard Tag Library – Version 1.2
+ + + + + + + + + +
URLhttps://jstl.java.net/
LicenseCDDL and GPL with classpath exception (https://jersey.java.net/license.html). + The Eclipse Foundation elects to include this software in this distribution under the CDDL license. + A copy of the license is available at CDDL-v1.1.txt.
+ +
Logback Classic – Version 1.1.1
+ + + + + + + + + +
URLhttp://logback.qos.ch/
LicenseEPL/LGPL dual license. + EPL: http://www.eclipse.org/legal/epl-v10.html. + LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1. + A copy of the license is contained in the file LICENSE-logback.txt and is also available at http://logback.qos.ch/license.html. + The Eclipse Foundation elects to include this software in this distribution under the EPL license.
+ +
Logback Core – Version 1.1.1
+ + + + + + + + + +
URLhttp://logback.qos.ch/
LicenseEPL/LGPL dual license. + EPL: http://www.eclipse.org/legal/epl-v10.html. + LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1. + A copy of the license is contained in the file LICENSE-logback.txt and is also available at http://logback.qos.ch/license.html. + The Eclipse Foundation elects to include this software in this distribution under the EPL license.
+ +
SLF4J: slf4j-api – Version 1.7.6
+ + + + + + + + + +
URLhttp://www.slf4j.org/
LicenseMIT. A copy of the license is contained in the file LICENSE-slf4j-api.txt and is also available at http://www.slf4j.org/license.html
+ +
SLF4J: jcl-over-slf4j – Version 1.7.6
+ + + + + + + + + +
URLhttp://www.slf4j.org/legacy.html
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Winery: org.eclipse.winery.model.tosca – Version 0.1.20
+ + + + + + + + + +
URLhttp://eclipse.org/winery/
LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
+ +
xz for Java – Version 1.3
+ + + + + + + + + +
URLhttp://tukaani.org/xz/java.html
LicensePublic domain. A copy of the license is available at http://tukaani.org/xz/java.html
+ + + \ No newline at end of file diff --git a/org.eclipse.winery.generators.ia/about_files/Apache-LICENSE-2.0.txt b/org.eclipse.winery.generators.ia/about_files/Apache-LICENSE-2.0.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/org.eclipse.winery.generators.ia/about_files/Apache-LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/org.eclipse.winery.generators.ia/about_files/CDDL-v1.1.txt b/org.eclipse.winery.generators.ia/about_files/CDDL-v1.1.txt new file mode 100644 index 0000000000..7cc8719b3b --- /dev/null +++ b/org.eclipse.winery.generators.ia/about_files/CDDL-v1.1.txt @@ -0,0 +1,129 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL - Version 1.1) +1. Definitions. + + 1.1. “Contributor” means each individual or entity that creates or contributes to the creation of Modifications. + + 1.2. “Contributor Version” means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. + + 1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. + + 1.4. “Executable” means the Covered Software in any form other than Source Code. + + 1.5. “Initial Developer” means the individual or entity that first makes Original Software available under this License. + + 1.6. “Larger Work” means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. + + 1.7. “License” means this document. + + 1.8. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. + + 1.9. “Modifications” means the Source Code and Executable form of any of the following: + + A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; + + B. Any new file that contains any part of the Original Software or previous Modification; or + + C. Any new file that is contributed or otherwise made available under the terms of this License. + + 1.10. “Original Software” means the Source Code and Executable form of computer software code that is originally released under this License. + + 1.11. “Patent Claims” means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. + + 1.12. “Source Code” means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. + + 1.13. “You” (or “Your”) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, “You” includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients’ rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient’s rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. + +4. Versions of the License. + + 4.1. New Versions. + + Oracle is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. + +5. DISCLAIMER OF WARRANTY. + +COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as “Participant”) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. + + 6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. + + 6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY’S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. +8. U.S. GOVERNMENT END USERS. + +The Covered Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer software” (as that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software documentation” as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. +9. MISCELLANEOUS. + +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction’s conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys’ fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. +10. RESPONSIBILITY FOR CLAIMS. + +As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. \ No newline at end of file diff --git a/org.eclipse.winery.generators.ia/about_files/LICENSE-logback.txt b/org.eclipse.winery.generators.ia/about_files/LICENSE-logback.txt new file mode 100644 index 0000000000..b4fe24e02a --- /dev/null +++ b/org.eclipse.winery.generators.ia/about_files/LICENSE-logback.txt @@ -0,0 +1,15 @@ +Logback LICENSE +--------------- + +Logback: the reliable, generic, fast and flexible logging framework. +Copyright (C) 1999-2012, QOS.ch. All rights reserved. + +This program and the accompanying materials are dual-licensed under +either the terms of the Eclipse Public License v1.0 as published by +the Eclipse Foundation + + or (per the licensee's choosing) + +under the terms of the GNU Lesser General Public License version 2.1 +as published by the Free Software Foundation. + diff --git a/org.eclipse.winery.generators.ia/about_files/LICENSE-slf4j-api.txt b/org.eclipse.winery.generators.ia/about_files/LICENSE-slf4j-api.txt new file mode 100644 index 0000000000..37050c9568 --- /dev/null +++ b/org.eclipse.winery.generators.ia/about_files/LICENSE-slf4j-api.txt @@ -0,0 +1,21 @@ + Copyright (c) 2004-2013 QOS.ch + All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.generators.ia/pom.xml b/org.eclipse.winery.generators.ia/pom.xml new file mode 100644 index 0000000000..1fa28f2134 --- /dev/null +++ b/org.eclipse.winery.generators.ia/pom.xml @@ -0,0 +1,103 @@ + + + + 4.0.0 + + org.eclipse.winery + winery + 0.1.37-SNAPSHOT + + org.eclipse.winery.generators.ia + + UTF-8 + + + + org.eclipse.winery + org.eclipse.winery.common + 0.1.31 + compile + + + ch.qos.logback + logback-classic + 1.1.1 + compile + + + org.slf4j + jcl-over-slf4j + 1.7.6 + compile + + + org.eclipse.winery + org.eclipse.winery.model.tosca + 0.1.20 + compile + + + org.apache.commons + commons-compress + 1.6 + compile + + + org.tukaani + xz + + + + + + org.tukaani + xz + 1.3 + + + commons-io + commons-io + 2.1 + compile + + + junit + junit + 4.11 + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.16 + + true + + + + + diff --git a/org.eclipse.winery.generators.ia/src/main/java/org/eclipse/winery/generators/ia/Generator.java b/org.eclipse.winery.generators.ia/src/main/java/org/eclipse/winery/generators/ia/Generator.java new file mode 100644 index 0000000000..9a1eb50196 --- /dev/null +++ b/org.eclipse.winery.generators.ia/src/main/java/org/eclipse/winery/generators/ia/Generator.java @@ -0,0 +1,387 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Tobias Binz - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.generators.ia; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.apache.commons.compress.archivers.ArchiveEntry; +import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.ArchiveStreamFactory; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.utils.IOUtils; +import org.apache.commons.io.FileUtils; +import org.eclipse.winery.model.tosca.TBoolean; +import org.eclipse.winery.model.tosca.TInterface; +import org.eclipse.winery.model.tosca.TOperation; +import org.eclipse.winery.model.tosca.TParameter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Generator { + + private static final Logger logger = LoggerFactory.getLogger(Generator.class); + + // Placeholder applicable for all files + public static final String PLACEHOLDER_JAVA_PACKAGE = "IA_PACKAGE"; + public static final String PLACEHOLDER_NAMESPACE = "IA_NAMESPACE"; + public static final String PLACEHOLDER_CLASS_NAME = "IA_CLASS_NAME"; + public static final String PLACEHOLDER_IA_ARTIFACT_TEMPLATE_UPLOAD_URL = "IA_ARTIFACT_TEMPLATE_UPLOAD_URL"; + + // Placeholders in Java Service Files + public static final String PLACEHOLDER_GENERATED_WEBSERVICE_METHODS = "GENERATED_WEBSERVICE_METHODS"; + + // Template folder relative to resources folder in this project + public static final String TEMPLATE_PROJECT_FOLDER = "template/project"; + public static final String TEMPLATE_JAVA_FOLDER = "template/java"; + + private static final String TEMPLATE_JAVA_ABSTRACT_IA_SERVICE = "AbstractIAService.java.template"; + private static final String TEMPLATE_JAVA_TEMPLATE_SERVICE = "TemplateService.java.template"; + + private final TInterface tinterface; + private final File workingDir; + private final File outDir; + private final String name; + private final String javaPackage; + private final String namespace; + private final URL iaArtifactTemplateUploadUrl; + + + /** + * Creates a new IA Generator instance for the given {@link TInterface}. + * + * @param tinterface TOSCA interface to generate the IA for + * @param packageAndNamespace Package to be used for the generated Java + * code, e.g. 'org.opentosca.ia'. To generate the respective + * Namespace for the Web Service the components of the package + * are reverted, prepended with 'http://' and appended with '/'. + * This is provided by the user in a textfield in the Winery UI. + * @param iaArtifactTemplateUploadUrl The URL to which the generated IA + * should be posted. + * @param name unique and valid name to be used for the generated maven + * project name, java project name, class name, port type name. + * @param workingDir working directory to generate the files. This directory + * also will contain the ZIP file with the Eclipse project after + * generating it. + */ + public Generator(TInterface tinterface, String packageAndNamespace, URL iaArtifactTemplateUploadUrl, String name, File workingDir) { + super(); + this.tinterface = tinterface; + this.javaPackage = packageAndNamespace; + this.iaArtifactTemplateUploadUrl = iaArtifactTemplateUploadUrl; + this.name = name; + this.workingDir = new File(workingDir.getAbsolutePath() + File.separator + this.name); + this.outDir = new File(workingDir.getAbsolutePath()); + + if (this.workingDir.exists()) { + Generator.logger.error("Workdir " + this.workingDir + " already exits. This might lead to corrupted results if it is not empty!"); + } + + // Generate Namespace + String[] splitPkg = this.javaPackage.split("\\."); + String tmpNamespace = "http://"; + for (int i = splitPkg.length - 1; i >= 0; i--) { + tmpNamespace += splitPkg[i]; + // Add '.' if it is not the last iterations + if (i != 0) { + tmpNamespace += "."; + } + } + this.namespace = tmpNamespace += "/"; + } + + /** + * Generates the IA project. + * + * @return The ZIP file containing the maven/eclipse project to be + * downloaded by the user. + */ + public File generateProject() { + + try { + Path workingDirPath = this.workingDir.toPath(); + Files.createDirectories(workingDirPath); + + // directory to store the template files to generate the java files from + Path javaTemplateDir = workingDirPath.resolve("../java"); + Files.createDirectories(javaTemplateDir); + + // Copy template project and template java files + String s = this.getClass().getResource("").getPath(); + if (s.contains("jar!")) { + Generator.logger.trace("we work on a jar file"); + Generator.logger.trace("Location of the current class: {}", s); + + // we have a jar file + // format: file:/location...jar!...path-in-the-jar + // we only want to have location :) + int excl = s.lastIndexOf("!"); + s = s.substring(0, excl); + s = s.substring("file:".length()); + + try (JarFile jf = new JarFile(s);) { + Enumeration entries = jf.entries(); + while (entries.hasMoreElements()) { + JarEntry je = entries.nextElement(); + String name = je.getName(); + if (name.startsWith(Generator.TEMPLATE_PROJECT_FOLDER + "/") && (name.length() > (Generator.TEMPLATE_PROJECT_FOLDER.length() + 1))) { + // strip "template/" from the beginning to have paths without "template" starting relatively from the working dir + name = name.substring(Generator.TEMPLATE_PROJECT_FOLDER.length() + 1); + if (je.isDirectory()) { + // directory found + Path dir = workingDirPath.resolve(name); + Files.createDirectory(dir); + } else { + Path file = workingDirPath.resolve(name); + try (InputStream is = jf.getInputStream(je);) { + Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING); + } + } + } else if (name.startsWith(Generator.TEMPLATE_JAVA_FOLDER + "/") && (name.length() > (Generator.TEMPLATE_JAVA_FOLDER.length() + 1))) { + if (!je.isDirectory()) { + // we copy the file directly into javaTemplateDir + File f = new File(name); + Path file = javaTemplateDir.resolve(f.getName()); + try (InputStream is = jf.getInputStream(je);) { + Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING); + } + } + } + } + } + } else { + // we're running in debug mode, we can work on the plain file system + File templateProjectDir = new File(this.getClass().getResource("/" + Generator.TEMPLATE_PROJECT_FOLDER).getFile()); + FileUtils.copyDirectory(templateProjectDir, this.workingDir); + + File javaTemplatesDir = new File(this.getClass().getResource("/" + Generator.TEMPLATE_JAVA_FOLDER).getFile()); + FileUtils.copyDirectory(javaTemplatesDir, javaTemplateDir.toFile()); + } + + // Create Java Code Folder + String[] splitPkg = this.javaPackage.split("\\."); + String javaFolderString = this.workingDir.getAbsolutePath() + File.separator + "src" + File.separator + "main" + File.separator + "java"; + for (int i = 0; i < splitPkg.length; i++) { + javaFolderString += File.separator + splitPkg[i]; + } + + // Copy AbstractIAService.java + Path templateAbstractIAService = javaTemplateDir.resolve(Generator.TEMPLATE_JAVA_ABSTRACT_IA_SERVICE); + File javaAbstractIAService = new File(javaFolderString + File.separator + "AbstractIAService.java"); + Files.createDirectories(javaAbstractIAService.toPath().getParent()); + Files.copy(templateAbstractIAService, javaAbstractIAService.toPath(), StandardCopyOption.REPLACE_EXISTING); + + // Copy and rename IA_TestInterface.java + Path templateJavaService = javaTemplateDir.resolve(Generator.TEMPLATE_JAVA_TEMPLATE_SERVICE); + File javaService = new File(javaFolderString + File.separator + this.name + ".java"); + Files.createDirectories(javaService.toPath().getParent()); + Files.copy(templateJavaService, javaService.toPath(), StandardCopyOption.REPLACE_EXISTING); + + this.generateJavaFile(javaService); + this.updateFilesRecursively(this.workingDir); + return this.packageProject(); + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private void generateJavaFile(File javaService) throws IOException { + + // Generate methods + StringBuilder sb = new StringBuilder(); + + for (TOperation op : this.tinterface.getOperation()) { + // Annotations + sb.append("\t@WebMethod\n"); + sb.append("\t@SOAPBinding\n"); + sb.append("\t@Oneway\n"); + + // Signatur + String operationReturn = "void"; + sb.append("\tpublic " + operationReturn + " " + op.getName() + "(\n"); + + // Parameter + boolean first = true; + if (op.getInputParameters() != null) { + for (TParameter parameter : op.getInputParameters().getInputParameter()) { + String parameterName = parameter.getName(); + + // All parameters are handled as required parameters! + if (parameter.getRequired().equals(TBoolean.NO)) { + Generator.logger.debug("Optional parameters are not supported. Therefore, the optional parameter " + parameterName + " is handled as required parameter."); + } + + if (first) { + first = false; + sb.append("\t\t"); + } else { + sb.append(",\n\t\t"); + } + sb.append("@WebParam(name=\"" + parameterName + "\", targetNamespace=\"" + this.namespace + "\") String " + parameterName); + } + } + sb.append("\n\t) {\n"); + + // If there are output parameters we generate the respective HashMap + boolean outputParamsExist = (op.getOutputParameters() != null) && (!op.getOutputParameters().getOutputParameter().isEmpty()); + if (outputParamsExist) { + sb.append("\t\t// This HashMap holds the return parameters of this operation.\n"); + sb.append("\t\tfinal HashMap returnParameters = new HashMap();\n\n"); + } + + sb.append("\t\t// TODO: Implement your operation here.\n"); + + // Generate code to set output parameters + if (outputParamsExist) { + for (TParameter outputParam : op.getOutputParameters().getOutputParameter()) { + sb.append("\n\n\t\t// Output Parameter '" + outputParam.getName() + "' "); + if (outputParam.getRequired().equals(TBoolean.YES)) { + sb.append("(required)"); + } else { + sb.append("(optional)"); + } + sb.append("\n\t\t// TODO: Set " + outputParam.getName() + " parameter here."); + sb.append("\n\t\t// Do NOT delete the next line of code. Set \"\" as value if you want to return nothing or an empty result!"); + sb.append("\n\t\treturnParameters.put(\"" + outputParam.getName() + "\", \"TODO\");"); + } + sb.append("\n\n\t\tsendResponse(returnParameters);\n"); + } + + sb.append("\t}\n\n"); + } + + // Read file and replace placeholders + Charset cs = Charset.defaultCharset(); + List lines = new ArrayList<>(); + for (String line : Files.readAllLines(javaService.toPath(), cs)) { + // Replace web service method + line = line.replaceAll(Generator.PLACEHOLDER_GENERATED_WEBSERVICE_METHODS, sb.toString()); + lines.add(line); + } + + // Write file + OpenOption[] options = new OpenOption[] {StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING}; + Files.write(javaService.toPath(), lines, cs, options); + } + + /** + * Iterates recursively through all the files in the project working + * directory and tries to replace the global placeholders. + * + * @param folderOrFile to start with + */ + private void updateFilesRecursively(File folderOrFile) { + if (folderOrFile.isFile()) { + + if (folderOrFile.getAbsolutePath().endsWith(".jar")) { + return; + } + + Generator.logger.trace("Updating file " + folderOrFile); + + try { + // Read file and replace placeholders + Charset cs = Charset.defaultCharset(); + List lines = new ArrayList<>(); + for (String line : Files.readAllLines(folderOrFile.toPath(), cs)) { + line = line.replaceAll(Generator.PLACEHOLDER_CLASS_NAME, this.name); + line = line.replaceAll(Generator.PLACEHOLDER_JAVA_PACKAGE, this.javaPackage); + line = line.replaceAll(Generator.PLACEHOLDER_NAMESPACE, this.namespace); + line = line.replaceAll(Generator.PLACEHOLDER_IA_ARTIFACT_TEMPLATE_UPLOAD_URL, this.iaArtifactTemplateUploadUrl.toString()); + lines.add(line); + } + + // Write file + OpenOption[] options = new OpenOption[] {StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING}; + Files.write(folderOrFile.toPath(), lines, cs, options); + + } catch (IOException e) { + e.printStackTrace(); + } + + } else { + Generator.logger.trace("Updating folder " + folderOrFile); + for (File childFile : folderOrFile.listFiles()) { + this.updateFilesRecursively(childFile); + } + } + } + + /** + * Packages the generated project into a ZIP file which is stored in outDir + * and has the name of the Project. + * + * @return ZIP file + */ + private File packageProject() { + try { + File packagedProject = new File(this.outDir.getAbsoluteFile() + File.separator + this.name + ".zip"); + FileOutputStream fileOutputStream = new FileOutputStream(packagedProject); + final ArchiveOutputStream zos = new ArchiveStreamFactory().createArchiveOutputStream("zip", fileOutputStream); + + this.addFilesRecursively(this.workingDir.getAbsoluteFile(), this.workingDir.getAbsoluteFile().getAbsolutePath() + File.separator, zos); + + zos.finish(); + zos.close(); + + return packagedProject; + + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * Recursive Helper function for packageProject() + * + * @param folderOrFile to add into the archive + * @param baseDir + * @param zos ArchiveOutputStream to add the files to + */ + private void addFilesRecursively(File folderOrFile, String baseDir, ArchiveOutputStream zos) { + if (folderOrFile.isFile()) { + String nameOfFileInZip = folderOrFile.getAbsolutePath().replace(baseDir, ""); + Generator.logger.trace("Adding " + folderOrFile + " as " + nameOfFileInZip); + ArchiveEntry archiveEntry = new ZipArchiveEntry(nameOfFileInZip); + try (InputStream is = new FileInputStream(folderOrFile)) { + zos.putArchiveEntry(archiveEntry); + IOUtils.copy(is, zos); + zos.closeArchiveEntry(); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + Generator.logger.trace("Adding folder " + folderOrFile); + for (File childFile : folderOrFile.listFiles()) { + this.addFilesRecursively(childFile, baseDir, zos); + } + } + } +} diff --git a/org.eclipse.winery.generators.ia/src/main/resources/template/java/AbstractIAService.java.template b/org.eclipse.winery.generators.ia/src/main/resources/template/java/AbstractIAService.java.template new file mode 100644 index 0000000000..4e713aab7c --- /dev/null +++ b/org.eclipse.winery.generators.ia/src/main/resources/template/java/AbstractIAService.java.template @@ -0,0 +1,82 @@ +package IA_PACKAGE; + +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +import javax.annotation.Resource; +import javax.xml.ws.WebServiceContext; + +import org.apache.cxf.headers.Header; +import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.jaxws.context.WrappedMessageContext; +import org.apache.cxf.message.Message; +import org.w3c.dom.Node; + +import org.eclipse.winery.highlevelrestapi.HighLevelRestApi; + +public abstract class AbstractIAService { + + @Resource + private WebServiceContext context; + + protected void sendResponse (HashMap returnParameters) { + + // Extract message + WrappedMessageContext wrappedContext = (WrappedMessageContext) context.getMessageContext(); + Message message = wrappedContext.getWrappedMessage(); + + // Extract headers from message + List
headers = CastUtils.cast((List) message.get(Header.HEADER_LIST)); + + // Find ReplyTo and MessageID SOAP Header + String replyTo = null; + String messageID = null; + for (Header iter : headers) { + + Object headerObject = iter.getObject(); + + // Unmarshall to org.w3c.dom.Node + if (headerObject instanceof Node) { + Node node = (Node) headerObject; + String localPart = iter.getName().getLocalPart(); + String content = node.getTextContent(); + + // Extract ReplyTo Header value + if ("ReplyTo".equals(localPart)) { + replyTo = content; + } + + // Extract MessageID Header value + if ("MessageID".equals(localPart)) { + messageID = content; + } + } + } + + // Create asynchronous SOAP Response Message + StringBuilder builder = new StringBuilder(); + + builder.append(""); + builder.append(" "); + builder.append(" "); + builder.append(" "); + builder.append(" " + messageID + ""); + + // Insert return parameters into asynchronous SOAP Response Message + for (Entry paramIter : returnParameters.entrySet()) { + + String key = paramIter.getKey(); + String value = paramIter.getValue(); + + builder.append(" <" + key + ">" + value + ""); + } + + builder.append(" "); + builder.append(" "); + builder.append(""); + + // Send SOAP Response Message back to requester + HighLevelRestApi.Post(replyTo, builder.toString(), ""); + } +} diff --git a/org.eclipse.winery.generators.ia/src/main/resources/template/java/TemplateService.java.template b/org.eclipse.winery.generators.ia/src/main/resources/template/java/TemplateService.java.template new file mode 100644 index 0000000000..7930c365c2 --- /dev/null +++ b/org.eclipse.winery.generators.ia/src/main/resources/template/java/TemplateService.java.template @@ -0,0 +1,16 @@ +package IA_PACKAGE; + +import java.util.HashMap; + +import javax.jws.Oneway; +import javax.jws.WebMethod; +import javax.jws.WebParam; +import javax.jws.WebService; +import javax.jws.soap.SOAPBinding; + +@WebService +public class IA_CLASS_NAME extends AbstractIAService { + +GENERATED_WEBSERVICE_METHODS + +} \ No newline at end of file diff --git a/org.eclipse.winery.generators.ia/src/main/resources/template/project/README.txt b/org.eclipse.winery.generators.ia/src/main/resources/template/project/README.txt new file mode 100644 index 0000000000..bce220db9f --- /dev/null +++ b/org.eclipse.winery.generators.ia/src/main/resources/template/project/README.txt @@ -0,0 +1,61 @@ +########################################################################### +GENERATED IMPLEMENTATION ARTIFACT SKELETON FOR IA_CLASS_NAME + +Interface Name: IA_CLASS_NAME +Namespace: IA_NAMESPACE +Java Package: IA_PACKAGE +URL: IA_ARTIFACT_TEMPLATE_UPLOAD_URL../ +########################################################################### + +##### Preconditions +To develop and build this Implementation Artifact you need Maven and Eclipse. ++ How to install maven is described at the end of this file ++ If you use an Eclipse workspace for the first time with a maven project you've to run this command before starting eclipse: + mvn -Declipse.workspace="" eclipse:configure-workspace + - When using Windows: Make sure you replace '\' (backslashes) with '/' ('slashes') + - It doesn't hurt to run it multiple times + - This command must not be executed in a particular folder + +##### Preparations ++ Unzip the archive generated by Winery into a location of your choice. ++ Note: All following maven commands are executed on a shell in the root folder of the Implementation Artifact. + +##### Create eclipse project +- Run: mvn eclipse:eclipse +- Open Eclipse +- 'File' -> 'Import' -> 'Existing Project into Workspace' -> click 'Next' +- Click 'Browse' and select folder where you unzipped the generated Implementation Artifact +- Select the project from the list and click 'Finish' + +##### Test your Implementation Artifact +- Run: mvn clean package tomcat7:run-war + (more information: http://tomcat.apache.org/maven-plugin-trunk/tomcat7-maven-plugin/plugin-info.html) +- Open this page to see the list of available services: http://localhost:9090/services/ +- This page also links the WSDL +- With the WSDL your're able to test your IA using SOAPui or other tools. + +##### Upload your Implementation Artifact +You have to options to do this: + +### 1) Automatically (to the Winery instance this IA project was generated with) +- Run: mvn deploy +- The WAR is directly uploaded into the correct ArtifactTemplate. Previous versions are overwritten. + +### 2) Manually +- Run: mvn clean package +- Locate the WAR file in the /target folder +- Open Winery in your browser, locate the NodeType and then click through to the Implementation of the respective Interface, its Implementation Artifacts and lastly to the ArtifactTemplate representing this IA. +- Upload the WAR file by clicking on the "Attach file..." button + + +##### Install Maven +- Download latest release of Maven: http://maven.apache.org/download.cgi (Binary zip) +- Unzip into directory of your choice +- Set environment variables (in system environment variables, not the ones for the user account): + + Check that the variables JAVA_HOME and JRE_HOME are set. If not create them and enter the path to your JDK, e.g., C:\Program Files (x86)\Java\jdk1.6.0_21 + + Create the following environment variables + M2_HOME = C:\Path\where\your\maven\was\unzipped\to (no backslash at the end) + M2 = %M2_HOME%\bin + MAVEN_OPTS = -Xms256m -Xmx512m + + Append ;%M2% to the 'Path' environment variable. Make sure to separate the new entry with a semicolon (;) from the last one. +- After that you have to open a new command line windows (if you already opened one) to let the changes take effect. \ No newline at end of file diff --git a/org.eclipse.winery.generators.ia/src/main/resources/template/project/pom.xml b/org.eclipse.winery.generators.ia/src/main/resources/template/project/pom.xml new file mode 100644 index 0000000000..1a0b7153b3 --- /dev/null +++ b/org.eclipse.winery.generators.ia/src/main/resources/template/project/pom.xml @@ -0,0 +1,251 @@ + + + 4.0.0 + IA_PACKAGE + IA_CLASS_NAME + war + 1.0-SNAPSHOT + Implementation Artifact IA_CLASS_NAME + + + + 2471.de + http://2471.de/maven2 + + + + + 9090 + IA_ARTIFACT_TEMPLATE_UPLOAD_URL + UTF-8 + 2.7.6 + 0.1.6 + + + + + + + + + + org.eclipse.winery + org.eclipse.winery.highlevelrestapi + ${highlevelrestapi.version} + + + junit + junit + 4.5 + test + + + org.springframework + spring-web + 3.0.7.RELEASE + + + org.springframework + spring-context + 3.0.7.RELEASE + + + org.apache.cxf + cxf-rt-frontend-jaxws + ${cxf.version} + + + org.apache.cxf + cxf-rt-frontend-simple + ${cxf.version} + + + org.apache.cxf + cxf-rt-transports-http + ${cxf.version} + + + + IA_CLASS_NAME + + + maven-compiler-plugin + 3.0 + + 1.6 + 1.6 + + + + + org.apache.maven.plugins + maven-eclipse-plugin + 2.9 + + false + true + + + + + org.apache.cxf + cxf-java2ws-plugin + ${cxf.version} + + + org.apache.cxf + cxf-rt-frontend-jaxws + ${cxf.version} + + + org.apache.cxf + cxf-rt-frontend-simple + ${cxf.version} + + + + + process-classes + process-classes + + IA_PACKAGE.IA_CLASS_NAME + ${basedir}/src/main/webapp/wsdl/IA_CLASS_NAME.wsdl + true + true + + + java2ws + + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.3 + + src/main/webapp/WEB-INF/web.xml + + + + + + org.codehaus.gmaven + gmaven-plugin + 1.4 + + + org.codehaus.gmaven.runtime + gmaven-runtime-1.7 + 1.2 + + + org.apache.httpcomponents + httpmime + 4.2.1 + + + org.apache.httpcomponents + httpcore + 4.2.1 + + + org.apache.httpcomponents + httpclient + 4.2.1 + + + + + upload2winery + + deploy + + + execute + + + 1.7 + + import org.apache.http.impl.client.DefaultHttpClient + import org.apache.http.client.methods.HttpPost + import org.apache.http.entity.mime.MultipartEntity + import org.apache.http.entity.mime.content.FileBody + + // Get WAR file + def name = "target/${project.build.finalName}.war" + println "Archive file: $name" + def f = new File(name) + + // POST file + DefaultHttpClient httpclient = new DefaultHttpClient() + println "Upload URL: ${winery.upload.url}" + def post = new HttpPost("${winery.upload.url}") + def entity = new MultipartEntity() + def fileBody = new FileBody(f) + entity.addPart("files[]", fileBody) + post.setEntity(entity) + + // Process response + def response = httpclient.execute(post) + def status = response.getStatusLine() + if( !(status ==~ /.*Created.*/) ) + fail("IA upload to Winery FAILED, please upload manually. (HTTP status code: $status)" ) + else + println "IA upload finished sucessfully (HTTP status code $status)" + + + + + + + + + + + + org.apache.tomcat.maven + tomcat7-maven-plugin + 2.1 + + + ${run.HttpPort} + + / + + false + + + + + + org.apache.maven.plugins + maven-install-plugin + + + default-install + none + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + + default-deploy + none + + + + + + + + \ No newline at end of file diff --git a/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/beans.xml b/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000000..2a926f2e93 --- /dev/null +++ b/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + diff --git a/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/web.xml b/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..f7bd1bfcca --- /dev/null +++ b/org.eclipse.winery.generators.ia/src/main/resources/template/project/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,33 @@ + + + IA_CLASS_NAME + + index.html + index.htm + index.jsp + default.html + default.htm + default.jsp + + + Apache CXF Endpoint + cxf + cxf + org.apache.cxf.transport.servlet.CXFServlet + 1 + + + cxf + /services/* + + + 60 + + + contextConfigLocation + WEB-INF/beans.xml + + + org.springframework.web.context.ContextLoaderListener + + diff --git a/org.eclipse.winery.generators.ia/src/test/java/META-INF/MANIFEST.MF b/org.eclipse.winery.generators.ia/src/test/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/org.eclipse.winery.generators.ia/src/test/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/org.eclipse.winery.generators.ia/src/test/java/org/eclipse/winery/generators/ia/Test.java b/org.eclipse.winery.generators.ia/src/test/java/org/eclipse/winery/generators/ia/Test.java new file mode 100644 index 0000000000..73d4127a0b --- /dev/null +++ b/org.eclipse.winery.generators.ia/src/test/java/org/eclipse/winery/generators/ia/Test.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Tobias Binz - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.generators.ia; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.eclipse.winery.model.tosca.ObjectFactory; +import org.eclipse.winery.model.tosca.TInterface; +import org.eclipse.winery.model.tosca.TNodeType; +import org.eclipse.winery.model.tosca.TOperation; +import org.eclipse.winery.model.tosca.TOperation.InputParameters; +import org.eclipse.winery.model.tosca.TOperation.OutputParameters; +import org.eclipse.winery.model.tosca.TParameter; +import org.junit.BeforeClass; + +public class Test { + + private static Path WORKING_DIR; + + + @BeforeClass + public static void initializeWorkingDir() throws IOException { + Test.WORKING_DIR = Files.createTempDirectory("IAGenerator"); + } + + @org.junit.Test + public void testInOut() throws MalformedURLException { + ObjectFactory f = new ObjectFactory(); + + TInterface tinterface = f.createTInterface(); + tinterface.setName("http://www.example.org/interfaces/lifecycle"); + + TOperation op1 = f.createTOperation(); + op1.setName("Op1InOut"); + tinterface.getOperation().add(op1); + InputParameters op1InputParameters = f.createTOperationInputParameters(); + + TParameter op1ip1 = f.createTParameter(); + op1ip1.setName("op1ip1"); + op1ip1.setType("xs:string"); + op1InputParameters.getInputParameter().add(op1ip1); + TParameter op1ip2 = f.createTParameter(); + op1ip2.setName("op1ip2"); + op1ip2.setType("xs:string"); + op1InputParameters.getInputParameter().add(op1ip2); + op1.setInputParameters(op1InputParameters); + + OutputParameters op1OutputParameters = f.createTOperationOutputParameters(); + TParameter op1op1 = f.createTParameter(); + op1op1.setName("op1op1"); + op1op1.setType("xs:string"); + op1OutputParameters.getOutputParameter().add(op1op1); + TParameter op1op2 = f.createTParameter(); + op1op2.setName("op1op2"); + op1op1.setType("xs:string"); + op1OutputParameters.getOutputParameter().add(op1op2); + op1.setOutputParameters(op1OutputParameters); + + TNodeType nodeType = f.createTNodeType(); + nodeType.setName("test"); + nodeType.setTargetNamespace("http://asd.com"); + + Generator gen = new Generator(tinterface, "org.opentosca.ia", new URL("http://asd.com"), "testname", Test.WORKING_DIR.toFile()); + File generateProject = gen.generateProject(); + System.out.println(generateProject); + } + + @org.junit.Test + public void testMultipleOperationsInOrOut() throws MalformedURLException { + ObjectFactory f = new ObjectFactory(); + + TInterface tinterface = f.createTInterface(); + tinterface.setName("TestInOrOut"); + + TOperation opIn = f.createTOperation(); + opIn.setName("OpIn"); + tinterface.getOperation().add(opIn); + + InputParameters op1InputParameters = f.createTOperationInputParameters(); + TParameter op1ip1 = f.createTParameter(); + op1ip1.setName("op1ip1"); + op1ip1.setType("xs:string"); + op1InputParameters.getInputParameter().add(op1ip1); + TParameter op1ip2 = f.createTParameter(); + op1ip2.setName("op1ip2"); + op1ip2.setType("xs:string"); + op1InputParameters.getInputParameter().add(op1ip2); + opIn.setInputParameters(op1InputParameters); + + TOperation opOut = f.createTOperation(); + opOut.setName("OpOut"); + tinterface.getOperation().add(opOut); + + OutputParameters op1OutputParameters = f.createTOperationOutputParameters(); + TParameter op1op1 = f.createTParameter(); + op1op1.setName("op1op1"); + op1op1.setType("xs:string"); + op1OutputParameters.getOutputParameter().add(op1op1); + TParameter op1op2 = f.createTParameter(); + op1op2.setName("op1op2"); + op1op1.setType("xs:string"); + op1OutputParameters.getOutputParameter().add(op1op2); + opOut.setOutputParameters(op1OutputParameters); + + TNodeType nodeType = f.createTNodeType(); + nodeType.setName("test"); + nodeType.setTargetNamespace("http://asd.com"); + + Generator gen = new Generator(tinterface, "org.opentosca.ia", new URL("http://asd.com"), "testname", Test.WORKING_DIR.toFile()); + File generateProject = gen.generateProject(); + System.out.println(generateProject); + } + + @org.junit.Test + public void testNoParams() throws MalformedURLException { + ObjectFactory f = new ObjectFactory(); + + TInterface tinterface = f.createTInterface(); + tinterface.setName("TestNoParams"); + + TOperation opIn = f.createTOperation(); + opIn.setName("OpNoParams"); + tinterface.getOperation().add(opIn); + + TNodeType nodeType = f.createTNodeType(); + nodeType.setName("test"); + nodeType.setTargetNamespace("http://asd.com"); + + Generator gen = new Generator(tinterface, "org.opentosca.ia", new URL("http://asd.com"), "testname", Test.WORKING_DIR.toFile()); + File generateProject = gen.generateProject(); + System.out.println(generateProject); + } + +} diff --git a/org.eclipse.winery.repository.client/.gitignore b/org.eclipse.winery.repository.client/.gitignore new file mode 100644 index 0000000000..3576cf9255 --- /dev/null +++ b/org.eclipse.winery.repository.client/.gitignore @@ -0,0 +1,14 @@ +.classpath +/.gradle +.project +.settings/org.eclipse.core.resources.prefs +.settings/org.eclipse.jdt.core.prefs +.settings/org.eclipse.m2e.core.prefs +.settings/org.eclipse.wst.common.component +.settings/org.eclipse.wst.common.project.facet.core.xml +.settings/org.eclipse.wst.validation.prefs +/.sonar +/bin +/build +/src/main/resources/rebel.xml +/target diff --git a/org.eclipse.winery.repository.client/.settings/de.loskutov.anyedit.AnyEditTools.prefs b/org.eclipse.winery.repository.client/.settings/de.loskutov.anyedit.AnyEditTools.prefs new file mode 100644 index 0000000000..a8ddcc62b8 --- /dev/null +++ b/org.eclipse.winery.repository.client/.settings/de.loskutov.anyedit.AnyEditTools.prefs @@ -0,0 +1,16 @@ +activeContentFilterList=*.makefile,makefile,*.Makefile,Makefile,Makefile.*,*.mk,MANIFEST.MF,*.java +addNewLine=true +convertActionOnSaave=AnyEdit.CnvrtSpacesToTabs +eclipse.preferences.version=1 +ignoreBlankLinesWhenTrimming=false +inActiveContentFilterList= +javaTabWidthForJava=true +org.eclipse.jdt.ui.editor.tab.width=4 +projectPropsEnabled=false +removeTrailingSpaces=true +replaceAllSpaces=false +replaceAllTabs=false +saveAndAddLine=true +saveAndConvert=true +saveAndTrim=true +useModulo4Tabs=true diff --git a/org.eclipse.winery.repository.client/README.md b/org.eclipse.winery.repository.client/README.md new file mode 100644 index 0000000000..b530bfa894 --- /dev/null +++ b/org.eclipse.winery.repository.client/README.md @@ -0,0 +1,5 @@ +This project provides a Java client to a Winery repository. + +## Build fat JARs +To build a fatJar of the repository client which also contains all the dependencies use the maven profile fatJar (i.e., run `mvn clean package -P fatJar`). +Maven will create a JAR called `org.eclipse.winery.repository.client-*-jar-with-dependencies.jar` in `/target`. \ No newline at end of file diff --git a/org.eclipse.winery.repository.client/about.html b/org.eclipse.winery.repository.client/about.html new file mode 100644 index 0000000000..9fe8131bfb --- /dev/null +++ b/org.eclipse.winery.repository.client/about.html @@ -0,0 +1,286 @@ + + + + +About + + +

About This Content

+ +

January 24, 2014

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in (“Content”). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 (“EPL”) +and Apache License Version 2.0. +A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html +and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php. +You may elect to redistribute this code under either of these licenses. +For purposes of the EPL, “Program” will mean the Content. +

+ +

+If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party (“Redistributor”) and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor’s license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL and Apache License 2.0 still apply to any source code +in the Content and such source code may be obtained at http://www.eclipse.org. +

+ +

Third Party Content

+ +

Java Libraries

+ +
Apache Commons Configuration – Version 1.9
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-configuration/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Apache Commons IO – Version 2.1
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-io/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Apache Commons Lang – Version 2.6
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-lang/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Apache Commons Lang3 – Version 3.1
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-lang/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
jackson-annotations – Version 2.2.2
+ + + + + + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-annotations
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
NoteThe license was explicitly added in version 2.2.3 and 2.3.0. See Issue #14 and LICENSE in the source repository.
+ +
jackson-core – Version 2.2.2
+ + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-core and http://wiki.fasterxml.com/JacksonHome
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
jackson-databind – Version 2.2.2
+ + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-databind
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
jackson-jaxrs-base – Version 2.2.2
+ + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-jaxrs-providers/tree/master/base
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
jackson-jaxrs-json-provider – Version 2.2.2
+ + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-jaxrs-providers/tree/master/json
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
jackson-module-jaxb-annotations – Version 2.3.0
+ + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-module-jaxb-annotations
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0. + The license is added via the oss-parent project.
+ +
Jersey Client – Version 1.17
+ + + + + + + + + +
URLjersey.java.net/
LicenseCDDL and GPL with classpath exception (https://jersey.java.net/license.html). + The Eclipse Foundation elects to include this software in this distribution under the CDDL license. + A copy of the license is available at CDDL-v1.1.txt.
+ +
Jersey Core – Version 1.17
+ + + + + + + + + +
URLjersey.java.net/
LicenseCDDL and GPL with classpath exception. A copy of the license is available at https://jersey.java.net/license.html
+ +
JSP Standard Tag Library – Version 1.2
+ + + + + + + + + +
URLhttps://jstl.java.net/
LicenseCDDL and GPL with classpath exception. A copy of the license is available at https://jstl.java.net/license.html
+ +
Logback Classic – Version 1.1.1
+ + + + + + + + + +
URLhttp://logback.qos.ch/
LicenseEPL/LGPL dual-license. A copy of the license is contained in the file LICENSE-logback.txt and is also available at http://logback.qos.ch/license.html
+ +
Logback Core – Version 1.1.1
+ + + + + + + + + +
URLhttp://logback.qos.ch/
LicenseEPL/LGPL dual-license. A copy of the license is contained in the file LICENSE-logback.txt and is also available at http://logback.qos.ch/license.html
+ +
SLF4J: slf4j-api – Version 1.7.6
+ + + + + + + + + +
URLhttp://www.slf4j.org/
LicenseMIT. A copy of the license is contained in the file LICENSE-slf4j-api.txt and is also available at http://www.slf4j.org/license.html
+ +
SLF4J: jcl-over-slf4j – Version 1.7.6
+ + + + + + + + + +
URLhttp://www.slf4j.org/legacy.html
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Winery: org.eclipse.winery.common – ${project.version}
+ + + + + + + + + +
URLhttp://eclipse.org/winery/
LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
+ +
Winery: org.eclipse.winery.model.tosca – Version 0.1.20
+ + + + + + + + + +
URLhttp://eclipse.org/winery/
LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
+ +

XSD Files

+ +
TOSCA-v1.0.xsd
+ + + + + + + + + +
URLhttp://docs.oasis-open.org/tosca/TOSCA/v1.0/os/schemas/
LicenseCopyright (c) OASIS Open 2013. All rights reserved.
+ + + \ No newline at end of file diff --git a/org.eclipse.winery.repository.client/about_files/Apache-LICENSE-2.0.txt b/org.eclipse.winery.repository.client/about_files/Apache-LICENSE-2.0.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/org.eclipse.winery.repository.client/about_files/Apache-LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/org.eclipse.winery.repository.client/about_files/CDDL-v1.1.txt b/org.eclipse.winery.repository.client/about_files/CDDL-v1.1.txt new file mode 100644 index 0000000000..7cc8719b3b --- /dev/null +++ b/org.eclipse.winery.repository.client/about_files/CDDL-v1.1.txt @@ -0,0 +1,129 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL - Version 1.1) +1. Definitions. + + 1.1. “Contributor” means each individual or entity that creates or contributes to the creation of Modifications. + + 1.2. “Contributor Version” means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. + + 1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. + + 1.4. “Executable” means the Covered Software in any form other than Source Code. + + 1.5. “Initial Developer” means the individual or entity that first makes Original Software available under this License. + + 1.6. “Larger Work” means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. + + 1.7. “License” means this document. + + 1.8. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. + + 1.9. “Modifications” means the Source Code and Executable form of any of the following: + + A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; + + B. Any new file that contains any part of the Original Software or previous Modification; or + + C. Any new file that is contributed or otherwise made available under the terms of this License. + + 1.10. “Original Software” means the Source Code and Executable form of computer software code that is originally released under this License. + + 1.11. “Patent Claims” means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. + + 1.12. “Source Code” means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. + + 1.13. “You” (or “Your”) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, “You” includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients’ rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient’s rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. + +4. Versions of the License. + + 4.1. New Versions. + + Oracle is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. + +5. DISCLAIMER OF WARRANTY. + +COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as “Participant”) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. + + 6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. + + 6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY’S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. +8. U.S. GOVERNMENT END USERS. + +The Covered Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer software” (as that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software documentation” as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. +9. MISCELLANEOUS. + +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction’s conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys’ fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. +10. RESPONSIBILITY FOR CLAIMS. + +As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. \ No newline at end of file diff --git a/org.eclipse.winery.repository.client/about_files/LICENSE-logback.txt b/org.eclipse.winery.repository.client/about_files/LICENSE-logback.txt new file mode 100644 index 0000000000..b4fe24e02a --- /dev/null +++ b/org.eclipse.winery.repository.client/about_files/LICENSE-logback.txt @@ -0,0 +1,15 @@ +Logback LICENSE +--------------- + +Logback: the reliable, generic, fast and flexible logging framework. +Copyright (C) 1999-2012, QOS.ch. All rights reserved. + +This program and the accompanying materials are dual-licensed under +either the terms of the Eclipse Public License v1.0 as published by +the Eclipse Foundation + + or (per the licensee's choosing) + +under the terms of the GNU Lesser General Public License version 2.1 +as published by the Free Software Foundation. + diff --git a/org.eclipse.winery.repository.client/about_files/LICENSE-slf4j-api.txt b/org.eclipse.winery.repository.client/about_files/LICENSE-slf4j-api.txt new file mode 100644 index 0000000000..37050c9568 --- /dev/null +++ b/org.eclipse.winery.repository.client/about_files/LICENSE-slf4j-api.txt @@ -0,0 +1,21 @@ + Copyright (c) 2004-2013 QOS.ch + All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.repository.client/pom.xml b/org.eclipse.winery.repository.client/pom.xml new file mode 100644 index 0000000000..68cd739884 --- /dev/null +++ b/org.eclipse.winery.repository.client/pom.xml @@ -0,0 +1,160 @@ + + + + 4.0.0 + + org.eclipse.winery + winery + 0.1.37-SNAPSHOT + + org.eclipse.winery.repository.client + + UTF-8 + + + + + true + + default + + none + + + + fatJar + + package + + + + + + com.fasterxml.jackson.core + jackson-databind + 2.2.2 + compile + + + ch.qos.logback + logback-classic + 1.1.1 + compile + + + org.slf4j + jcl-over-slf4j + 1.7.6 + compile + + + org.eclipse.winery + org.eclipse.winery.model.tosca + 0.1.18 + compile + + + com.sun.jersey + jersey-core + 1.17 + compile + + + org.eclipse.winery + org.eclipse.winery.common + 0.1.31 + compile + + + com.fasterxml.jackson.core + jackson-core + 2.2.2 + compile + + + com.sun.jersey + jersey-client + 1.17 + compile + + + commons-configuration + commons-configuration + 1.9 + compile + + + commons-logging + commons-logging + + + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + 2.2.2 + + + junit + junit + 4.11 + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.16 + + true + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.4 + + + jar-with-dependencies + + + + + assemble-all + ${package.fatJar} + + single + + + + + + + diff --git a/org.eclipse.winery.repository.client/src/main/java/META-INF/MANIFEST.MF b/org.eclipse.winery.repository.client/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/org.eclipse.winery.repository.client/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/IWineryRepositoryClient.java b/org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/IWineryRepositoryClient.java new file mode 100644 index 0000000000..5b104cd340 --- /dev/null +++ b/org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/IWineryRepositoryClient.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.client; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.common.interfaces.IWineryRepository; +import org.eclipse.winery.common.interfaces.QNameAlreadyExistsException; + +public interface IWineryRepositoryClient extends IWineryRepository { + + /** + * Adds an URI to the list of known repositories + * + * SIDE EFFECT: If currently no primary repository is defined, the given + * repository is used as primary repository + * + * @param uri the URI of the repository + */ + void addRepository(String uri); + + /** + * Get the currently defined primary repository + */ + String getPrimaryRepository(); + + /** + * Sets the primary repository + * + * SIDE EFFECT: If the repository is not known as general repository (via + * addRepository), the given repository is added to the list of known + * repositories + * + * @param uri + */ + void setPrimaryRepository(String uri); + + /** + * Checks whether the primary repository is available to be used. Typically, + * this method should return "true". In case of network or server failures, + * the result is "false". Note that the availability may change over time + * and also a repository might become unavailable during querying it. + * + * This method also returns "false" if no primary repository is set. For + * instance, this is the case of no repository is registered at the client. + * + * @return true if the repository is reachable over network, false otherwise + */ + boolean primaryRepositoryAvailable(); + + /** + * Creates a component of the type idClass. + * + * @param qname + * @param type + * @throws QNameAlreadyExistsException + */ + void createComponent(QName qname, Class idClass) throws QNameAlreadyExistsException; +} diff --git a/org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/WineryRepositoryClient.java b/org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/WineryRepositoryClient.java new file mode 100644 index 0000000000..216c6234a1 --- /dev/null +++ b/org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/WineryRepositoryClient.java @@ -0,0 +1,746 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.client; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.beans.NamespaceIdOptionalName; +import org.eclipse.winery.common.constants.MimeTypes; +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.common.ids.IdUtil; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.common.interfaces.QNameAlreadyExistsException; +import org.eclipse.winery.common.interfaces.QNameWithName; +import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition; +import org.eclipse.winery.model.tosca.TDefinitions; +import org.eclipse.winery.model.tosca.TEntityType; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TTopologyTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.config.ClientConfig; +import com.sun.jersey.api.client.config.DefaultClientConfig; +import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory; +import com.sun.jersey.client.urlconnection.URLConnectionClientHandler; +import com.sun.jersey.core.util.MultivaluedMapImpl; + +public final class WineryRepositoryClient implements IWineryRepositoryClient { + + private static final Logger logger = LoggerFactory.getLogger(WineryRepositoryClient.class); + + // switch off validation, currently causes more trouble than it brings + private static final boolean VALIDATING = false; + + private final Collection knownURIs = new HashSet(); + private final Collection repositoryResources = new HashSet(); + private final Client client; + private final ObjectMapper mapper = new ObjectMapper(); + + private final Map, Map> entityTypeDataCache; + + private final Map nameCache; + private static final int MAX_NAME_CACHE_SIZE = 1000; + + private String primaryRepository = null; + private WebResource primaryWebResource = null; + + // thread-safe JAXB as inspired by https://jaxb.java.net/guide/Performance_and_thread_safety.html + // The other possibility: Each subclass sets JAXBContext.newInstance(theSubClass.class); in its static {} part. + // This seems to be more complicated than listing all subclasses in initContext + public final static JAXBContext context = WineryRepositoryClient.initContext(); + + // schema aware document builder + private final DocumentBuilder toscaDocumentBuilder; + + + // taken from http://stackoverflow.com/a/15253142/873282 + private static class ConnectionFactory implements HttpURLConnectionFactory { + + Proxy proxy; + + + private void initializeProxy() { + this.proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8888)); + } + + @Override + public HttpURLConnection getHttpURLConnection(URL url) throws IOException { + this.initializeProxy(); + return (HttpURLConnection) url.openConnection(this.proxy); + } + } + + + /** + * Creates the client without the use of any proxy + */ + public WineryRepositoryClient() { + this(false); + } + + /** + * @param useProxy if a debugging proxy should be used + * + * @throws IllegalStateException if DOM parser could not be created + */ + public WineryRepositoryClient(boolean useProxy) { + ClientConfig clientConfig = new DefaultClientConfig(); + clientConfig.getClasses().add(JacksonJsonProvider.class); + if (useProxy) { + URLConnectionClientHandler ch = new URLConnectionClientHandler(new ConnectionFactory()); + this.client = new Client(ch, clientConfig); + } else { + this.client = Client.create(clientConfig); + } + + this.entityTypeDataCache = new HashMap<>(); + this.nameCache = new HashMap<>(); + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + if (WineryRepositoryClient.VALIDATING) { + factory.setValidating(true); + SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema; + URL resource = this.getClass().getResource("/TOSCA-v1.0.xsd"); + try { + schema = schemaFactory.newSchema(resource); + } catch (SAXException e) { + throw new IllegalStateException("Schema could not be initalized", e); + } + factory.setSchema(schema); + } + try { + this.toscaDocumentBuilder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new IllegalStateException("document builder could not be initalized", e); + } + /* + TODO: include this somehow - in the case of VALIDATING + + Does not work with TTopolgoyTemplate as this is not allowed in the root of an XML document + this.toscaDocumentBuilder.setErrorHandler(new ErrorHandler() { + + @Override + public void warning(SAXParseException arg0) throws SAXException { + throw arg0; + } + + @Override + public void fatalError(SAXParseException arg0) throws SAXException { + throw arg0; + } + + @Override + public void error(SAXParseException arg0) throws SAXException { + throw arg0; + } + }); + */ + } + + private static JAXBContext initContext() { + // code copied+adapted from JAXBSupport + + JAXBContext context; + try { + // For winery classes, eventually the package+jaxb.index method could be better. See http://stackoverflow.com/a/3628525/873282 + // @formatter:off + context = JAXBContext.newInstance( + TDefinitions.class, + WinerysPropertiesDefinition.class); + // @formatter:on + } catch (JAXBException e) { + WineryRepositoryClient.logger.error("Could not initialize JAXBContext", e); + throw new IllegalStateException(e); + } + return context; + } + + /** + * Creates a marshaller + * + * @throws IllegalStateException if marshaller could not be instantiated + */ + private static Marshaller createMarshaller() { + // code copied+adapted from JAXBSupport + Marshaller m; + try { + m = WineryRepositoryClient.context.createMarshaller(); + // pretty printed output is required as the XML is sent 1:1 to the browser for editing + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + // not possible here: m.setProperty("com.sun.xml.bind.namespacePrefixMapper", JAXBSupport.prefixMapper); + } catch (JAXBException e) { + WineryRepositoryClient.logger.error("Could not instantiate marshaller", e); + throw new IllegalStateException(e); + } + return m; + } + + /** + * Creates a unmarshaller + * + * @throws IllegalStateException if unmarshaller could not be instantiated + */ + private static Unmarshaller createUnmarshaller() { + Unmarshaller um; + try { + um = WineryRepositoryClient.context.createUnmarshaller(); + } catch (JAXBException e) { + WineryRepositoryClient.logger.error("Could not instantiate unmarshaller", e); + throw new IllegalStateException(e); + } + return um; + } + + /*** methods directly from IWineryRepositoryClient ***/ + + /** + * {@inheritDoc} + */ + @Override + public void addRepository(String uri) { + if (this.knownURIs.add(uri)) { + // URI is not already known, add a new resource + WebResource wr = this.client.resource(uri); + this.repositoryResources.add(wr); + if (this.primaryRepository == null) { + this.primaryRepository = uri; + this.primaryWebResource = wr; + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public String getPrimaryRepository() { + return this.primaryRepository; + } + + /** + * {@inheritDoc} + */ + @Override + public void setPrimaryRepository(String uri) { + this.addRepository(uri); + // now we are sure that a web resource for the uri exists + this.primaryRepository = uri; + // Update the reference to the primaryWebResource + // The appropriate resource has been created via + // this.addRepository(uri); + for (WebResource wr : this.repositoryResources) { + if (wr.getURI().equals(uri)) { + this.primaryWebResource = wr; + break; + } + } + assert (this.primaryWebResource != null); + } + + /*** methods directly from IWineryRepository ***/ + + /** + * {@inheritDoc} + */ + @Override + public SortedSet getNamespaces() { + SortedSet res = new TreeSet(); + for (WebResource wr : this.repositoryResources) { + WebResource namespacesResource = wr.path("admin").path("namespaces"); + + // this could be parsed using JAXB + // (http://jersey.java.net/nonav/documentation/latest/json.html), + // but we are short in time, so we do a quick hack + String nsList = namespacesResource.accept(MediaType.APPLICATION_JSON).get(String.class); + WineryRepositoryClient.logger.trace(nsList); + List nsListList; + try { + nsListList = this.mapper.readValue(nsList, new TypeReference>() { + }); + } catch (Exception e) { + WineryRepositoryClient.logger.error(e.getMessage(), e); + continue; + } + res.addAll(nsListList); + } + return res; + } + + /** + * Base method for getQNameListOfAllTypes and getAllTypes. + */ + private Map> getWRtoNamespaceAndIdListMapOfAllTypes(String path) { + Map> res = new HashMap>(); + for (WebResource wr : this.repositoryResources) { + WebResource componentListResource = wr.path(path); + + // this could be parsed using JAXB + // (http://jersey.java.net/nonav/documentation/latest/json.html), + // but we are short in time, so we do a quick hack + // The result also contains the optional name + String idList = componentListResource.accept(MediaType.APPLICATION_JSON).get(String.class); + WineryRepositoryClient.logger.trace(idList); + List nsAndIdList; + try { + nsAndIdList = this.mapper.readValue(idList, new TypeReference>() { + }); + } catch (Exception e) { + WineryRepositoryClient.logger.error(e.getMessage(), e); + continue; + } + res.put(wr, nsAndIdList); + } + return res; + } + + /** + * {@inheritDoc} + */ + @Override + public String getName(GenericId id) { + if (this.nameCache.containsKey(id)) { + return this.nameCache.get(id); + } + + String name = null; + for (WebResource wr : this.repositoryResources) { + String pathFragment = IdUtil.getURLPathFragment(id); + WebResource resource = wr.path(pathFragment).path("name"); + ClientResponse response = resource.accept(MediaType.TEXT_PLAIN_TYPE).get(ClientResponse.class); + if (response.getClientResponseStatus() == ClientResponse.Status.OK) { + name = response.getEntity(String.class); + // break loop as the first match is the final result + break; + } + } + // if all resources did not return "OK", "null" is returned + + if (name != null) { + if (this.nameCache.size() > WineryRepositoryClient.MAX_NAME_CACHE_SIZE) { + // if cache grew too large, clear it. + this.nameCache.clear(); + } + this.nameCache.put(id, name); + } + + return name; + } + + /** + * {@inheritDoc} + */ + @Override + public List getQNameListOfAllTypes(Class className) { + String path = Util.getURLpathFragmentForCollection(className); + Map> wRtoNamespaceAndIdListMapOfAllTypes = this.getWRtoNamespaceAndIdListMapOfAllTypes(path); + Collection> namespaceAndIdListCollection = wRtoNamespaceAndIdListMapOfAllTypes.values(); + List res = new ArrayList(namespaceAndIdListCollection.size()); + for (List namespaceAndIdList : namespaceAndIdListCollection) { + for (NamespaceIdOptionalName namespaceAndId : namespaceAndIdList) { + QName qname = new QName(namespaceAndId.getNamespace(), namespaceAndId.getId()); + res.add(qname); + } + } + return res; + } + + /** + * Fetches java objects at a given URL + * + * @param path the path to use. E.g., "nodetypes" for node types, ... + * @param className the class of the expected return type. May be + * TDefinitions or TEntityType. TDefinitions the mode is that the + * import statement are recursively resolved and added to the + * returned Defintitions elment + */ + // we convert an object to T if it T is definitions + // does not work without compiler error + @SuppressWarnings("unchecked") + private Collection getAllTypes(String path, Class className) { + Map> wRtoNamespaceAndIdListMapOfAllTypes = this.getWRtoNamespaceAndIdListMapOfAllTypes(path); + // now we now all QNames. We have to fetch the full content now + + Collection res = new LinkedList(); + for (WebResource wr : wRtoNamespaceAndIdListMapOfAllTypes.keySet()) { + WebResource componentListResource = wr.path(path); + + // go through all ids and fetch detailed information on each + // type + + for (NamespaceIdOptionalName nsAndId : wRtoNamespaceAndIdListMapOfAllTypes.get(wr)) { + TDefinitions definitions = WineryRepositoryClient.getDefinitions(componentListResource, nsAndId.getNamespace(), nsAndId.getId()); + if (definitions == null) { + // try next one + continue; + } + + T result; + + if (TDefinitions.class.equals(className)) { + // mode: complete definitions + result = (T) definitions; + } else { + // mode: only the nested element + // convention: first element in list is the element we look for + if (definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().isEmpty()) { + result = null; + WineryRepositoryClient.logger.error("Type {}/{} was found, but did not return any data", nsAndId.getNamespace(), nsAndId.getId()); + } else { + WineryRepositoryClient.logger.trace("Probably found valid data for {}/{}", nsAndId.getNamespace(), nsAndId.getId()); + result = (T) definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().get(0); + + this.cache((TEntityType) result, new QName(nsAndId.getNamespace(), nsAndId.getId())); + } + } + + // TODO: if multiple repositories are used, the new element + // should be put "sorted" into the list. This could be done by + // add(parsedResult, index), where index is calculated by + // incrementing index as long as the current element is smaller + // than the element to insert. + if (result != null) { + res.add(result); + } + } + } + return res; + } + + /** + * Caches the TEntityType data of a QName to avoid multiple get requests + * + * NOT thread safe + */ + private void cache(TEntityType et, QName qName) { + Map map; + if ((map = this.entityTypeDataCache.get(et.getClass())) == null) { + map = new HashMap<>(); + this.entityTypeDataCache.put(et.getClass(), map); + } else { + // quick hack to keep cache size small + if (map.size() > 1000) { + map.clear(); + } + } + map.put(qName, et); + } + + private static WebResource getTopologyTemplateWebResource(WebResource base, QName serviceTemplate) { + String nsEncoded = Util.DoubleURLencode(serviceTemplate.getNamespaceURI()); + String idEncoded = Util.DoubleURLencode(serviceTemplate.getLocalPart()); + WebResource res = base.path("servicetemplates").path(nsEncoded).path(idEncoded).path("topologytemplate"); + return res; + } + + /** + * {@inheritDoc} + */ + @Override + public Collection getListOfAllInstances(Class clazz) { + // inspired by getQNameListOfAllTypes + String path = Util.getRootPathFragment(clazz); + Map> wRtoNamespaceAndIdListMapOfAllTypes = this.getWRtoNamespaceAndIdListMapOfAllTypes(path); + Collection> namespaceAndIdListCollection = wRtoNamespaceAndIdListMapOfAllTypes.values(); + List res = new ArrayList(namespaceAndIdListCollection.size()); + + for (List namespaceAndIdList : namespaceAndIdListCollection) { + for (NamespaceIdOptionalName namespaceAndId : namespaceAndIdList) { + QNameWithName qn = new QNameWithName(); + qn.qname = new QName(namespaceAndId.getNamespace(), namespaceAndId.getId()); + qn.name = namespaceAndId.getName(); + res.add(qn); + } + } + return res; + } + + /** + * {@inheritDoc} + */ + @Override + public Collection getAllTypes(Class c) { + String urlPathFragment = Util.getURLpathFragmentForCollection(c); + Collection allTypes = this.getAllTypes(urlPathFragment, c); + return allTypes; + } + + @Override + @SuppressWarnings("unchecked") + public T getType(QName qname, Class type) { + T res = null; + if (this.entityTypeDataCache.containsKey(type)) { + Map map = this.entityTypeDataCache.get(type); + if (map.containsKey(qname)) { + res = (T) map.get(qname); + } + } + + if (res == null) { + // not yet seen, try to fetch resource + + for (WebResource wr : this.repositoryResources) { + String path = Util.getURLpathFragmentForCollection(type); + + TDefinitions definitions = WineryRepositoryClient.getDefinitions(wr, path, qname.getNamespaceURI(), qname.getLocalPart()); + + if (definitions == null) { + // in case of an error, just try the next one + continue; + } + + res = (T) definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().get(0); + this.cache(res, qname); + break; + } + } + + return res; + } + + /** + * Tries to retrieve a TDefinitions from the given resource / encoded(ns) / + * encoded(localPart) + * + * @return null if 404 or other error + */ + private static TDefinitions getDefinitions(WebResource wr, String path, String ns, String localPart) { + WebResource componentListResource = wr.path(path); + return WineryRepositoryClient.getDefinitions(componentListResource, ns, localPart); + } + + /** + * Tries to retrieve a TDefinitions from the given resource / encoded(ns) / + * encoded(localPart) + * + * @return null if 404 or other error + */ + private static TDefinitions getDefinitions(WebResource componentListResource, String ns, String localPart) { + // we need double encoding as the client decodes the URL once + String nsEncoded = Util.DoubleURLencode(ns); + String idEncoded = Util.DoubleURLencode(localPart); + + WebResource instanceResource = componentListResource.path(nsEncoded).path(idEncoded); + + // TODO: org.eclipse.winery.repository.resources.AbstractComponentInstanceResource.getDefinitionsWithAssociatedThings() could be used to do the resolving at the server + + ClientResponse response = instanceResource.accept(MimeTypes.MIMETYPE_TOSCA_DEFINITIONS).get(ClientResponse.class); + if (response.getStatus() != 200) { + // also handles 404 + return null; + } + + TDefinitions definitions; + try { + Unmarshaller um = WineryRepositoryClient.createUnmarshaller(); + definitions = (TDefinitions) um.unmarshal(response.getEntityInputStream()); + } catch (JAXBException e) { + WineryRepositoryClient.logger.error("Could not umarshal TDefinitions", e); + // try next service + return null; + } + return definitions; + } + + /** + * {@inheritDoc} + */ + @Override + public Collection getAllTypesWithAssociatedElements(Class c) { + String urlPathFragment = Util.getURLpathFragmentForCollection(c); + Collection allTypes = this.getAllTypes(urlPathFragment, TDefinitions.class); + return allTypes; + } + + /** + * + * @param stream the stream to parse + * @return null if document is invalid + */ + private Document parseAndValidateTOSCAXML(InputStream stream) { + Document document; + try { + document = this.toscaDocumentBuilder.parse(stream); + } catch (SAXException | IOException e) { + WineryRepositoryClient.logger.debug("Could not parse TOSCA file", e); + return null; + } + return document; + } + + /** + * {@inheritDoc} + */ + @Override + public TTopologyTemplate getTopologyTemplate(QName serviceTemplate) { + // we try all repositories until the first hit + for (WebResource wr : this.repositoryResources) { + WebResource r = WineryRepositoryClient.getTopologyTemplateWebResource(wr, serviceTemplate); + ClientResponse response = r.accept(MediaType.TEXT_XML).get(ClientResponse.class); + if (response.getClientResponseStatus() == ClientResponse.Status.OK) { + TTopologyTemplate topologyTemplate; + Document doc = this.parseAndValidateTOSCAXML(response.getEntityInputStream()); + if (doc == null) { + // no valid document + return null; + } + try { + topologyTemplate = WineryRepositoryClient.createUnmarshaller().unmarshal(doc.getDocumentElement(), TTopologyTemplate.class).getValue(); + } catch (JAXBException e) { + WineryRepositoryClient.logger.debug("Could not parse topology, returning null", e); + return null; + } + // first hit: immediately stop and return result + return topologyTemplate; + } + } + // nothing found + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public void setTopologyTemplate(QName serviceTemplate, TTopologyTemplate topologyTemplate) throws Exception { + WebResource r = WineryRepositoryClient.getTopologyTemplateWebResource(this.primaryWebResource, serviceTemplate); + String xmlAsString = Util.getXMLAsString(TTopologyTemplate.class, topologyTemplate); + ClientResponse response = r.type(MediaType.TEXT_XML).put(ClientResponse.class, xmlAsString); + WineryRepositoryClient.logger.debug(response.toString()); + int status = response.getStatus(); + if ((status < 200) || (status >= 300)) { + throw new Exception(response.toString()); + } + } + + /** + * {@inheritDoc} + */ + @Override + public QName getArtifactTypeQNameForExtension(String extension) { + // we try all repositories until the first hit + for (WebResource wr : this.repositoryResources) { + WebResource artifactTypesResource = wr.path("artifacttypes").queryParam("extension", extension); + ClientResponse response = artifactTypesResource.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class); + if (response.getClientResponseStatus() == ClientResponse.Status.OK) { + QName res = QName.valueOf(response.getEntity(String.class)); + return res; + } + } + return null; + } + + /** + * {@inheritDoc} + * + * Does NOT check for global QName uniqueness, only in the scope of all + * artifact templates + */ + @Override + public void createArtifactTemplate(QName qname, QName artifactType) throws QNameAlreadyExistsException { + WebResource artifactTemplates = this.primaryWebResource.path("artifacttemplates"); + MultivaluedMap map = new MultivaluedMapImpl(); + map.putSingle("namespace", qname.getNamespaceURI()); + map.putSingle("name", qname.getLocalPart()); + map.putSingle("type", artifactType.toString()); + ClientResponse response = artifactTemplates.type(MediaType.APPLICATION_FORM_URLENCODED).accept(MediaType.TEXT_PLAIN).post(ClientResponse.class, map); + if (response.getClientResponseStatus() != ClientResponse.Status.CREATED) { + // TODO: pass ClientResponse.Status somehow + // TODO: more fine grained checking for error message. Not all + // failures are that the QName already exists + WineryRepositoryClient.logger.debug(String.format("Error %d when creating id %s from URI %s", response.getStatus(), qname.toString(), this.primaryWebResource.getURI().toString())); + throw new QNameAlreadyExistsException(); + } + // no further return is made + } + + /** + * {@inheritDoc} + */ + @Override + public void createComponent(QName qname, Class idClass) throws QNameAlreadyExistsException { + WebResource resource = this.primaryWebResource.path(Util.getRootPathFragment(idClass)); + MultivaluedMap map = new MultivaluedMapImpl(); + map.putSingle("namespace", qname.getNamespaceURI()); + map.putSingle("name", qname.getLocalPart()); + ClientResponse response = resource.type(MediaType.APPLICATION_FORM_URLENCODED).accept(MediaType.TEXT_PLAIN).post(ClientResponse.class, map); + if (response.getClientResponseStatus() != ClientResponse.Status.CREATED) { + // TODO: pass ClientResponse.Status somehow + // TODO: more fine grained checking for error message. Not all failures are that the QName already exists + WineryRepositoryClient.logger.debug(String.format("Error %d when creating id %s from URI %s", response.getStatus(), qname.toString(), this.primaryWebResource.getURI().toString())); + throw new QNameAlreadyExistsException(); + } + // no further return is made + } + + @Override + public void forceDelete(GenericId id) throws IOException { + String pathFragment = IdUtil.getURLPathFragment(id); + for (WebResource wr : this.repositoryResources) { + ClientResponse response = wr.path(pathFragment).delete(ClientResponse.class); + if ((response.getClientResponseStatus() != ClientResponse.Status.NO_CONTENT) || (response.getClientResponseStatus() != ClientResponse.Status.NOT_FOUND)) { + WineryRepositoryClient.logger.debug(String.format("Error %d when deleting id %s from URI %s", response.getStatus(), id.toString(), wr.getURI().toString())); + } + } + } + + @Override + public boolean primaryRepositoryAvailable() { + if (this.primaryWebResource == null) { + return false; + } + + ClientResponse response = this.primaryWebResource.get(ClientResponse.class); + boolean res = (response.getClientResponseStatus() == ClientResponse.Status.OK); + return res; + } + +} diff --git a/org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/WineryRepositoryClientFactory.java b/org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/WineryRepositoryClientFactory.java new file mode 100644 index 0000000000..59f01663c3 --- /dev/null +++ b/org.eclipse.winery.repository.client/src/main/java/org/eclipse/winery/repository/client/WineryRepositoryClientFactory.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.client; + +public class WineryRepositoryClientFactory { + + public static IWineryRepositoryClient getWineryRepositoryClient() { + return new WineryRepositoryClient(); + } + +} diff --git a/org.eclipse.winery.repository.client/src/test/java/META-INF/MANIFEST.MF b/org.eclipse.winery.repository.client/src/test/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/org.eclipse.winery.repository.client/src/test/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/org.eclipse.winery.repository.client/src/test/java/org/eclipse/winery/repository/client/TestWineryRepositoryClient.java b/org.eclipse.winery.repository.client/src/test/java/org/eclipse/winery/repository/client/TestWineryRepositoryClient.java new file mode 100644 index 0000000000..77ab588714 --- /dev/null +++ b/org.eclipse.winery.repository.client/src/test/java/org/eclipse/winery/repository/client/TestWineryRepositoryClient.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.client; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.eclipse.winery.model.tosca.TDefinitions; +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.model.tosca.TNodeType; +import org.eclipse.winery.model.tosca.TRelationshipType; +import org.eclipse.winery.model.tosca.TTopologyTemplate; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.interfaces.QNameAlreadyExistsException; + +/** + * Tests client methods with a pre-configured client stored in a local static + * field. + * + * Client creation and multiple repositories are not tested. This should be + * subject to other test classes. + * + * TODO: This class expects things to be existent in the namespace "test". This + * should be enforced in a preload. + */ +@RunWith(JUnit4.class) +public class TestWineryRepositoryClient { + + // private final String repositoryURI = "http://2471.de:8080/wineydev"; + private static final String repositoryURI = "http://localhost:8080/winery"; + + private static final boolean USE_PROXY = true; + + private static final IWineryRepositoryClient client = new WineryRepositoryClient(TestWineryRepositoryClient.USE_PROXY); + static { + TestWineryRepositoryClient.client.addRepository(TestWineryRepositoryClient.repositoryURI); + } + + /** + * The namespace to put new things in.
+ * TODO: Is deleted completely after testing + */ + private static final String namespaceForNewArtifacts = "http://www.example.org/test/wineryclient/"; + + + @Test + public void getAllNodeTypes() { + Collection allTypes = TestWineryRepositoryClient.client.getAllTypes(TNodeType.class); + for (TNodeType type : allTypes) { + Assert.assertNotNull("name is null", type.getName()); + Assert.assertNotNull("target namespace is null", type.getTargetNamespace()); + } + } + + @Test + public void getAllRelationshipTypes() { + Collection allTypes = TestWineryRepositoryClient.client.getAllTypes(TRelationshipType.class); + for (TRelationshipType type : allTypes) { + Assert.assertNotNull("name is null", type.getName()); + Assert.assertNotNull("target namespace is null", type.getTargetNamespace()); + } + } + + @Test + public void getAllNodeTypesWithAssociatedElements() { + Collection allTypes = TestWineryRepositoryClient.client.getAllTypesWithAssociatedElements(TNodeType.class); + Assert.assertNotNull(allTypes); + } + + @Test + public void getAllRelationshipTypesWithAssociatedElements() { + Collection allTypes = TestWineryRepositoryClient.client.getAllTypesWithAssociatedElements(TRelationshipType.class); + Assert.assertNotNull(allTypes); + } + + @Test + public void getPropertiesOfAllNodeTypes() { + // TODO + } + + @Test + public void getPropertiesOfAllRelationshipTypes() { + // TODO + } + + @Test + public void getTestTopologyTemplate() { + QName serviceTemplate = new QName("test", "test"); + TTopologyTemplate topologyTemplate = TestWineryRepositoryClient.client.getTopologyTemplate(serviceTemplate); + Assert.assertNotNull(topologyTemplate); + } + + @Test + public void getPropertiesOfTestTopologyTemplate() { + QName serviceTemplate = new QName("test", "test"); + TTopologyTemplate topologyTemplate = TestWineryRepositoryClient.client.getTopologyTemplate(serviceTemplate); + Assert.assertNotNull(topologyTemplate); + List allTemplates = topologyTemplate.getNodeTemplateOrRelationshipTemplate(); + for (TEntityTemplate e : allTemplates) { + // TODO + } + } + + @Test + public void artifactTypeForWARfiles() { + QName artifactType = TestWineryRepositoryClient.client.getArtifactTypeQNameForExtension("war"); + Assert.assertNotNull("Artifact Type for .war does not exist", artifactType); + } + + @Test + public void createArtifactTemplate() throws IOException, QNameAlreadyExistsException { + // assure that the artifact type exists + QName artifactTypeQName = TestWineryRepositoryClient.client.getArtifactTypeQNameForExtension("war"); + Assert.assertNotNull("Artifact Type for .war does not exist", artifactTypeQName); + + // assure that the artifact template does not yet exist + // one possibility is to delete the artifact template, the other + // possibility is to + + QName artifactTemplateQName = new QName(TestWineryRepositoryClient.namespaceForNewArtifacts, "artifactTemplate"); + ArtifactTemplateId atId = new ArtifactTemplateId(artifactTemplateQName); + + // ensure that the template does not exist yet + TestWineryRepositoryClient.client.forceDelete(atId); + + TestWineryRepositoryClient.client.createArtifactTemplate(artifactTemplateQName, artifactTypeQName); + } +} diff --git a/org.eclipse.winery.repository/.bowerrc b/org.eclipse.winery.repository/.bowerrc new file mode 100644 index 0000000000..eb92b22ed1 --- /dev/null +++ b/org.eclipse.winery.repository/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory" : "src/main/webapp/components" +} \ No newline at end of file diff --git a/org.eclipse.winery.repository/.gitattributes b/org.eclipse.winery.repository/.gitattributes new file mode 100644 index 0000000000..3c3f5dfaa7 --- /dev/null +++ b/org.eclipse.winery.repository/.gitattributes @@ -0,0 +1,6 @@ +.gitattributes -crlf +.gitmodules -crlf +*.pdf binary +*.vsd binary +*.ppt* binary +bower.json eol=lf diff --git a/org.eclipse.winery.repository/.gitignore b/org.eclipse.winery.repository/.gitignore new file mode 100644 index 0000000000..9d4d64c5f5 --- /dev/null +++ b/org.eclipse.winery.repository/.gitignore @@ -0,0 +1,23 @@ +.classpath +/.gradle +.project +.settings/.jsdtscope +.settings/org.eclipse.core.resources.prefs +.settings/org.eclipse.jdt.core.prefs +.settings/org.eclipse.m2e.core.prefs +.settings/org.eclipse.wst.common.component +.settings/org.eclipse.wst.common.project.facet.core.xml +.settings/org.eclipse.wst.common.project.facet.core.prefs.xml +.settings/org.eclipse.wst.jsdt.ui.superType.container +.settings/org.eclipse.wst.jsdt.ui.superType.name +.settings/org.eclipse.wst.validation.prefs +/.sonar +/bin +/build +/conf/valesca.properties +sonar-project.properties +/src/main/resources/rebel.xml +/src/main/webapp/components +/src/main/webapp/valesca.properties +/src/main/webapp/META-INF/MANIFEST.MF +/target diff --git a/org.eclipse.winery.repository/.settings/de.loskutov.anyedit.AnyEditTools.prefs b/org.eclipse.winery.repository/.settings/de.loskutov.anyedit.AnyEditTools.prefs new file mode 100644 index 0000000000..a8ddcc62b8 --- /dev/null +++ b/org.eclipse.winery.repository/.settings/de.loskutov.anyedit.AnyEditTools.prefs @@ -0,0 +1,16 @@ +activeContentFilterList=*.makefile,makefile,*.Makefile,Makefile,Makefile.*,*.mk,MANIFEST.MF,*.java +addNewLine=true +convertActionOnSaave=AnyEdit.CnvrtSpacesToTabs +eclipse.preferences.version=1 +ignoreBlankLinesWhenTrimming=false +inActiveContentFilterList= +javaTabWidthForJava=true +org.eclipse.jdt.ui.editor.tab.width=4 +projectPropsEnabled=false +removeTrailingSpaces=true +replaceAllSpaces=false +replaceAllTabs=false +saveAndAddLine=true +saveAndConvert=true +saveAndTrim=true +useModulo4Tabs=true diff --git a/org.eclipse.winery.repository/README.md b/org.eclipse.winery.repository/README.md new file mode 100644 index 0000000000..b8c0088e4a --- /dev/null +++ b/org.eclipse.winery.repository/README.md @@ -0,0 +1,59 @@ +# Winery Repository + +Setup, usage, and implementation hints are given in the [global README.md](../README.md) + +## REST API +Winery offers a REST API to communicate with the backend. +When issuing an `OPTIONS` request to `winery/`, a [RestDoc] description of the possible interactions is presented. +The returned JSON can be views in a browsable html format using [restdoc-renderer]. +If you install restdoc-renderer as `restdoc.html` in the `ROOT` of the tomcat, Winery automatically displays a link to the renderer in the about dialog. + +## About the code +The code tries to make use of EL and JSP tags wherever possible. All data is accessible via a REST API. +The REST API does **not** follow the HATEOAS approach. +The URLs follow the pattern `///`, where `type` is `servicetemplate`, `nodetype`, ... +Below a concrete instanance, subresources such as `name` exist. + +Definitions are not modeled as explicit element. Only the nested elements are handled by Winery. +That means, it is not possible to specify custom definitions bundling a customized subset of available elements. + +Intentionally, a QName should be unique within the repository. +We did not follow this assumption, but only require that QNames are unique within a type. +That means, the repository allows `{http://www.example.org}id` for both a service template and a node type. +We introduced TOSCAcomponentId uniquely identifying a TOSCA element. +Future versions might redesign the backend to use a QName as the unique key. + +Currently, Winery is switching from plain Javascript library loading to [RequireJS]. + +The file `src/main/webapp/WEB-INF/common-functions.tld` and the files in `src/main/webapp/WEB-INF/tags/common` are copied from the sister project `org.eclipse.winery.topologymodler` at `mvn generate-sources`. + +### Trouble shooting +In case, `Version.java` is not found, then run `mvn compile`, which should trigger a regeneration of Version.java. + +In case `javax.servlet.jsp.PageContext` cannot be found: +Project -> right click -> Properties -> Project Facets -> Dynamic Web Module -> "Runtimes" -> "New..." + +When running in jetty 9.0.5, there is always the error message "Request Entity Too Large" when uploading a file. +There is the `maxFormContentSize` set in `jetty-web.xml`, but it currently does not help to solve this issue. + +When doing a copy-libs-to-tomcat hack, possibly "W3C_XML_SCHEMA_NS_URI cannot be resolved or is not a field" appears. +Remove `stax-api-1.0.1.jar` out of `tomcat7/lib`: Java's `rt.jar` should be used instead for `javax.xml.XMLConstants`. + +## License +Copyright (c) 2012-2014 University of Stuttgart. + +All rights reserved. This program and the accompanying materials +are made available under the terms of the [Eclipse Public License v1.0] +and the [Apache License v2.0] which both accompany this distribution, +and are available at http://www.eclipse.org/legal/epl-v10.html +and http://www.apache.org/licenses/LICENSE-2.0 + +Contributors: +* Oliver Kopp - initial API and implementation + + + [Apache License v2.0]: http://www.apache.org/licenses/LICENSE-2.0.html + [Eclipse Public License v1.0]: http://www.eclipse.org/legal/epl-v10.html + [RequireJS]: http://requirejs.org/ + [RestDoc]: http://www.restdoc.org + [restdoc-renderer]: https://github.com/hoegertn/restdoc-renderer diff --git a/org.eclipse.winery.repository/about.html b/org.eclipse.winery.repository/about.html new file mode 100644 index 0000000000..7cffd4d788 --- /dev/null +++ b/org.eclipse.winery.repository/about.html @@ -0,0 +1,1037 @@ + + + + +About + + +

About This Content

+ +

January 24, 2014

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in (“Content”). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 (“EPL”) +and Apache License Version 2.0. +A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html +and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php. +You may elect to redistribute this code under either of these licenses. +For purposes of the EPL, “Program” will mean the Content. +

+ +

+If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party (“Redistributor”) and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor’s license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL and Apache License 2.0 still apply to any source code +in the Content and such source code may be obtained at http://www.eclipse.org. +

+ +

Third Party Content

+ +

The Content includes items that have been sourced from third parties as set out below. If you +did not receive this Content directly from the Eclipse Foundation, the following is provided +for informational purposes only, and you should look to the Redistributor's license for +terms and conditions of use.

+ +

JavaScript libraries

+ +
biltong – Version 0.1
+ + + + + + + + + + + + + +
FilesThe library is completly included in jsPlumb as “jsPlumbGeom v0.1
URLhttps://github.com/jsplumb/biltong
LicenseMIT. A copy of the license is contained in the file LICENSE-bitlong.txt and is also available at github
+ +
Bootstrap – Version 3.1.1
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/bootstrap
URLhttp://getbootstrap.com/
LicenseMIT. A copy of the license is contained in the file LICENSE-bootstrap.txt and is also available at github
+ +
bootstrap-spinedit – Version 1.0.0
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/bootstrap-spinedit
URLhttps://github.com/scyv/bootstrap-spinedit
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at github
+ +
bootstrap-switch – Version 1.9.0
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/bootstrap-switch
URLhttp://www.bootstrap-switch.org/
LicenseApache 2.0. A copy of the license is contained in the file LICENSE-bootstrap-switch.txt and is also available at github
+ +
bootstrap3-wysihtml5-bower – Version 0.2.8
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/bootstrap3-wysihtml5-bower
URLhttps://github.com/Waxolunist/bootstrap3-wysihtml5-bower
LicenseMIT. A copy of the license is contained in the file LICENSE-bootstrap3-wysihtml5-bower.txt and is also available at github
+ +
DataTables – Version 1.9.4
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/datatables
URLhttp://datatables.net/
LicenseDataTables is dual licensed under the GPL v2 license (http://datatables.net/license_gpl2)or a BSD (3 clauses) license (http://datatables.net/license_bsd). + The Eclipse Foundation elects to include this software in this distribution under the BSD license. + A copy of the license is contained in the file LICENSE-datatables.txt.
+ +
Handlebars – Version 1.3.0
+ + + + + + + + + + + + + +
Pathsrc/main/webapp/components/handlebars/
URLhttp://handlebarsjs.com/
LicenseMIT. A copy of the license is contained in the file LICENSE-handlebars and is also available at github
+ +
JavaScript Canvas to Blob – Version 2.1.0
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/blueimp-canvas-to-blob
URLhttps://github.com/blueimp/JavaScript-Canvas-to-Blob
LicenseMIT. The authors did not provide a separate variant of the MIT license. The generic MIT license is available at http://opensource.org/licenses/MIT
+ +
JavaScript Load Image – Version 1.11.0
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/blueimp-load-image
URLhttps://github.com/blueimp/JavaScript-Load-Image
LicenseMIT. The authors did not provide a separate variant of the MIT license. The generic MIT license is available at http://opensource.org/licenses/MIT
+ +
JavaScript Templates – Version 2.5.3
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/blueimp-tmpl
URLhttps://github.com/blueimp/JavaScript-Templates
LicenseMIT. The authors did not provide a separate variant of the MIT license. The generic MIT license is available at http://opensource.org/licenses/MIT
+ +
jQuery – Version 2.0.3
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/jquery
URLhttp://jquery.com/
LicenseMIT. A copy of the license is contained in the file LICENSE-jQuery.txt and is also available at https://jquery.org/license/
+ +
jQuery Typing – v0.3.2-2
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/jquery-typing
URLhttps://github.com/tnajdek/jquery-typing
LicensePublic domain. An explicit license is not provided, only a link to unlicense.org is provided.
+ +
jQuery File Upload Plugin – Version 9.5.3
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/blueimp-file-upload
URLhttps://github.com/blueimp/jQuery-File-Upload
LicenseMIT. The authors did not provide a separate variant of the MIT license. The generic MIT license is available at http://opensource.org/licenses/MIT
+ +
jQuery UI – Version 1.10.3
+This library is required by jsPlumb only + + + + + + + + + + + + + +
Filessrc/main/webapp/components/jquery-ui
URLhttp://jqueryui.com/
LicenseMIT. A copy of the license is contained in the file LICENSE-jQuery-UI.txt and is also available at https://github.com/jquery/jquery-ui/blob/master/MIT-LICENSE.txt
+ +
jsBezier – Version 0.6
+ + + + + + + + + + + + + +
FilesThe library is completly included in jsPlumb
URLhttps://github.com/jsplumb/jsBezier
LicenseMIT. An explicit license is not provided, only an entry in the header of jsBezier-0.6.js.
+ + +
jsPlumb – Version 1.5.4
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/jsPlumb
URLhttp://jsplumb.org/
LicenseAll 1.x.x versions of jsPlumb are dual-licensed under both MIT and GPLv2 (http://www.gnu.org/licenses/old-licenses/gpl-2.0). + The Eclipse Foundation elects to include this software in this distribution under the MIT license. + A copy of the license is contained in the file LICENSE-jsPlumb-MIT and is also available at github
+ +
KeyboardJS – Version 0.4.2
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/KeyboardJS
URLhttps://github.com/RobertWHurst/KeyboardJS/tree/v0.4.2
LicenseBSD (2 clauses). A copy of the license is contained in the file LICENSE-KeyboardJS.txt and is also available at https://github.com/RobertWHurst/KeyboardJS/blob/v0.4.2/license.txt
+ +
Orion – Version 4.0
+ + + + + + + + + + + + + +
URLhttp://eclipse.org/orion/editor/releases/latest/built-editor.js
URLhttp://www.eclipse.org/orion/
LicenseEclipse Public License v1.0 and Eclipse Distribution License v1.0. + A copy of the licenses is contained in the files LICENSE-EPL.txt and EDL.txt. + A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the EDL is available at http://www.eclipse.org/org/documents/edl-v10.html.
+ + +
PNotify – Version 1.2.2-koppor-2
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/pnotify
URLhttp://sciactive.com/pnotify/ and https://github.com/koppor/pnotify
LicensePines Notify is distributed under the GPL (http://www.gnu.org/licenses/gpl.html), + LGPL (http://www.gnu.org/licenses/lgpl.html), and + MPL (http://www.mozilla.org/MPL/MPL-1.1.html). + The Eclipse Foundation elects to include this software in this distribution under the MPL license. + A copy of the license is contained in the file MPL-v1.1.txt.
+ +
Really Simple Color Picker – Version 1.0.2
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/colorPicker
URLhttps://github.com/laktek/really-simple-color-picker
LicenseMIT. A copy of the license is contained in the file LICENSE-colorPicker.txt and is also available at github
+ +
RequireJS – Version 2.1.5
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/requirejs
URLhttp://requirejs.org/
LicenseBSD and MIT (see https://github.com/jrburke/requirejs/blob/master/LICENSE). + The Eclipse Foundation elects to include this software in this distribution under the MIT license. + A copy of the license is contained in the file LICENSE-requirejs.txt.
+ +
Select2 – Version 3.4.5
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/select2
URLhttp://ivaynberg.github.io/select2/
LicenseApache 2.0 (http://www.apache.org/licenses/LICENSE-2.0) and GPL2 (http://www.gnu.org/licenses/gpl-2.0.html). + The Eclipse Foundation elects to include this software in this distribution under the Apache 2.0 license. + A copy of the license is contained in the file Apache-LICENSE-2.0.txt.
+ +
URI.js – Version 3.4.5
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/uri.js
URLhttp://medialize.github.io/URI.js/
LicenseMIT (http://www.opensource.org/licenses/mit-license) and GPL3 (http://www.gnu.org/licenses/gpl-3.0.html). + The Eclipse Foundation elects to include this software in this distribution under the MIT license.
+ +
wysihtml5 – Version 0.3.0
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/wysihtml5
URLhttps://github.com/xing/wysihtml5
LicenseMIT. A copy of the license is contained in the file LICENSE-wysihtml5.txt and is also available at github
+ +
X-editable – Version 1.5.1
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/x-editable
URLhttp://vitalets.github.io/x-editable/
LicenseMIT. A copy of the license is contained in the file LICENSE-x-editable.txt and is also available at github
+ +
XMLTree – Version 3.1.2
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/xmltree
URLhttp://koppor.github.com/xmltree
LicenseMIT. A copy of the license is contained in the file LICENSE-xmltree.txt and is also available at github
+ +
XMLWriter – Version v1.0.2
+ + + + + + + + + + + + + +
Filessrc/main/webapp/components/XMLWriter
URLhttps://github.com/flesler/XMLWriter
LicenseBSD. A copy of the license is contained in the file LICENSE-XMLWriter.txt and is also available at github
+ +

Java Libraries

+ +
Apache Commons Compress – Version 1.6
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-compress/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Apache Commons Configuration – Version 1.9
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-configuration/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Apache Commons HTTP Client – Version 3.1
+ + + + + + + + + + + + + +
URLhttp://hc.apache.org/httpclient-3.x/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
NoteOnly org.apache.http.impl.cookie.DateUtils is included. It was stripped down to fit the requirements of winery
+ +
Apache Commons IO – Version 2.1
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-io/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Apache Commons Lang – Version 2.6
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-lang/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Apache Commons Lang3 – Version 3.1
+ + + + + + + + + +
URLhttp://commons.apache.org/proper/commons-lang/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Apache Tika – Version 1.3
+ + + + + + + + + +
URLhttp://tika.apache.org/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Apache Xerces – Version 2.9.1
+ + + + + + + + + +
URLhttp://xerces.apache.org/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
ASM – Version 3.1
+ + + + + + + + + +
URLhttp://asm.ow2.org/
LicenseBSD (3 clauses). A copy of the license is contained in the file LICENSE-ASM.txt and is also available at http://asm.ow2.org/license.html
+ +
Guava – Version 15.0
+ + + + + + + + + +
URLhttp://code.google.com/p/guava-libraries/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
jackson-annotations – Version 2.2.2
+ + + + + + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-annotations
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
NoteThe license was explictily added in version 2.2.3 and 2.3.0. See Issue #14 and LICENSE in the source repository.
+ +
jackson-core – Version 2.2.2
+ + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-core and http://wiki.fasterxml.com/JacksonHome
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
jackson-databind – Version 2.2.2
+ + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-databind
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
jackson-jaxrs-base – Version 2.2.2
+ + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-jaxrs-providers/tree/master/base
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
jackson-jaxrs-json-provider – Version 2.2.2
+ + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-jaxrs-providers/tree/master/json
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
jackson-module-jaxb-annotations – Version 2.3.0
+ + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-module-jaxb-annotations
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0. + The license is added via the oss-parent project.
+ +
jackson-module-jsonSchema – Version 2.3.0
+ + + + + + + + + +
URLhttps://github.com/FasterXML/jackson-module-jsonSchema
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
JavaEWAH – Version 0.5.6
+ + + + + + + + + +
URLhttps://code.google.com/p/javaewah/
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
Java Manifest Parser – Version 2.0.5
+ + + + + + + + + +
URLhttp://ebr.springsource.com/repository/app/bundle/version/detail?name=com.springsource.util.parser.manifest&version=2.0.5.RELEASE
LicenseApache 2.0. The sources do not contain a license file, but each .java file contains an Apache 2.0 license header. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
JAXB Standard Implementation – Version 2.2.5
+ + + + + + + + + +
URLhttps://java.net/projects/jaxb/
LicenseCDDL and GPL with classpath exception (https://java.net/projects/jaxb/sources/version2/content/tags/jaxb-2_2_5/License.txt?rev=4179). + The Eclipse Foundation elects to include this software in this distribution under the CDDL license. + A copy of the license is available at CDDL-v1.1.txt.
+ + +
Jersey Core – Version 1.17
+ + + + + + + + + +
URLjersey.java.net/
LicenseCDDL and GPL with classpath exception (https://jersey.java.net/license.html). + The Eclipse Foundation elects to include this software in this distribution under the CDDL license. + A copy of the license is available at CDDL-v1.1.txt.
+ +
Jersey Contribs: Jersey-Multipart – Version 1.17
+ + + + + + + + + +
URLjersey.java.net/
LicenseCDDL and GPL with classpath exception (https://jersey.java.net/license.html). + The Eclipse Foundation elects to include this software in this distribution under the CDDL license. + A copy of the license is available at CDDL-v1.1.txt.
+ +
JGit – Version 3.0.0.201306101825-r
+ + + + + + + + + +
URLhttp://www.eclipse.org/jgit/
LicenseEclipse Distribution Licencse - v 1.0. A copy of the license is contained in the file EDL.txt and is also available at http://www.eclipse.org/org/documents/edl-v10.php
+ +
JSch – Version 0.1.46
+ + + + + + + + + +
URLhttp://www.jcraft.com/jsch/
LicenseBSD (3 clause). A copy of the license is contained in the file LICENSE-JSch.txt and is also available at http://www.jcraft.com/jsch/LICENSE.txt
+ +
JSP Standard Tag Library – Version 1.2
+ + + + + + + + + +
URLhttps://jstl.java.net/
LicenseCDDL and GPL with classpath exception (https://jersey.java.net/license.html). + The Eclipse Foundation elects to include this software in this distribution under the CDDL license. + A copy of the license is available at CDDL-v1.1.txt.
+ +
Logback Classic – Version 1.1.1
+ + + + + + + + + +
URLhttp://logback.qos.ch/
LicenseEPL/LGPL dual license. + EPL: http://www.eclipse.org/legal/epl-v10.html. + LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1. + A copy of the license is contained in the file LICENSE-logback.txt and is also available at http://logback.qos.ch/license.html. + The Eclipse Foundation elects to include this software in this distribution under the EPL license.
+ +
Logback Core – Version 1.1.1
+ + + + + + + + + +
URLhttp://logback.qos.ch/
LicenseEPL/LGPL dual license. + EPL: http://www.eclipse.org/legal/epl-v10.html. + LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1. + A copy of the license is contained in the file LICENSE-logback.txt and is also available at http://logback.qos.ch/license.html. + The Eclipse Foundation elects to include this software in this distribution under the EPL license.
+ +
Mimepull – Version 1.9.4
+ + + + + + + + + +
URLhttps://mimepull.java.net/
LicenseCDDL and GPL with classpath exception (https://jersey.java.net/license.html). + The Eclipse Foundation elects to include this software in this distribution under the CDDL license. + A copy of the license is available at CDDL-v1.1.txt.
+ +
RestDoc API – Version 1.3.0
+ + + + + + + + + +
URLhttps://github.com/RestDoc/restdoc-api
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
RestDoc Jersey Server Jersey – Version 1.0.1
+ + + + + + + + + +
URLhttps://github.com/koppor/restdoc-server-jersey
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
RestDoc Java Server (JAX-RS 1.1) – Version 1.7.1
+ + + + + + + + + +
URLhttps://github.com/hoegertn/restdoc-java-server/tree/jaxrs11
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
RestDoc Renderer – v1.0
+ + + + + + + + + +
URLhttps://github.com/hoegertn/restdoc-renderer
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
SLF4J: slf4j-api – Version 1.7.5
+ + + + + + + + + +
URLhttp://www.slf4j.org/
LicenseMIT. A copy of the license is contained in the file LICENSE-slf4j-api.txt and is also available at http://www.slf4j.org/license.html
+ +
SLF4J: jcl-over-slf4j – Version 1.7.6
+ + + + + + + + + +
URLhttp://www.slf4j.org/legacy.html
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
SLF4J: slf4j-ext – Version 1.7.2
+ + + + + + + + + +
URLhttp://www.slf4j.org/extensions.html
LicenseMIT. A copy of the license is contained in the file LICENSE-slf4j-ext.txt and is also available at https://github.com/qos-ch/slf4j/blob/master/LICENSE.txt
+ +
Winery: org.eclipse.winery.common – ${project.version}
+ + + + + + + + + +
URLhttp://eclipse.org/winery/
LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
+ +
Winery: org.eclipse.winery.generators.ia – ${project.version}
+ + + + + + + + + +
URLhttp://eclipse.org/winery/
LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
+ +
Winery: org.eclipse.winery.model.csar.toscametafile – Version 0.0.3
+ + + + + + + + + +
URLhttp://eclipse.org/winery/
LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
+ +
Winery: org.eclipse.winery.model.selfservice – Version 0.1.19
+ + + + + + + + + +
URLhttp://eclipse.org/winery/
LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
+ +
Winery: org.eclipse.winery.model.tosca – Version 0.1.20
+ + + + + + + + + +
URLhttp://eclipse.org/winery/
LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
+ +
Winery: org.eclipse.winery.repository.client – ${project.version}
+ + + + + + + + + +
URLhttp://eclipse.org/winery/
LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
+ +
XML Commons External Components XML APIs Extensions (xml-apis) – Version 1.3.04
+ + + + + + + + + +
URLhttp://xml.apache.org/commons/components/external
LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
+ +
xz for Java – Version 1.3
+ + + + + + + + + +
URLhttp://tukaani.org/xz/java.html
LicensePublic domain. A copy of the license is available at http://tukaani.org/xz/java.html
+ + \ No newline at end of file diff --git a/org.eclipse.winery.repository/about_files/Apache-LICENSE-2.0.txt b/org.eclipse.winery.repository/about_files/Apache-LICENSE-2.0.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/Apache-LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/org.eclipse.winery.repository/about_files/CDDL-v1.1.txt b/org.eclipse.winery.repository/about_files/CDDL-v1.1.txt new file mode 100644 index 0000000000..7cc8719b3b --- /dev/null +++ b/org.eclipse.winery.repository/about_files/CDDL-v1.1.txt @@ -0,0 +1,129 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL - Version 1.1) +1. Definitions. + + 1.1. “Contributor” means each individual or entity that creates or contributes to the creation of Modifications. + + 1.2. “Contributor Version” means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. + + 1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. + + 1.4. “Executable” means the Covered Software in any form other than Source Code. + + 1.5. “Initial Developer” means the individual or entity that first makes Original Software available under this License. + + 1.6. “Larger Work” means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. + + 1.7. “License” means this document. + + 1.8. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. + + 1.9. “Modifications” means the Source Code and Executable form of any of the following: + + A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; + + B. Any new file that contains any part of the Original Software or previous Modification; or + + C. Any new file that is contributed or otherwise made available under the terms of this License. + + 1.10. “Original Software” means the Source Code and Executable form of computer software code that is originally released under this License. + + 1.11. “Patent Claims” means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. + + 1.12. “Source Code” means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. + + 1.13. “You” (or “Your”) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, “You” includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients’ rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient’s rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. + +4. Versions of the License. + + 4.1. New Versions. + + Oracle is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. + +5. DISCLAIMER OF WARRANTY. + +COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as “Participant”) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. + + 6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. + + 6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY’S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. +8. U.S. GOVERNMENT END USERS. + +The Covered Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer software” (as that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software documentation” as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. +9. MISCELLANEOUS. + +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction’s conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys’ fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. +10. RESPONSIBILITY FOR CLAIMS. + +As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. \ No newline at end of file diff --git a/org.eclipse.winery.repository/about_files/EDL.txt b/org.eclipse.winery.repository/about_files/EDL.txt new file mode 100644 index 0000000000..52c7ca2d66 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/EDL.txt @@ -0,0 +1,13 @@ +Eclipse Distribution License - v 1.0 + +Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of the Eclipse Foundation, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/org.eclipse.winery.repository/about_files/LICENSE-ASM.txt b/org.eclipse.winery.repository/about_files/LICENSE-ASM.txt new file mode 100644 index 0000000000..7676ba542d --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-ASM.txt @@ -0,0 +1,29 @@ +Copyright (c) 2000-2011 INRIA, France Telecom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/org.eclipse.winery.repository/about_files/LICENSE-JSch.txt b/org.eclipse.winery.repository/about_files/LICENSE-JSch.txt new file mode 100644 index 0000000000..81c8eacf4f --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-JSch.txt @@ -0,0 +1,30 @@ +JSch 0.0.* was released under the GNU LGPL license. Later, we have switched +over to a BSD-style license. + +------------------------------------------------------------------------------ +Copyright (c) 2002-2012 Atsuhiko Yamanaka, JCraft,Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-KeyboardJS.txt b/org.eclipse.winery.repository/about_files/LICENSE-KeyboardJS.txt new file mode 100644 index 0000000000..e71620bb20 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-KeyboardJS.txt @@ -0,0 +1,25 @@ +Copyright 2011 Robert Hurst. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY ROBERT HURST ''AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ROBERT HURST OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of Robert Hurst. \ No newline at end of file diff --git a/org.eclipse.winery.repository/about_files/LICENSE-XMLWriter.txt b/org.eclipse.winery.repository/about_files/LICENSE-XMLWriter.txt new file mode 100644 index 0000000000..2676da367e --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-XMLWriter.txt @@ -0,0 +1,27 @@ +Copyright (c) 2014, Ariel Flesler +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +* Neither the name of the organization nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-biltong.txt b/org.eclipse.winery.repository/about_files/LICENSE-biltong.txt new file mode 100644 index 0000000000..11cb2154ed --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-biltong.txt @@ -0,0 +1,22 @@ +Copyright (c) 2013 Simon Porritt + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/org.eclipse.winery.repository/about_files/LICENSE-boostrap.txt b/org.eclipse.winery.repository/about_files/LICENSE-boostrap.txt new file mode 100644 index 0000000000..8d94aa9ac9 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-boostrap.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2011-2014 Twitter, Inc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-bootstrap-switch.txt b/org.eclipse.winery.repository/about_files/LICENSE-bootstrap-switch.txt new file mode 100644 index 0000000000..d9a10c0d8e --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-bootstrap-switch.txt @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/org.eclipse.winery.repository/about_files/LICENSE-bootstrap3-wysihtml5-bower.txt b/org.eclipse.winery.repository/about_files/LICENSE-bootstrap3-wysihtml5-bower.txt new file mode 100644 index 0000000000..af8b31e64c --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-bootstrap3-wysihtml5-bower.txt @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (c) 2012 JFHollingworth LTD + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/org.eclipse.winery.repository/about_files/LICENSE-colorPicker.txt b/org.eclipse.winery.repository/about_files/LICENSE-colorPicker.txt new file mode 100644 index 0000000000..d717c4ba38 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-colorPicker.txt @@ -0,0 +1,22 @@ +Copyright (c) 2012 Lakshan Perera + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-datatables.txt b/org.eclipse.winery.repository/about_files/LICENSE-datatables.txt new file mode 100644 index 0000000000..2477290c60 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-datatables.txt @@ -0,0 +1,10 @@ +Copyright (c) 2008-2013, Allan Jardine +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + Neither the name of Allan Jardine nor SpryMedia may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-handlebars.txt b/org.eclipse.winery.repository/about_files/LICENSE-handlebars.txt new file mode 100644 index 0000000000..f466a93fd3 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-handlebars.txt @@ -0,0 +1,19 @@ +Copyright (C) 2011 by Yehuda Katz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-jQuery-UI.txt b/org.eclipse.winery.repository/about_files/LICENSE-jQuery-UI.txt new file mode 100644 index 0000000000..1c693e3d44 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-jQuery-UI.txt @@ -0,0 +1,26 @@ +Copyright 2013 jQuery Foundation and other contributors, +http://jqueryui.com/ + +This software consists of voluntary contributions made by many +individuals (AUTHORS.txt, http://jqueryui.com/about) For exact +contribution history, see the revision history and logs, available +at http://jquery-ui.googlecode.com/svn/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-jQuery.txt b/org.eclipse.winery.repository/about_files/LICENSE-jQuery.txt new file mode 100644 index 0000000000..957f26d3e3 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-jQuery.txt @@ -0,0 +1,21 @@ +Copyright 2013 jQuery Foundation and other contributors +http://jquery.com/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-jsPlumb-MIT.txt b/org.eclipse.winery.repository/about_files/LICENSE-jsPlumb-MIT.txt new file mode 100644 index 0000000000..b5bc6504fc --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-jsPlumb-MIT.txt @@ -0,0 +1,20 @@ +Copyright (c) 2013 Simon Porritt, http://jsplumb.org/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-logback.txt b/org.eclipse.winery.repository/about_files/LICENSE-logback.txt new file mode 100644 index 0000000000..b4fe24e02a --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-logback.txt @@ -0,0 +1,15 @@ +Logback LICENSE +--------------- + +Logback: the reliable, generic, fast and flexible logging framework. +Copyright (C) 1999-2012, QOS.ch. All rights reserved. + +This program and the accompanying materials are dual-licensed under +either the terms of the Eclipse Public License v1.0 as published by +the Eclipse Foundation + + or (per the licensee's choosing) + +under the terms of the GNU Lesser General Public License version 2.1 +as published by the Free Software Foundation. + diff --git a/org.eclipse.winery.repository/about_files/LICENSE-open-sans.txt b/org.eclipse.winery.repository/about_files/LICENSE-open-sans.txt new file mode 100644 index 0000000000..392c811a21 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-open-sans.txt @@ -0,0 +1,204 @@ +License for 'Open Sans' +Apache License + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + License shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + Licensor shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + Legal Entity shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + control means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + You (or Your) shall mean an individual or Legal Entity + exercising permissions granted by this License. + + Source form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + Object form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + Work shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + Derivative Works shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + Contribution shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, submitted + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as Not a Contribution. + + Contributor shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a NOTICE text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an AS IS BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets [] + replaced with your own identifying information. (Dont include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same printed page as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the License); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an AS IS BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/org.eclipse.winery.repository/about_files/LICENSE-requirejs.txt b/org.eclipse.winery.repository/about_files/LICENSE-requirejs.txt new file mode 100644 index 0000000000..de4ee2963f --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-requirejs.txt @@ -0,0 +1,58 @@ +RequireJS is released under two licenses: new BSD, and MIT. You may pick the +license that best suits your development needs. The text of both licenses are +provided below. + + +The "New" BSD License: +---------------------- + +Copyright (c) 2010-2013, The Dojo Foundation +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Dojo Foundation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + +MIT License +----------- + +Copyright (c) 2010-2013, The Dojo Foundation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-slf4j-api.txt b/org.eclipse.winery.repository/about_files/LICENSE-slf4j-api.txt new file mode 100644 index 0000000000..37050c9568 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-slf4j-api.txt @@ -0,0 +1,21 @@ + Copyright (c) 2004-2013 QOS.ch + All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-slf4j-ext.txt b/org.eclipse.winery.repository/about_files/LICENSE-slf4j-ext.txt new file mode 100644 index 0000000000..361d2ce016 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-slf4j-ext.txt @@ -0,0 +1,24 @@ +Copyright (c) 2004-2013 QOS.ch +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + diff --git a/org.eclipse.winery.repository/about_files/LICENSE-wysihtml5.txt b/org.eclipse.winery.repository/about_files/LICENSE-wysihtml5.txt new file mode 100644 index 0000000000..e5083d05f5 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-wysihtml5.txt @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (c) 2012 XING AG + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/org.eclipse.winery.repository/about_files/LICENSE-x-editable.txt b/org.eclipse.winery.repository/about_files/LICENSE-x-editable.txt new file mode 100644 index 0000000000..eeb9357e72 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-x-editable.txt @@ -0,0 +1,22 @@ +Copyright (c) 2012 Vitaliy Potapov + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.repository/about_files/LICENSE-xmltree.txt b/org.eclipse.winery.repository/about_files/LICENSE-xmltree.txt new file mode 100644 index 0000000000..7a280634bc --- /dev/null +++ b/org.eclipse.winery.repository/about_files/LICENSE-xmltree.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Mitya + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/org.eclipse.winery.repository/about_files/MPL-v1.1.txt b/org.eclipse.winery.repository/about_files/MPL-v1.1.txt new file mode 100644 index 0000000000..a8cd934df1 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/MPL-v1.1.txt @@ -0,0 +1,470 @@ + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the MPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + diff --git a/org.eclipse.winery.repository/about_files/file-icons.txt b/org.eclipse.winery.repository/about_files/file-icons.txt new file mode 100644 index 0000000000..f7a8560715 --- /dev/null +++ b/org.eclipse.winery.repository/about_files/file-icons.txt @@ -0,0 +1,27 @@ +http://www.splitbrain.org/projects/file_icons + +Released to the Public Domain +Free to use. Provided as is. No warranties. + +Note: The big majority of icons where created by the creators listed + below. Only a few ones where found on the net. They were too + widespread to determine the original author and thus were + considered public domain. + If you are the author of one of those icons just send a short + mail to either be included in the list below or have the icon + removed from the package. + +Creators: + + Andreas Gohr + Michael Klier + Andreas Barton + Hubert Chathi + Johan Koehne + Rudi von Staden + Daniel Darvish + Andy Pascall + Seth + David Carella + Tom N. Harris + Brandon Carmon Colvin diff --git a/org.eclipse.winery.repository/bower.json b/org.eclipse.winery.repository/bower.json new file mode 100644 index 0000000000..73766abbc9 --- /dev/null +++ b/org.eclipse.winery.repository/bower.json @@ -0,0 +1,61 @@ +{ + "name": "Winery", + "version": "0.1.37-SNAPSHOT", + "author": "Oliver Kopp ", + "contributors": [ + { + "name": "Uwe Breitenbücher" + }, + { + "name": "Kálmán Képes" + }, + { + "name": "Yves Schubert" + }, + { + "name": "Timur Sungur" + }, + { + "name": "Jerome Tagliaferri" + } + ], + "licenses": [ + { + "type": "EPL", + "url": "http://www.eclipse.org/legal/epl-v10.html" + }, + { + "type": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + } + ], + "dependencies": { + "blueimp-file-upload": "9.5.3", + "blueimp-tmpl": "2.5.3", + "bootstrap": "3.1.1", + "bootstrap-spinedit": "https://github.com/scyv/bootstrap-spinedit.git#1.0.0", + "bootstrap-switch": "v1.9.0", + "colorPicker": "https://github.com/Belelros/jQuery-ColorPicker.git#1.0.2", + "datatables": "1.9.4", + "jquery": "2.0.3", + "jquery-typing": "https://github.com/tnajdek/jquery-typing.git#0.3.2-2", + "jquery-ui": "1.10.3", + "jsPlumb": "1.5.4", + "KeyboardJS": "git://github.com/RobertWHurst/KeyboardJS.git#v0.4.2", + "pnotify": "https://github.com/koppor/pnotify.git#1.2.2-koppor-2", + "requirejs": "2.1.5", + "select2": "https://github.com/ivaynberg/select2/archive/3.4.5.zip", + "uri.js": "v1.12.0", + "x-editable": "1.5.1", + "bootstrap3-wysihtml5-bower": "0.2.8", + "wysihtml5": "0.3.0", + "xmltree": "3.1.2", + "XMLWriter": "1.0.2" + }, + "keywords": [ + "TOSCA" + ], + "resolutions": { + "jquery": "2.0.3" + } +} diff --git a/org.eclipse.winery.repository/conf/winery.properties.dist b/org.eclipse.winery.repository/conf/winery.properties.dist new file mode 100644 index 0000000000..078d1bd64f --- /dev/null +++ b/org.eclipse.winery.repository/conf/winery.properties.dist @@ -0,0 +1,49 @@ +#URL for the topology modeler +#topologymodeler=http://opentosca-winery.appspot.com + +#Warning to be displayed +warning = Development version ${project.version} + +#speedup at first XML save +#default: false +initializeXMLValidationDuringStartup = true + +############################################################################# +# Repository Storage Configuration +############################################################################# + + +# Option A: plain file-based repository +# locally stored +############################################################################# + +#use slashes +#repositoryPath=c:/winery-repository + + +# Option B: git based repository, based on Option A +# locally stored +############################################################################# +# first, configure Option A + +#additionally: +#for http-based username/password authentification +#git.username=username +#git.password=password + + +# Option C: jclouds-based repository +# +# !! NOT SUPPORTED YET !! +# +# See http://www.jclouds.org/documentation/reference/supported-providers/ +# for a list of supported providers +############################################################################# + +#jclouds.context.provider=aws-s3 +#jclouds.context.identity=OOV7VOHYFEE7AIGOKAEM9TAH +#jclouds.context.credential=iw4DoopGui4is4eze7Eeph4/aeYoo7re + +# optional options +#jclouds.blobstore.location=US-EAST +#jclouds.blobstore.container=repository.winery diff --git a/org.eclipse.winery.repository/pom.xml b/org.eclipse.winery.repository/pom.xml new file mode 100644 index 0000000000..8a4c45f691 --- /dev/null +++ b/org.eclipse.winery.repository/pom.xml @@ -0,0 +1,522 @@ + + + + 4.0.0 + + org.eclipse.winery + winery + 0.1.37-SNAPSHOT + + org.eclipse.winery.repository + war + + UTF-8 + + + + ch.qos.logback + logback-classic + 1.1.1 + compile + + + com.fasterxml.jackson.core + jackson-databind + 2.2.2 + compile + + + com.fasterxml.jackson.core + jackson-core + 2.2.2 + compile + + + com.sun.jersey + jersey-core + 1.17 + compile + + + org.apache.commons + commons-compress + 1.6 + compile + + + org.tukaani + xz + + + + + + org.tukaani + xz + 1.3 + + + commons-io + commons-io + 2.1 + compile + + + xerces + xercesImpl + 2.9.1 + compile + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + org.apache.tika + tika-core + 1.3 + compile + + + org.restdoc + restdoc-server-jersey + 1.0.1 + compile + + + + com.sun.jersey + jersey-server + + + com.sun.jersey + jersey-servlet + + + com.fasterxml.jackson.core + jackson-core + + + + javax.ws.rs + jsr311-api + + + + com.fasterxml.jackson.core + jackson-annotations + + + + com.fasterxml.jackson.core + jackson-databind + + + + org.slf4j + slf4j-api + + + + + com.sun.jersey.contribs + jersey-multipart + 1.17 + compile + + + org.jvnet + mimepull + + + + + org.jvnet.mimepull + mimepull + 1.9.4 + + + org.apache.commons + commons-lang3 + 3.1 + compile + + + org.eclipse.winery + org.eclipse.winery.model.selfservice + + 0.1.19 + compile + + + org.slf4j + jcl-over-slf4j + 1.7.6 + compile + + + com.sun.jersey + jersey-servlet + 1.11 + compile + + + com.sun.jersey + jersey-server + 1.17 + compile + + + jstl + jstl + 1.2 + compile + + + org.eclipse.winery + org.eclipse.winery.model.csar.toscametafile + + 0.0.3 + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + 2.2.2 + + + org.slf4j + slf4j-ext + 1.7.2 + compile + + + + ch.qos.cal10n + cal10n-api + + + + + org.eclipse.winery + org.eclipse.winery.common + 0.1.31 + compile + + + org.eclipse.winery + org.eclipse.winery.generators.ia + 0.1.31 + compile + + + org.eclipse.winery + org.eclipse.winery.repository.client + 0.1.31 + compile + + + commons-configuration + commons-configuration + 1.9 + compile + + + + commons-logging + commons-logging + + + + + org.eclipse.jgit + org.eclipse.jgit + 3.0.0.201306101825-r + compile + + + + com.sun.xml.bind + jaxb-impl + 2.2.5 + + + + junit + junit + 4.11 + test + + + com.jayway.restassured + rest-assured + 1.9.0 + test + + + + + + . + true + + about.html + + + + src/main/resources + true + + winery.properties + + + + src/main/templates + + *.java + + true + ${project.build.directory}/generated-sources/java/org/eclipse/winery/repository + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-war-plugin + 2.4 + + + + ${basedir}/src/main/webapp/WEB-INF + true + WEB-INF + + tags/about.tag + tags/genericpage.tag + + + + + + + maven-antrun-plugin + 1.7 + + + + org.codehaus.groovy + groovy-all + 2.1.7 + + + + + generate-sources + default-cli + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + run + + + + + + maven-clean-plugin + 2.5 + + + + + ${project.basedir}/src/main/webapp/WEB-INF/tags/common + + .gitignore + + false + + + + ${project.basedir}/src/main/webapp/jsp/shared + + .gitignore + + false + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.16 + + true + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.8 + + + add-source + generate-sources + + add-source + + + + ${project.build.directory}/generated-sources/java/ + + + + + + + winery + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.maven.plugins + maven-antrun-plugin + [1.0.0,) + + run + + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + [1.0.0,) + + resources + + + + + true + false + + + + + + org.codehaus.mojo + build-helper-maven-plugin + [1.0,) + + parse-version + add-source + maven-version + add-resource + add-test-resource + add-test-source + + + + + true + true + + + + + + + + + + + diff --git a/org.eclipse.winery.repository/sonar-project.java.properties b/org.eclipse.winery.repository/sonar-project.java.properties new file mode 100644 index 0000000000..2c182ef012 --- /dev/null +++ b/org.eclipse.winery.repository/sonar-project.java.properties @@ -0,0 +1,24 @@ +# required metadata +sonar.projectKey=org.eclipse.winery.repository-java +sonar.projectName=org.eclipse.winery.repository-java +sonar.projectVersion=0.1.2 + +# path to source directories (required) +sonar.sources=src/main/java + +# path to test source directories (optional) +#sonar.tests= + +# path to project binaries (optional), for example directory of Java bytecode +#sonar.binaries=binDir + +# optional comma-separated list of paths to libraries. Only path to JAR file and path to directory of classes are supported. +#sonar.libraries=org.eclipse.jgit-2.1.0.201209190230-r.jar + +# The value of the property must be the key of the language. +sonar.language=java + +# enforece Java 1.7 to enable analysis of diamon operator by PMD +sonar.java.source=1.7 + +sonar.sourceEncoding=UTF-8 diff --git a/org.eclipse.winery.repository/sonar-project.twomodules.properties b/org.eclipse.winery.repository/sonar-project.twomodules.properties new file mode 100644 index 0000000000..a03160f92a --- /dev/null +++ b/org.eclipse.winery.repository/sonar-project.twomodules.properties @@ -0,0 +1,29 @@ +# required metadata +sonar.projectKey=valesca +sonar.projectName=Valesca +sonar.projectVersion=1.0 + +# path to source directories (required) +sonar.sources=. +sonar.sourceEncoding=UTF-8 + +sonar.modules=java,jsp + +## Java +java.sonar.projectBaseDir=src/main/java +java.sonar.language=java + +# path to test source directories (optional) +#java.sonar.tests= + +# path to project binaries (optional), for example directory of Java bytecode +#java.sonar.binaries=binDir + +# optional comma-separated list of paths to libraries. Only path to JAR file and path to directory of classes are supported. +#java.sonar.libraries=org.eclipse.jgit-2.1.0.201209190230-r.jar + +## jsp +#http://docs.codehaus.org/display/SONAR/Web+Plugin +jsp.sonar.projectBaseDir=src/main/webapp +jsp.sonar.language=web +jsp.sonar.web.sourceDirectory=src/main/webapp diff --git a/org.eclipse.winery.repository/sonar-project.web.properties b/org.eclipse.winery.repository/sonar-project.web.properties new file mode 100644 index 0000000000..bd3ab14048 --- /dev/null +++ b/org.eclipse.winery.repository/sonar-project.web.properties @@ -0,0 +1,16 @@ +# required metadata +sonar.projectKey=org.eclipse.winery.repository-web +sonar.projectName=org.eclipse.winery.repository-web +sonar.projectVersion=0.1.2 + +# path to source directories (required) +sonar.sources=src/main/ +sonar.exclusions=webapp/components/** + +# The value of the property must be the key of the language. +sonar.language=web + +sonar.sourceEncoding=UTF-8 + +#http://docs.codehaus.org/display/SONAR/Web+Plugin +sonar.web.sourceDirectory=src/main/webapp \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Constants.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Constants.java new file mode 100644 index 0000000000..9fd3785074 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Constants.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository; + +import java.util.Calendar; +import java.util.Date; + +public class Constants { + + /** repository specific **/ + public static final String DEFAULT_REPO_NAME = "winery-repository"; + // this directory is checked for existence. If it does not exist + // $HOME/DEFAULT_REPO_NAME is used + public static final String GLOBAL_REPO_PATH_WINDOWS = "C:\\" + Constants.DEFAULT_REPO_NAME; + + /** file-system in general **/ + public static final String newline = System.getProperty("line.separator"); + + // Path to images for extensions + // Currently, we require the format .png + public static final String PATH_MIMETYPEIMAGES = "/images/mime-types/"; + + // suffix for CSAR files + public static final String SUFFIX_CSAR = ".csar"; + + // suffix for files in the directory PATH_MIMETYPEIMAGES, including "." + public static final String SUFFIX_MIMETYPEIMAGES = ".png"; + + // suffix for files storing the mimetype of the belonging files + // used in implementors if IRepository of no appropriate implementation for storing a mimetype is available + public static final String SUFFIX_MIMETYPE = ".mimetype"; + + // suffix for all property files + public static final String SUFFIX_PROPERTIES = ".properties"; + + // suffix for all files storing Definitions + // following line 2935 of TOSCA cos01 + public static final String SUFFIX_TOSCA_DEFINITIONS = ".tosca"; + + // at each new start of the application, the modified date changes + // reason: the default values of the properties or the JSP could have + // changed + public static final Date LASTMODIFIEDDATE_FOR_404 = Calendar.getInstance().getTime(); + + public static final String TOSCA_PLANTYPE_BUILD_PLAN = "http://docs.oasis-open.org/tosca/ns/2011/12/PlanTypes/BuildPlan"; + public static final String TOSCA_PLANTYPE_TERMINATION_PLAN = "http://docs.oasis-open.org/tosca/ns/2011/12/PlanTypes/TerminationPlan"; + + public static final String DIRNAME_SELF_SERVICE_METADATA = "SELFSERVICE-Metadata"; + + /* used for IA generation */ + //public static final String NAMESPACE_ARTIFACTTYPE_WAR = "http://www.opentosca.org/types"; + public static final String NAMESPACE_ARTIFACTTYPE_WAR = "http://www.example.com/ToscaTypes"; + public static final String LOCALNAME_ARTIFACTTYPE_WAR = "WAR"; + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/JAXBSupport.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/JAXBSupport.java new file mode 100644 index 0000000000..876c015d3e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/JAXBSupport.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; + +import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition; +import org.eclipse.winery.model.tosca.TDefinitions; +import org.eclipse.winery.repository.backend.MockXMLElement; +import org.eclipse.winery.repository.resources.admin.NamespacesResource; +import org.eclipse.winery.model.selfservice.Application; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.xml.bind.marshaller.NamespacePrefixMapper; + +// if com.sun.xml.bind.marshaller.NamespacePrefixMapper cannot be resolved, +// possibly +// http://mvnrepository.com/artifact/com.googlecode.jaxb-namespaceprefixmapper-interfaces/JAXBNamespacePrefixMapper/2.2.4 +// helps +// also com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper could be the +// right package + +/** + * Bundles all general JAXB functionality + */ +public class JAXBSupport { + + private static final Logger logger = LoggerFactory.getLogger(JAXBSupport.class); + + // thread-safe JAXB as inspired by https://jaxb.java.net/guide/Performance_and_thread_safety.html + // The other possibility: Each subclass sets JAXBContext.newInstance(theSubClass.class); in its static {} part. + // This seems to be more complicated than listing all subclasses in initContext + public final static JAXBContext context = JAXBSupport.initContext(); + + private final static PrefixMapper prefixMapper = new PrefixMapper(); + + + /** + * Follows + * https://jaxb.java.net/2.2.5/docs/release-documentation.html#marshalling + * -changing-prefixes + * + * See http://www.jarvana.com/jarvana/view/com/sun/xml/bind/jaxb-impl/2.2.2/ + * jaxb-impl-2.2.2-javadoc.jar!/com/sun/xml/bind/marshaller/ + * NamespacePrefixMapper.html for a JavaDoc of the NamespacePrefixMapper + */ + private static class PrefixMapper extends NamespacePrefixMapper { + + @Override + public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { + if (namespaceUri.equals("")) { + return ""; + } + + // this does not work to get TOSCA elements without prefix + // possibly because the attribute "name" is present without prefix + // if (namespaceUri.equals(Namespaces.TOSCA_NAMESPACE)) { + // return ""; + // } + + String prefix = NamespacesResource.getPrefix(namespaceUri); + return prefix; + } + } + + + private static JAXBContext initContext() { + JAXBContext context; + try { + // For winery classes, eventually the package+jaxb.index method could be better. See http://stackoverflow.com/a/3628525/873282 + // @formatter:off + context = JAXBContext.newInstance( + TDefinitions.class, // all other elements are referred by "@XmlSeeAlso" + WinerysPropertiesDefinition.class, + // for the self-service portal + Application.class, + // MockXMLElement is added for testing purposes only. + MockXMLElement.class); + // @formatter:on + } catch (JAXBException e) { + JAXBSupport.logger.error("Could not initialize JAXBContext", e); + throw new IllegalStateException(e); + } + return context; + } + + /** + * Creates a marshaller + * + * @throws IllegalStateException if marshaller could not be instantiated + */ + public static Marshaller createMarshaller(boolean includeProcessingInstruction) { + Marshaller m; + try { + m = JAXBSupport.context.createMarshaller(); + // pretty printed output is required as the XML is sent 1:1 to the browser for editing + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + m.setProperty("com.sun.xml.bind.namespacePrefixMapper", JAXBSupport.prefixMapper); + if (!includeProcessingInstruction) { + // side effect of JAXB_FRAGMENT property (when true): processing instruction is not included + m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); + } + } catch (JAXBException e) { + JAXBSupport.logger.error("Could not instantiate marshaller", e); + throw new IllegalStateException(e); + } + + return m; + } + + /** + * Creates an unmarshaller + * + * @throws IllegalStateException if unmarshaller could not be instantiated + */ + public static Unmarshaller createUnmarshaller() { + try { + return JAXBSupport.context.createUnmarshaller(); + } catch (JAXBException e) { + JAXBSupport.logger.error("Could not instantiate unmarshaller", e); + throw new IllegalStateException(e); + } + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Prefs.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Prefs.java new file mode 100644 index 0000000000..dd5c3a2426 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Prefs.java @@ -0,0 +1,293 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + * C. Timurhan Sungur - jClouds preferences + *******************************************************************************/ +package org.eclipse.winery.repository; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.security.AccessControlException; +import java.util.Locale; +import java.util.Properties; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.eclipse.winery.common.TOSCADocumentBuilderFactory; +import org.eclipse.winery.repository.backend.IRepository; +import org.eclipse.winery.repository.backend.filebased.FilebasedRepository; +import org.eclipse.winery.repository.backend.filebased.GitBasedRepository; +import org.eclipse.winery.repository.runtimeintegration.OpenTOSCAContainerConnection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Prefs implements ServletContextListener { + + // set by the constructors + // We have to do this hack as the servlet container initializes this class + // on its own and we want to have a *single* instance of this class. + public static Prefs INSTANCE; + + private static final Logger logger = LoggerFactory.getLogger(Prefs.class); + + protected IRepository repository = null; + + private ServletContext context; + + private Boolean isContainerLocallyAvailable = null; + + private Boolean isRestDocDocumentationAvailable = null; + + // location of the winery topology modeler + private String wineryTopologyModelerPath = null; + + // the properties from winery.properties + protected Properties properties = null; + + // package visibility to ease testing + static final String PROP_JCLOUDS_CONTEXT_PROVIDER = "jclouds.context.provider"; + static final String PROP_JCLOUDS_CONTEXT_IDENTITY = "jclouds.context.identity"; + static final String PROP_JCLOUDS_CONTEXT_CREDENTIAL = "jclouds.context.credential"; + static final String PROP_JCLOUDS_BLOBSTORE_LOCATION = "jclouds.blobstore.location"; + static final String PROP_JCLOUDS_CONTAINERNAME = "jclouds.blobstore.container"; + static final String PROP_JCLOUDS_END_POINT = "jclouds.blobstore.endpoint"; + + static final String PROP_INITIALIZE_XML_VALIDATION_DURING_STARTUP = "initializeXMLValidationDuringStartup"; + + + /** + * This constructor is called at handling at servlets, too. Therefore, we + * make it private. If testing is needed, an additional paramater has to be + * passed + */ + public Prefs() { + Prefs.INSTANCE = this; + } + + /** + * Constructor for Unit testing ONLY! + * + * @param initializeRepository true if the repository should be initialized + * as provided in winery.properties + * @throws IOException + * @warning Do not call! (except from Unit testing code) + */ + protected Prefs(boolean initializeRepository) throws IOException { + this(); + + // emulate behavior of doInitialization(Context) + Properties p = new Properties(); + InputStream is = this.getClass().getClassLoader().getResourceAsStream("winery.properties"); + if (is != null) { + p.load(is); + } + this.properties = p; + + if (initializeRepository) { + this.doRepositoryInitialization(); + } + } + + /** + * Initialization code for the repository. Should go into separate class, + * but being here should be OK for a prototype + * + * Called from both the constructor for JUnit and the servlet-based + * initialization + * + * Pre-Condition: this.properties is set. + */ + private void doRepositoryInitialization() { + assert (this.properties != null); + + String provider = this.properties.getProperty(Prefs.PROP_JCLOUDS_CONTEXT_PROVIDER); + if (provider != null) { + // repository runs via jclouds + // String identity = this.properties.getProperty(Prefs.PROP_JCLOUDS_CONTEXT_IDENTITY); + // String credential = this.properties.getProperty(Prefs.PROP_JCLOUDS_CONTEXT_CREDENTIAL); + // String location = this.properties.getProperty(Prefs.PROP_JCLOUDS_BLOBSTORE_LOCATION); + // String containerName = this.properties.getProperty(Prefs.PROP_JCLOUDS_CONTAINERNAME); + // String endPoint = this.properties.getProperty(Prefs.PROP_JCLOUDS_END_POINT); + Prefs.logger.error("jClouds is currently not supported due to jClouds not yet approved by Eclipse. Falling back to local storages"); + provider = null; + // Prefs.logger.info("Using jclouds as interface to the repository"); + // this.repository = new JCloudsBasedRepository(provider, identity, credential, location, containerName, endPoint); + } // else { + if (provider == null) { + String repositoryLocation = this.properties.getProperty("repositoryPath"); + Prefs.logger.debug("Repository location: {}", repositoryLocation); + Prefs.logger.debug("Trying git-based backend"); + try { + this.repository = new GitBasedRepository(repositoryLocation); + Prefs.logger.debug("git-based backend is used"); + } catch (Throwable e) { + Prefs.logger.trace(e.getMessage()); + Prefs.logger.debug("There seems to be no git repository at the specified location. We fall back to the file-based repository"); + this.repository = new FilebasedRepository(repositoryLocation); + } + } + } + + private void doInitialization(ServletContext ctx) { + if (Locale.getDefault() != Locale.ENGLISH) { + try { + // needed for {@link + // org.eclipse.winery.repository.filesystem.Utils.returnFile(File, + // String)} + Locale.setDefault(Locale.ENGLISH); + } catch (AccessControlException e) { + // Happens at Google App Engine + Prefs.logger.error("Could not switch locale to English", e); + } + } + + this.context = ctx; + + // Reading // + final String fn = "/WEB-INF/classes/winery.properties"; + Prefs.logger.debug("Trying to read ".concat(ctx.getRealPath(fn))); + InputStream inStream = ctx.getResourceAsStream(fn); + // alternative: InputStream inStream = this.getClass().getClassLoader().getResourceAsStream("winery.properties"); + Properties p = new Properties(); + if (inStream == null) { + Prefs.logger.info(fn + " does not exist."); + } else { + try { + p.load(inStream); + try { + inStream.close(); + } catch (IOException e) { + Prefs.logger.error("Could not close stream of winery.properties", e); + } + } catch (FileNotFoundException e) { + // OK if file does not exist + } catch (IOException e) { + Prefs.logger.error("Could not load winery.properties", e); + } + } + + this.wineryTopologyModelerPath = p.getProperty("topologymodeler"); + + // make the properties known in the class + this.properties = p; + + this.doRepositoryInitialization(); + + String init = p.getProperty(Prefs.PROP_INITIALIZE_XML_VALIDATION_DURING_STARTUP); + boolean doXMLInitialization = false; + if (p != null) { + doXMLInitialization = Boolean.parseBoolean(init); + } + if (doXMLInitialization) { + // initialize XSD validation. Takes up a few seconds + // if we do not do it here, the first save by a user takes a few seconds, which is inconvenient + Prefs.logger.debug("Initializing XML validation"); + @SuppressWarnings("unused") + TOSCADocumentBuilderFactory tdbf = TOSCADocumentBuilderFactory.INSTANCE; + Prefs.logger.debug("Initialized XML validation"); + } + } + + public IRepository getRepository() { + return this.repository; + } + + @Override + public void contextInitialized(ServletContextEvent arg0) { + Prefs.INSTANCE.doInitialization(arg0.getServletContext()); + } + + @Override + public void contextDestroyed(ServletContextEvent arg0) { + // nothing to do at tear down + } + + /** + * @return the path of the root resource + */ + public String getResourcePath() { + return this.context.getContextPath(); + } + + /** + * @return the path to the winery topology modeler. Without trailing slash + */ + public String getWineryTopologyModelerPath() { + if (this.wineryTopologyModelerPath == null) { + // derive the path from the current path + String res = this.getResourcePath(); + if (res.endsWith("/")) { + res = res.substring(0, res.length() - 1); + } + int pos = res.lastIndexOf("/"); + if (pos <= 0) { + res = "/winery-topologymodeler"; + } else { + res = res.substring(0, pos); + res = res + "winery-topologymodeler"; + } + return res; + } else { + assert (this.wineryTopologyModelerPath != null); + return this.wineryTopologyModelerPath; + } + } + + /** + * Returns the read content from winery.properties. + * + * @return the internal object held by this class. Manipulations on this + * object may cause trouble. + */ + public Properties getProperties() { + return this.properties; + } + + /** + * @return the version of winery + */ + public String getVersion() { + return Version.VERSION; + } + + /** + * @return true if the OpenTOSCA container is locally available + */ + public boolean isContainerLocallyAvailable() { + if (this.isContainerLocallyAvailable == null) { + // we initialize the variable at the first read + // The container and Winery are started simultaneously + // Therefore, the container might not be available if Winery is starting + // When checking at the first read, chances are high that the container started + this.isContainerLocallyAvailable = OpenTOSCAContainerConnection.isContainerLocallyAvailable(); + } + return this.isContainerLocallyAvailable; + } + + /** + * Quick hack to check whether a RestDoc documentation is available at + * /restdoc.html. We do not deliver + */ + public boolean isRestDocDocumentationAvailable() { + String path = "http://localhost:8080/restdoc.html"; + if (this.isRestDocDocumentationAvailable == null) { + // we initialize the variable at the first read + // The container and Winery are started simultaneously + // Therefore, the container might not be available if Winery is starting + // When checking at the first read, chances are high that the container started + this.isRestDocDocumentationAvailable = Utils.isResourceAvailable(path); + } + return this.isRestDocDocumentationAvailable; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/RestDocFilter.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/RestDocFilter.java new file mode 100644 index 0000000000..92b7fe357e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/RestDocFilter.java @@ -0,0 +1,14 @@ +package org.eclipse.winery.repository; + +import org.eclipse.winery.repository.resources.MainResource; +import org.restdoc.jersey.server.RestDocFeature; + +public class RestDocFilter extends RestDocFeature { + + @Override + protected Class[] getClasses() { + Class[] res = {MainResource.class}; + return res; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Utils.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Utils.java new file mode 100644 index 0000000000..756dd00f2d --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/Utils.java @@ -0,0 +1,783 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.StringWriter; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.Response.Status.Family; +import javax.ws.rs.core.StreamingOutput; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; + +import org.apache.commons.compress.archivers.ArchiveException; +import org.apache.taglibs.standard.functions.Functions; +import org.apache.tika.detect.Detector; +import org.apache.tika.metadata.Metadata; +import org.apache.tika.parser.AutoDetectParser; +import org.apache.xerces.xs.XSConstants; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.common.ids.definitions.imports.XSDImportId; +import org.eclipse.winery.model.tosca.TArtifactType; +import org.eclipse.winery.model.tosca.TConstraint; +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.model.tosca.TEntityType; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TNodeType; +import org.eclipse.winery.model.tosca.TPolicyType; +import org.eclipse.winery.model.tosca.TRelationshipType; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.datatypes.ids.admin.AdminId; +import org.eclipse.winery.repository.export.CSARExporter; +import org.eclipse.winery.repository.export.TOSCAExportUtil; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources.AbstractComponentsResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypesResource; +import org.eclipse.winery.repository.resources.entitytypes.relationshiptypes.RelationshipTypeResource; +import org.eclipse.winery.repository.resources.entitytypes.relationshiptypes.RelationshipTypesResource; +import org.eclipse.winery.repository.resources.imports.xsdimports.XSDImportResource; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; +import org.w3c.dom.Element; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; + +/** + * Contains utility functionality concerning with everything that is + * not related only to the repository, but more. For instance, resource + * functionality. Utility functionality for the repository is contained at + * {@link BackendUtils} + */ +public class Utils { + + private static final XLogger logger = XLoggerFactory.getXLogger(Utils.class); + + + public static URI createURI(String uri) { + try { + return new URI(uri); + } catch (URISyntaxException e) { + throw new IllegalStateException(); + } + } + + + // RegExp inspired by http://stackoverflow.com/a/5396246/873282 + // NameStartChar without ":" + // stackoverflow: -dfff, standard: d7fff + private static final String RANGE_NCNAMESTARTCHAR = "A-Z_a-z\\u00C0\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02ff\\u0370-\\u037d" + "\\u037f-\\u1fff\\u200c\\u200d\\u2070-\\u218f\\u2c00-\\u2fef\\u3001-\\ud7ff" + "\\uf900-\\ufdcf\\ufdf0-\\ufffd\\x10000-\\xEFFFF"; + private static final String REGEX_NCNAMESTARTCHAR = "[" + Utils.RANGE_NCNAMESTARTCHAR + "]"; + + private static final String RANGE_NCNAMECHAR = Utils.RANGE_NCNAMESTARTCHAR + "\\-\\.0-9\\u00b7\\u0300-\\u036f\\u203f-\\u2040"; + private static final String REGEX_INVALIDNCNAMESCHAR = "[^" + Utils.RANGE_NCNAMECHAR + "]"; + + + /** + * Creates a (valid) XML ID (NCName) based on the passed name + * + * Valid NCNames: http://www.w3.org/TR/REC-xml-names/#NT-NCName / + * http://www.w3.org/TR/xml/#NT-Name http://www.w3.org/TR/xml/#NT-Name + * + */ + public static XMLId createXMLid(String name) { + return new XMLId(Utils.createXMLidAsString(name), false); + } + + /** + * Creates a (valid) XML ID (NCName) based on the passed name + * + * Valid NCNames: http://www.w3.org/TR/REC-xml-names/#NT-NCName / + * http://www.w3.org/TR/xml/#NT-Name http://www.w3.org/TR/xml/#NT-Name + * + * TODO: this method seems to be equal to {@link + * org.eclipse.winery.common.Util.makeNCName(String)}. The methods should be + * merged into one. + * + */ + public static String createXMLidAsString(String name) { + String id = name; + if (!id.substring(0, 1).matches(Utils.REGEX_NCNAMESTARTCHAR)) { + id = "_".concat(id); + } + // id starts with a valid character + + // before we wipe out all invalid characters, we do a readable + // replacement for appropriate characters + id = id.replace(' ', '_'); + + // keep length of ID, only wipe out invalid characters + // alternative: replace invalid characters by URLencoded version. As the + // ID is visible only in the URL, this quick hack should be OK + // ID is visible only in the URL, this quick hack should be OK + id = id.replaceAll(Utils.REGEX_INVALIDNCNAMESCHAR, "_"); + + return id; + } + + /** + * Returns the plain XML for the selected resource + * + * @param uri + */ + public static Response getDefinitionsOfSelectedResource(final AbstractComponentInstanceResource resource, final URI uri) { + final TOSCAExportUtil exporter = new TOSCAExportUtil(); + StreamingOutput so = new StreamingOutput() { + + @Override + public void write(OutputStream output) throws IOException, WebApplicationException { + Map conf = new HashMap<>(); + conf.put(TOSCAExportUtil.ExportProperties.REPOSITORY_URI.toString(), uri); + try { + exporter.exportTOSCA(resource.getId(), output, conf); + } catch (JAXBException e) { + throw new WebApplicationException(e); + } + output.close(); + } + }; + /* + * this code is for offering a download action // Browser offers save as + * // .tosca is more or less needed for debugging, only a CSAR makes + * sense. // Therefore, we want to have the xml opened in the browser. + * StringBuilder sb = new StringBuilder(); + * sb.append("attachment;filename=\""); + * sb.append(resource.getXmlId().getEncoded()); sb.append(" - "); + * sb.append(resource.getNamespace().getEncoded()); sb.append(".xml"); + * sb.append("\""); return Response.ok().header("Content-Disposition", + * sb + * .toString()).type(MediaType.APPLICATION_XML_TYPE).entity(so).build(); + */ + return Response.ok().type(MediaType.APPLICATION_XML).entity(so).build(); + } + + public static Response getCSARofSelectedResource(final AbstractComponentInstanceResource resource) { + final CSARExporter exporter = new CSARExporter(); + StreamingOutput so = new StreamingOutput() { + + @Override + public void write(OutputStream output) throws IOException, WebApplicationException { + try { + exporter.writeCSAR(resource.getId(), output); + } catch (XMLStreamException | JAXBException | ArchiveException e) { + throw new WebApplicationException(e); + } + } + }; + StringBuilder sb = new StringBuilder(); + sb.append("attachment;filename=\""); + sb.append(resource.getXmlId().getEncoded()); + sb.append(org.eclipse.winery.repository.Constants.SUFFIX_CSAR); + sb.append("\""); + return Response.ok().header("Content-Disposition", sb.toString()).type(org.eclipse.winery.common.constants.MimeTypes.MIMETYPE_ZIP).entity(so).build(); + } + + /** + * @return Singular type name for the given resource. E.g., + * "ServiceTemplateResource" gets "ServiceTemplate" + */ + public static String getTypeForInstance(Class resClass) { + String res = resClass.getName(); + // Everything between the last "." and before "Resource" is the Type + int dotIndex = res.lastIndexOf('.'); + assert (dotIndex >= 0); + return res.substring(dotIndex + 1, res.length() - "Resource".length()); + } + + /** + * @return Singular type name for the given id. E.g., "ServiceTemplateId" + * gets "ServiceTemplate" + */ + public static String getTypeForAdminId(Class idClass) { + return Util.getEverythingBetweenTheLastDotAndBeforeId(idClass); + } + + /** + * @return Singular type name for given AbstractComponentsResource. E.g, + * "ServiceTemplatesResource" gets "ServiceTemplate" + */ + public static String getTypeForComponentContainer(Class containerClass) { + String res = containerClass.getName(); + // Everything between the last "." and before "sResource" is the Type + int dotIndex = res.lastIndexOf('.'); + assert (dotIndex >= 0); + return res.substring(dotIndex + 1, res.length() - "sResource".length()); + } + + @SuppressWarnings("unchecked") + public static Class getComponentIdClass(String idClassName) { + String pkg = "org.eclipse.winery.common.ids.definitions."; + if (idClassName.contains("Import")) { + // quick hack to handle imports, which reside in their own package + pkg = pkg + "imports."; + } + String fullClassName = pkg + idClassName; + try { + return (Class) Class.forName(fullClassName); + } catch (ClassNotFoundException e) { + // quick hack for Ids local to winery repository + try { + fullClassName = "org.eclipse.winery.repository.datatypes.ids.admin." + idClassName; + return (Class) Class.forName(fullClassName); + } catch (ClassNotFoundException e2) { + String errorMsg = "Could not find id class for component container, " + fullClassName; + Utils.logger.error(errorMsg); + throw new IllegalStateException(errorMsg); + } + } + } + + /** + * Returns a class object for ids of components nested in the given + * AbstractComponentsResource + */ + public static Class getComponentIdClassForComponentContainer(Class containerClass) { + // the name of the id class is the type + "Id" + String idClassName = Utils.getTypeForComponentContainer(containerClass) + "Id"; + + return Utils.getComponentIdClass(idClassName); + } + + public static Class getComponentIdClassForTExtensibleElements(Class clazz) { + // we assume that the clazzName always starts with a T. + // Therefore, we fetch everything after the last dot (plus offest 1) + String idClassName = clazz.getName(); + int dotIndex = idClassName.lastIndexOf('.'); + assert (dotIndex >= 0); + idClassName = idClassName.substring(dotIndex + 2) + "Id"; + + return Utils.getComponentIdClass(idClassName); + } + + + private static final String slashEncoded = Util.URLencode("/"); + + + public static String getURLforPathInsideRepo(String pathInsideRepo) { + // first encode the whole string + String res = Util.URLencode(pathInsideRepo); + // issue: "/" is also encoded. This has to be undone: + res = res.replaceAll(Utils.slashEncoded, "/"); + return res; + } + + + /** + * Shared object to map JSONs + */ + public static final ObjectMapper mapper = new ObjectMapper(); + + + public static String Object2JSON(Object o) { + String res; + try { + res = Utils.mapper.writeValueAsString(o); + } catch (Exception e) { + Utils.logger.error(e.getMessage(), e); + return null; + } + return res; + } + + @SuppressWarnings("unchecked") + public static Class getGenericIdClassForType(String typeIdType) { + Class res; + // quick hack - we only need definitions right now + String pkg = "org.eclipse.winery.repository.datatypes.ids.definitions."; + String className = typeIdType; + className = pkg + className; + try { + res = (Class) Class.forName(className); + } catch (ClassNotFoundException e) { + Utils.logger.error("Could not find id class for id type", e); + res = null; + } + return res; + } + + /** + * @return the absolute path for the given id + */ + public static String getAbsoluteURL(GenericId id) { + return Prefs.INSTANCE.getResourcePath() + "/" + Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(id)); + } + + /** + * @param baseURI the URI from which the path should start + * @param id the generic id to resolve + * + * @return the relative path for the given id + */ + public static String getRelativeURL(URI baseURI, GenericId id) { + String absolutePath = Prefs.INSTANCE.getResourcePath() + "/" + Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(id)); + return baseURI.relativize(URI.create(absolutePath)).toString(); + } + + /** + * @return the absolute path for the given id + */ + public static String getAbsoluteURL(RepositoryFileReference ref) { + return Prefs.INSTANCE.getResourcePath() + "/" + Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(ref)); + } + + public static URI getAbsoluteURI(GenericId id) { + return Utils.createURI(Utils.getAbsoluteURL(id)); + } + + public static String doubleEscapeHTMLAndThenConvertNL2BR(String txt) { + String res = Functions.escapeXml(txt); + res = Functions.escapeXml(res); + res = res.replaceAll("\\n", "
"); + return res; + } + + /** + * This method is similar to {@link + * org.eclipse.winery.common.Util.qname2href()}, but treats winery's + * internal ID model instead of the global TOSCA model + * + * @param id the id to create an a href element for + * @return an a HTML element pointing to the given id + */ + public static String getHREF(TOSCAComponentId id) { + String res = "" + Functions.escapeXml(id.getXmlId().getDecoded()) + ""; + return res; + } + + public static String artifactTypeQName2href(QName qname) { + return Util.qname2href(Prefs.INSTANCE.getResourcePath(), TArtifactType.class, qname); + } + + public static String nodeTypeQName2href(QName qname) { + return Util.qname2href(Prefs.INSTANCE.getResourcePath(), TNodeType.class, qname); + } + + public static String relationshipTypeQName2href(QName qname) { + return Util.qname2href(Prefs.INSTANCE.getResourcePath(), TRelationshipType.class, qname); + } + + public static String policyTypeQName2href(QName qname) { + return Util.qname2href(Prefs.INSTANCE.getResourcePath(), TPolicyType.class, qname); + } + + /** + * Returns the middle part of the package name or the JSP location + * + * @param type the type + * @param separator the separator to be used, "." or "/" + * @return string which can be used "in the middle" of a package or of a + * path to a JSP + */ + public static String getIntermediateLocationStringForType(String type, String separator) { + String location; + if (type.contains("ServiceTemplate")) { + location = "servicetemplates"; + } else { + if (type.contains("TypeImplementation")) { + location = "entitytypeimplementations"; + } else if (type.contains("Type")) { + location = "entitytypes"; + } else if (type.contains("Import")) { + location = "imports"; + } else { + assert (type.contains("Template")); + location = "entitytemplates"; + } + // location now is the super pkg, we have to add a pkg of the type + location = location + separator + type.toLowerCase() + "s"; + } + return location; + } + + /** + * Required by topologyedit.jsp + * + * @return all known nodetype resources + */ + public static Collection getAllNodeTypeResources() { + @SuppressWarnings("unchecked") + Collection res = (Collection) (Collection) new NodeTypesResource().getAll(); + return res; + } + + /** + * Required by topologyedit.jsp + * + * @return all known relation ship type resources + */ + public static Collection getAllRelationshipTypeResources() { + @SuppressWarnings("unchecked") + Collection res = (Collection) (Collection) new RelationshipTypesResource().getAll(); + return res; + } + + /** + * @return the path to the Winery topology modeler. Required by + * functions.tld + */ + public static String getWineryTopologyModelerPath() { + return Prefs.INSTANCE.getWineryTopologyModelerPath(); + } + + /** + * Detect the mime type of the stream. The stream is marked at the beginning + * and reset at the end + * + * @param is the stream + * @param fileName the fileName of the file belonging to the stream + */ + public static String getMimeType(BufferedInputStream bis, String fn) throws IOException { + AutoDetectParser parser = new AutoDetectParser(); + Detector detector = parser.getDetector(); + Metadata md = new Metadata(); + md.add(Metadata.RESOURCE_NAME_KEY, fn); + org.apache.tika.mime.MediaType mediaType = detector.detect(bis, md); + return mediaType.toString(); + } + + + private static final MediaType MEDIATYPE_APPLICATION_OCTET_STREAM = MediaType.valueOf("application/octet-stream"); + + + /** + * Fixes the mediaType if it is too vague (such as application/octet-stream) + * + * @return a more fitting MediaType or the original one if it is appropriate + * enough + */ + public static MediaType getFixedMimeType(BufferedInputStream is, String fileName, MediaType mediaType) { + if (mediaType.equals(Utils.MEDIATYPE_APPLICATION_OCTET_STREAM)) { + // currently, we fix application/octet-stream only + + // TODO: instead of using apache tika, we could hve a user-configured map storing + // * media type + // * file extension + + try { + return MediaType.valueOf(Utils.getMimeType(is, fileName)); + } catch (Exception e) { + Utils.logger.debug("Could not determine mimetype for " + fileName, e); + // just keep the old one + return mediaType; + } + } else { + return mediaType; + } + } + + /** + * Converts the given object to XML. + * + * Used in cases the given element is not annotated with @XmlRoot + * + * We cannot use {@literal Class} as, for + * instance, {@link TConstraint} does not inherit from + * {@link TExtensibleElements} + * + * @param clazz the Class of the passed object, required if obj is null + * @param obj the object to serialize + */ + public static Response getXML(Class clazz, T obj) { + // see commit ab4b5c547619c058990 for an implementation using getJAXBElement, + // which can be directly passed as entity + // the issue is that we want to have a *formatted* XML + // Therefore, we serialize "by hand". + String xml = Utils.getXMLAsString(clazz, obj, false); + + return Response.ok().type(MediaType.TEXT_XML).entity(xml).build(); + } + + public static String getXMLAsString(Class clazz, T obj, boolean includeProcessingInstruction) { + JAXBElement rootElement = Util.getJAXBElement(clazz, obj); + Marshaller m = JAXBSupport.createMarshaller(includeProcessingInstruction); + StringWriter w = new StringWriter(); + try { + m.marshal(rootElement, w); + } catch (JAXBException e) { + Utils.logger.error("Could not put content to string", e); + throw new IllegalStateException(e); + } + String res = w.toString(); + return res; + } + + public static String getXMLAsString(Object obj) { + if (obj instanceof Element) { + // in case the object is a DOM element, we use the DOM functionality + return Util.getXMLAsString((Element) obj); + } else { + return Utils.getXMLAsString(obj, false); + } + } + + public static String getXMLAsString(T obj, boolean includeProcessingInstruction) { + if (obj == null) { + return ""; + } + @SuppressWarnings("unchecked") + Class clazz = (Class) obj.getClass(); + return Utils.getXMLAsString(clazz, obj, includeProcessingInstruction); + } + + public static String getAllXSDElementDefinitionsForTypeAheadSelection() { + Utils.logger.entry(); + try { + return Utils.getAllXSDefinitionsForTypeAheadSelection(XSConstants.ELEMENT_DECLARATION); + } finally { + Utils.logger.exit(); + } + } + + public static String getAllXSDTypeDefinitionsForTypeAheadSelection() { + Utils.logger.entry(); + try { + return Utils.getAllXSDefinitionsForTypeAheadSelection(XSConstants.TYPE_DEFINITION); + } finally { + Utils.logger.exit(); + } + } + + public static String getAllXSDefinitionsForTypeAheadSelection(short type) { + SortedSet allImports = Repository.INSTANCE.getAllTOSCAComponentIds(XSDImportId.class); + + Map> data = new HashMap>(); + + for (XSDImportId id : allImports) { + XSDImportResource resource = new XSDImportResource(id); + Collection allLocalNames = resource.getAllDefinedLocalNames(type); + + Collection list; + if ((list = data.get(id.getNamespace())) == null) { + // list does not yet exist + list = new ArrayList(); + data.put(id.getNamespace(), list); + } + assert (list != null); + + list.addAll(allLocalNames); + } + + ArrayNode rootNode = Utils.mapper.createArrayNode(); + + // ensure ordering in JSON object + Collection allns = new TreeSet(); + allns.addAll(data.keySet()); + + for (Namespace ns : allns) { + Collection localNames = data.get(ns); + if (!localNames.isEmpty()) { + ObjectNode groupEntry = Utils.mapper.createObjectNode(); + rootNode.add(groupEntry); + groupEntry.put("text", ns.getDecoded()); + ArrayNode children = Utils.mapper.createArrayNode(); + groupEntry.put("children", children); + Collection sortedLocalNames = new TreeSet(); + sortedLocalNames.addAll(localNames); + for (String localName : sortedLocalNames) { + String value = "{" + ns.getDecoded() + "}" + localName; + String text = localName; + ObjectNode o = Utils.mapper.createObjectNode(); + o.put("text", text); + o.put("value", value); + children.add(o); + } + } + } + + try { + return Utils.mapper.writeValueAsString(rootNode); + } catch (JsonProcessingException e) { + throw new IllegalStateException("Could not create JSON", e); + } + } + + public static Response getResponseForException(Exception e) { + String msg; + if (e.getCause() != null) { + msg = e.getCause().getMessage(); + } else { + msg = e.getMessage(); + } + Response res = Response.status(Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + return res; + } + + /** + * Returns the stored type for the given template + * + * Goes to the repository to retrieve stored data + * + * @param template the template to determine the type for + */ + // we supress "unchecked" as we use Class.forName + @SuppressWarnings("unchecked") + public static TEntityType getTypeForTemplate(TEntityTemplate template) { + QName type = template.getType(); + + // Possibilities: + // a) try all possibly types whether an appropriate QName exists + // b) derive type class from template class. Determine appropriate resource afterwards. + // We go for b) + + String instanceResourceClassName = template.getClass().toString(); + int idx = instanceResourceClassName.lastIndexOf('.'); + // get everything from ".T", where "." is the last dot + instanceResourceClassName = instanceResourceClassName.substring(idx + 2); + // strip off "Template" + instanceResourceClassName = instanceResourceClassName.substring(0, instanceResourceClassName.length() - "Template".length()); + // add "Type" + instanceResourceClassName += "Type"; + + // an id is required to instantiate the resource + String idClassName = "org.eclipse.winery.common.ids.definitions." + instanceResourceClassName + "Id"; + + String packageName = "org.eclipse.winery.repository.resources.entitytypes." + instanceResourceClassName.toLowerCase() + "s"; + // convert from NodeType to NodeTypesResource + instanceResourceClassName += "Resource"; + instanceResourceClassName = packageName + "." + instanceResourceClassName; + + Utils.logger.debug("idClassName: {}", idClassName); + Utils.logger.debug("className: {}", instanceResourceClassName); + + // Get instance of id class having "type" as id + Class idClass; + try { + idClass = (Class) Class.forName(idClassName); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("Could not determine id class", e); + } + Constructor idConstructor; + try { + idConstructor = idClass.getConstructor(QName.class); + } catch (NoSuchMethodException | SecurityException e) { + throw new IllegalStateException("Could not get QName id constructor", e); + } + TOSCAComponentId typeId; + try { + typeId = idConstructor.newInstance(type); + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + throw new IllegalStateException("Could not instantiate type", e); + } + + // now instantiate the resource, where the type belongs to + Class instanceResourceClass; + try { + instanceResourceClass = (Class) Class.forName(instanceResourceClassName); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("Could not determine component instance resource class", e); + } + Constructor resConstructor; + try { + resConstructor = instanceResourceClass.getConstructor(typeId.getClass()); + } catch (NoSuchMethodException | SecurityException e) { + throw new IllegalStateException("Could not get contructor", e); + } + AbstractComponentInstanceResource typeResource; + try { + typeResource = resConstructor.newInstance(typeId); + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + throw new IllegalStateException("Could not instantiate resoruce", e); + } + + // read the data from the resource and store it + TEntityType entityType = (TEntityType) typeResource.getElement(); + + return entityType; + } + + /** + * referenced by functions.tld + */ + public static Boolean isContainerLocallyAvailable() { + return Prefs.INSTANCE.isContainerLocallyAvailable(); + } + + /** + * referenced by functions.tld + * + * We need the bridge as functions (at tld) require a static method. We did + * not want to put two methods in Prefs and therefore, we put the method + * here. + */ + public static Boolean isRestDocDocumentationAvailable() { + return Prefs.INSTANCE.isRestDocDocumentationAvailable(); + } + + public static boolean isSuccessFulResponse(Response res) { + return Status.fromStatusCode(res.getStatus()).getFamily().equals(Family.SUCCESSFUL); + } + + /** + * Converts the given String to an integer. Fallback if String is a float. + * If String is an invalid number, "0" is returned + */ + public static int convertStringToInt(String number) { + int intTop = 0; + try { + intTop = Integer.parseInt(number); + } catch (NumberFormatException e) { + try { + float floatTop = Float.parseFloat(number); + intTop = Math.round(floatTop); + } catch (NumberFormatException e2) { + // do nothing + } + } + + return intTop; + } + + /** + * Checks whether a given resource (with absolute URL!) is available with a + * HEAD request on it. + */ + public static boolean isResourceAvailable(String path) { + Client client = Client.create(); + WebResource wr = client.resource(path); + ClientResponse response = wr.head(); + boolean res = (response.getClientResponseStatus().getFamily().equals(Family.SUCCESSFUL)); + return res; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/AbstractRepository.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/AbstractRepository.java new file mode 100644 index 0000000000..6417df6908 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/AbstractRepository.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; + +import javax.ws.rs.core.MediaType; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.io.IOUtils; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.repository.Constants; +import org.eclipse.winery.repository.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides basic implementations for {@link IRepository} + */ +public abstract class AbstractRepository implements IRepository { + + private static final Logger logger = LoggerFactory.getLogger(AbstractRepository.class); + + + /** + * + * @param ref the file reference to store the mime type for + * @return a reference to the file holding the mime type + */ + private RepositoryFileReference getMimeFileRef(RepositoryFileReference ref) { + String fileName = ref.getFileName() + Constants.SUFFIX_MIMETYPE; + RepositoryFileReference mimeFileRef = new RepositoryFileReference(ref.getParent(), fileName); + return mimeFileRef; + } + + /** + * {@inheritDoc} + * + * This is a simple implementation using the information put by + * setMimeType(RepositoryFileReference ref) or determining the mime type + * using Utils.getMimeType. If the latter is done, the mime type is + * persisted using setMimeType + */ + @Override + public String getMimeType(RepositoryFileReference ref) throws IOException { + RepositoryFileReference mimeFileRef = this.getMimeFileRef(ref); + String mimeType; + if (this.exists(mimeFileRef)) { + InputStream is = this.newInputStream(mimeFileRef); + mimeType = IOUtils.toString(is, "UTF-8"); + is.close(); + } else { + // repository has been manipulated manually, + // create mimetype information + mimeType = null; + try (InputStream is = this.newInputStream(ref); + BufferedInputStream bis = new BufferedInputStream(is);) { + mimeType = Utils.getMimeType(bis, ref.getFileName()); + } + if (mimeType != null) { + // successful execution + this.setMimeType(ref, MediaType.valueOf(mimeType)); + } else { + AbstractRepository.logger.debug("Could not determine mimetype"); + } + } + return mimeType; + } + + /** + * Stores the mime type of the given file reference in a separate file + * + * This method calls putContentToFile(), where the filename is appended with + * Constants.SUFFIX_MIMETYPE and a null mime type. The latter indicates that + * no "normal" file is stored. + * + * @param ref the file reference + * @param mediaType the mimeType + */ + protected void setMimeType(RepositoryFileReference ref, MediaType mediaType) throws IOException { + RepositoryFileReference mimeFileRef = this.getMimeFileRef(ref); + this.putContentToFile(mimeFileRef, mediaType.toString(), null); + } + + @Override + public Date getConfigurationLastUpdate(GenericId id) { + RepositoryFileReference ref = BackendUtils.getRefOfConfiguration(id); + return this.getLastUpdate(ref); + } + + @Override + public Configuration getConfiguration(GenericId id) { + RepositoryFileReference ref = BackendUtils.getRefOfConfiguration(id); + return this.getConfiguration(ref); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/BackendUtils.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/BackendUtils.java new file mode 100644 index 0000000000..51e9652ca2 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/BackendUtils.java @@ -0,0 +1,891 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.nio.file.attribute.FileTime; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.SortedSet; + +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.namespace.QName; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.apache.xerces.impl.dv.XSSimpleType; +import org.apache.xerces.impl.xs.XSImplementationImpl; +import org.apache.xerces.xs.XSComplexTypeDefinition; +import org.apache.xerces.xs.XSElementDeclaration; +import org.apache.xerces.xs.XSImplementation; +import org.apache.xerces.xs.XSLoader; +import org.apache.xerces.xs.XSModel; +import org.apache.xerces.xs.XSModelGroup; +import org.apache.xerces.xs.XSObjectList; +import org.apache.xerces.xs.XSParticle; +import org.apache.xerces.xs.XSTerm; +import org.apache.xerces.xs.XSTypeDefinition; +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.common.ids.IdUtil; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.definitions.EntityTypeId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.common.ids.definitions.imports.GenericImportId; +import org.eclipse.winery.common.ids.elements.PlansId; +import org.eclipse.winery.common.ids.elements.TOSCAElementId; +import org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKV; +import org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKVList; +import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition; +import org.eclipse.winery.model.tosca.Definitions; +import org.eclipse.winery.model.tosca.ObjectFactory; +import org.eclipse.winery.model.tosca.TEntityType; +import org.eclipse.winery.model.tosca.TEntityType.PropertiesDefinition; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.repository.Constants; +import org.eclipse.winery.repository.JAXBSupport; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.constants.Filename; +import org.eclipse.winery.repository.datatypes.ids.admin.AdminId; +import org.eclipse.winery.repository.datatypes.ids.elements.VisualAppearanceId; +import org.eclipse.winery.repository.resources.AbstractComponentsResource; +import org.eclipse.winery.repository.resources.IHasTypeReference; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources.admin.NamespacesResource; +import org.eclipse.winery.repository.resources.entitytypes.TopologyGraphElementEntityTypeResource; +import org.eclipse.winery.repository.resources.imports.xsdimports.XSDImportsResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.ls.LSInput; + +/** + * Contains generic utility functions for the Backend + * + * Contains everything that is useful for our ids etc. Does not contain + * anything that has to do with resources + */ +public class BackendUtils { + + private static final Logger logger = LoggerFactory.getLogger(BackendUtils.class); + + + /** + * Deletes given file/dir and returns appropriate response code + */ + public static Response delete(GenericId id) { + if (!Repository.INSTANCE.exists(id)) { + return Response.status(Status.NOT_FOUND).build(); + } + try { + Repository.INSTANCE.forceDelete(id); + } catch (IOException e) { + BackendUtils.logger.error(e.getMessage(), e); + return Response.serverError().entity(e.getMessage()).build(); + } + return Response.noContent().build(); + } + + /** + * Deletes given file and returns appropriate response code + */ + public static Response delete(RepositoryFileReference ref) { + if (!Repository.INSTANCE.exists(ref)) { + return Response.status(Status.NOT_FOUND).build(); + } + try { + Repository.INSTANCE.forceDelete(ref); + } catch (IOException e) { + BackendUtils.logger.error(e.getMessage(), e); + return Response.serverError().entity(e.getMessage()).build(); + } + return Response.ok().build(); + } + + /** + * Generates given TOSCA element and returns appropriate response code
+ * + * In the case of an existing resource, the other possible return code is + * 302. This code has no Status constant, therefore we use Status.CONFLICT, + * which is also possible. + * + * @return
    + *
  • + *
      + *
    • Status.CREATED (201) if the resource has been created,
    • + *
    • Status.CONFLICT if the resource already exists,
    • + *
    • Status.INTERNAL_SERVER_ERROR (500) if something went wrong
    • + *
    + *
  • + *
  • URI: the absolute URI of the newly created resource
  • + *
+ */ + public static ResourceCreationResult create(GenericId id) { + ResourceCreationResult res = new ResourceCreationResult(); + if (Repository.INSTANCE.exists(id)) { + // res.setStatus(302); + res.setStatus(Status.CONFLICT); + } else { + if (Repository.INSTANCE.flagAsExisting(id)) { + res.setStatus(Status.CREATED); + // @formatter:off + // This method is a generic method + // We cannot return an "absolute" URL as the URL is always + // relative to the caller + // Does not work: String path = Prefs.INSTANCE.getResourcePath() + // + "/" + + // Utils.getURLforPathInsideRepo(id.getPathInsideRepo()); + // We distinguish between two cases: TOSCAcomponentId and + // TOSCAelementId + // @formatter:on + String path; + if (id instanceof TOSCAComponentId) { + // here, we return namespace + id, as it is only possible to + // post on the TOSCA component*s* resource to create an + // instance of a TOSCA component + TOSCAComponentId tcId = (TOSCAComponentId) id; + path = tcId.getNamespace().getEncoded() + "/" + tcId.getXmlId().getEncoded() + "/"; + } else { + assert (id instanceof TOSCAElementId); + // We just return the id as we assume that only the parent + // of this id may create sub elements + path = id.getXmlId().getEncoded() + "/"; + } + // we have to encode it twice to get correct URIs + path = Utils.getURLforPathInsideRepo(path); + URI uri = Utils.createURI(path); + res.setUri(uri); + res.setId(id); + } else { + res.setStatus(Status.INTERNAL_SERVER_ERROR); + } + } + return res; + } + + /** + * + * Sends the file if modified and "not modified" if not modified future work + * may put each file with a unique id in a separate folder in tomcat * use + * that static URL for each file * if file is modified, URL of file changes + * * -> client always fetches correct file + * + * additionally "Vary: Accept" header is added (enables caching of the + * response) + * + * method header for calling method public
+ * Response getXY(@HeaderParam("If-Modified-Since") String modified) {...} + * + * + * @param ref references the file to be send + * @param modified - HeaderField "If-Modified-Since" - may be "null" + * @return Response to be sent to the client + */ + public static Response returnRepoPath(RepositoryFileReference ref, String modified) { + return BackendUtils.returnRefAsResponseBuilder(ref, modified).build(); + } + + /** + * @return true if given fileDate is newer then the modified date (or + * modified is null) + */ + public static boolean isFileNewerThanModifiedDate(long millis, String modified) { + if (modified == null) { + return true; + } + + Date modifiedDate = null; + + assert (Locale.getDefault() == Locale.ENGLISH); + try { + modifiedDate = DateUtils.parseDate(modified, org.apache.http.impl.cookie.DateUtils.DEFAULT_PATTERNS); + } catch (ParseException e) { + BackendUtils.logger.error(e.getMessage(), e); + } + + if (modifiedDate != null) { + // modifiedDate does not carry milliseconds, but fileDate does + // therefore we have to do a range-based comparison + if ((millis - modifiedDate.getTime()) < DateUtils.MILLIS_PER_SECOND) { + return false; + } + } + + return true; + } + + /** + * This is not repository specific, but we leave it close to the only caller + * + * If the passed ref is newer than the modified date (or the modified date + * is null), an OK response with an inputstream pointing to the path is + * returned + */ + private static ResponseBuilder returnRefAsResponseBuilder(RepositoryFileReference ref, String modified) { + if (!Repository.INSTANCE.exists(ref)) { + return Response.status(Status.NOT_FOUND); + } + + FileTime lastModified; + try { + lastModified = Repository.INSTANCE.getLastModifiedTime(ref); + } catch (IOException e1) { + BackendUtils.logger.debug("Could not get lastModifiedTime", e1); + return Response.serverError(); + } + + // do we really need to send the file or can send "not modified"? + if (!BackendUtils.isFileNewerThanModifiedDate(lastModified.toMillis(), modified)) { + return Response.status(Status.NOT_MODIFIED); + } + + ResponseBuilder res; + try { + res = Response.ok(Repository.INSTANCE.newInputStream(ref)); + } catch (IOException e) { + BackendUtils.logger.debug("Could not open input stream", e); + return Response.serverError(); + } + res = res.lastModified(new Date(lastModified.toMillis())); + // vary:accept header is always set to be safe + res = res.header(HttpHeaders.VARY, HttpHeaders.ACCEPT); + // determine and set MIME content type + try { + res = res.header(HttpHeaders.CONTENT_TYPE, Repository.INSTANCE.getMimeType(ref)); + } catch (IOException e) { + BackendUtils.logger.debug("Could not determine mime type", e); + return Response.serverError(); + } + return res; + } + + /** + * Updates the given property in the given configuration. Currently always + * returns "no content", because the underlying class does not report any + * errors during updating.
+ * + * If null or "" is passed as value, the property is cleared + * + * @return Status.NO_CONTENT + */ + public static Response updateProperty(Configuration configuration, String property, String val) { + if (StringUtils.isBlank(val)) { + configuration.clearProperty(property); + } else { + configuration.setProperty(property, val); + } + return Response.noContent().build(); + } + + /** + * Persists the resource and returns appropriate response + */ + public static Response persist(IPersistable res) { + Response r; + try { + res.persist(); + } catch (IOException e) { + BackendUtils.logger.debug("Could not persist resource", e); + r = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build(); + return r; + } + r = Response.noContent().build(); + return r; + } + + /** + * Writes data to file. Replaces the file's content with the given content. + * The file does not need to exist + * + * @param ref Reference to the File to write to (overwrite) + * @param content the data to write + * @return a JAX-RS Response containing the result. NOCONTENT if successful, + * InternalSeverError otherwise + */ + public static Response putContentToFile(RepositoryFileReference ref, String content, MediaType mediaType) { + try { + Repository.INSTANCE.putContentToFile(ref, content, mediaType); + } catch (IOException e) { + BackendUtils.logger.error(e.getMessage(), e); + return Response.serverError().entity(e.getMessage()).build(); + } + return Response.noContent().build(); + } + + public static Response putContentToFile(RepositoryFileReference ref, InputStream inputStream, MediaType mediaType) { + try { + Repository.INSTANCE.putContentToFile(ref, inputStream, mediaType); + } catch (IOException e) { + BackendUtils.logger.error(e.getMessage(), e); + return Response.serverError().entity(e.getMessage()).build(); + } + return Response.noContent().build(); + } + + public static T getTOSCAcomponentId(Class idClass, String qnameStr) { + QName qname = QName.valueOf(qnameStr); + return BackendUtils.getTOSCAcomponentId(idClass, qname.getNamespaceURI(), qname.getLocalPart(), false); + } + + public static T getTOSCAcomponentId(Class idClass, QName qname) { + // we got two implementation possibilities: one is to directly use the + // QName constructor, + // the other is to use a namespace, localname, urlencoded constructor + // we opt for the latter one, which forces the latter constructor to + // exist at all ids + return BackendUtils.getTOSCAcomponentId(idClass, qname.getNamespaceURI(), qname.getLocalPart(), false); + } + + public static T getTOSCAcomponentId(Class idClass, String namespace, String id, boolean URLencoded) { + Constructor constructor; + try { + constructor = idClass.getConstructor(String.class, String.class, boolean.class); + } catch (NoSuchMethodException | SecurityException e) { + BackendUtils.logger.error("Could not get constructor for id " + idClass.getName(), e); + throw new IllegalStateException(e); + } + T tcId; + try { + tcId = constructor.newInstance(namespace, id, URLencoded); + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + BackendUtils.logger.error("Could not create id instance", e); + throw new IllegalStateException(e); + } + return tcId; + } + + /** + * @param id the id to determine the namespace of the parent for + * @return the namespace of the first TOSCAcomponentId found in the ID + * hierarchy + */ + public static Namespace getNamespace(TOSCAElementId id) { + GenericId parent = id.getParent(); + while (!(parent instanceof TOSCAComponentId)) { + parent = parent.getParent(); + } + return ((TOSCAComponentId) parent).getNamespace(); + } + + public static String getName(TOSCAComponentId instanceId) { + // TODO: Here is a performance issue as we don't use caching or a database + // Bad, but without performance loss: Use "text = instanceId.getXmlId().getDecoded();" + TExtensibleElements instanceElement = AbstractComponentsResource.getComponentInstaceResource(instanceId).getElement(); + return ModelUtilities.getNameWithIdFallBack(instanceElement); + } + +/** + * Do not use this for creating URLs. Use + * + * {@link org.eclipse.winery.repository.Utils.getURLforPathInsideRepo(String)} + * + * or + * + * {@link org.eclipse.winery.repository.Utils.getAbsoluteURL(GenericId) + * instead. + * + * @return the path starting from the root element to the current element. + * Separated by "/", URLencoded, but not double encoded. With + * trailing slash if sub-resources can exist + * @throws IllegalStateException if id is of an unknown subclass of id + */ + public static String getPathInsideRepo(GenericId id) { + if (id == null) { + throw new NullPointerException("id is null"); + } + + // for creating paths see also org.eclipse.winery.repository.Utils.getIntermediateLocationStringForType(String, String) + // and org.eclipse.winery.common.Util.getRootPathFragment(Class) + if (id instanceof AdminId) { + return "admin/" + id.getXmlId().getEncoded() + "/"; + } else if (id instanceof GenericImportId) { + GenericImportId i = (GenericImportId) id; + String res = "imports/"; + res = res + Util.URLencode(i.getType()) + "/"; + res = res + i.getNamespace().getEncoded() + "/"; + res = res + i.getXmlId().getEncoded() + "/"; + return res; + } else if (id instanceof TOSCAComponentId) { + return IdUtil.getPathFragment(id); + } else if (id instanceof TOSCAElementId) { + // we cannot reuse IdUtil.getPathFragment(id) as this TOSCAelementId + // might be nested in an AdminId + return BackendUtils.getPathInsideRepo(id.getParent()) + id.getXmlId().getEncoded() + "/"; + } else { + throw new IllegalStateException("Unknown subclass of GenericId " + id.getClass()); + } + } + +/** + * Do not use this for creating URLs. Use + * + * {@link org.eclipse.winery.repository.Utils.getURLforPathInsideRepo(String)} + * + * or + * + * {@link org.eclipse.winery.repository.Utils.getAbsoluteURL(GenericId) + * instead. + * + * @return the path starting from the root element to the current element. + * Separated by "/", parent URLencoded. Without trailing slash. + */ + public static String getPathInsideRepo(RepositoryFileReference ref) { + return BackendUtils.getPathInsideRepo(ref.getParent()) + ref.getFileName(); + } + + /** + * Returns the reference to the definitions XML storing the TOSCA for the + * given id + * + * @param id the id to lookup + * @return the reference + */ + public static RepositoryFileReference getRefOfDefinitions(TOSCAComponentId id) { + String name = Util.getTypeForComponentId(id.getClass()); + name = name + Constants.SUFFIX_TOSCA_DEFINITIONS; + RepositoryFileReference ref = new RepositoryFileReference(id, name); + return ref; + } + + /** + * Returns the reference to the properties file storing the TOSCA + * information for the given id + * + * @param id the id to lookup + * @return the reference + */ + public static RepositoryFileReference getRefOfConfiguration(GenericId id) { + String name; + // Hack to determine file name + if (id instanceof TOSCAComponentId) { + name = Util.getTypeForComponentId(((TOSCAComponentId) id).getClass()); + name = name + Constants.SUFFIX_PROPERTIES; + } else if (id instanceof AdminId) { + name = Utils.getTypeForAdminId(((AdminId) id).getClass()); + name = name + Constants.SUFFIX_PROPERTIES; + } else { + assert (id instanceof TOSCAElementId); + TOSCAElementId tId = (TOSCAElementId) id; + if (tId instanceof PlansId) { + name = Filename.FILENAME_PROPERTIES_PLANCONTAINER; + } else if (tId instanceof VisualAppearanceId) { + // quick hack for special name here + name = Filename.FILENAME_PROPERTIES_VISUALAPPEARANCE; + } else { + name = Util.getTypeForElementId(tId.getClass()) + Constants.SUFFIX_PROPERTIES; + } + } + + RepositoryFileReference ref = new RepositoryFileReference(id, name); + return ref; + } + + /** + * @param qNameOfTheType the QName of the type, where all TOSCAComponentIds, + * where the associated element points to the type + * @param clazz the Id class of the entities to discover + */ + public static Collection getAllElementsRelatedWithATypeAttribute(Class clazz, QName qNameOfTheType) { + // we do not use any database system, + // therefore we have to crawl through each node type implementation by ourselves + SortedSet allIds = Repository.INSTANCE.getAllTOSCAComponentIds(clazz); + Collection res = new HashSet<>(); + for (X id : allIds) { + IHasTypeReference resource; + try { + resource = (IHasTypeReference) AbstractComponentsResource.getComponentInstaceResource(id); + } catch (ClassCastException e) { + String error = "Requested following the type, but the component instance does not implmenet IHasTypeReference"; + BackendUtils.logger.error(error); + throw new IllegalStateException(error); + } + // The resource may have been freshly initialized due to existence of a directory + // then it has no node type assigned leading to ntiRes.getType() being null + // we ignore this error here + if (qNameOfTheType.equals(resource.getType())) { + // the component instance is an implementation of the associated node type + res.add(id); + } + } + return res; + } + + /** + * Creates a new TDefintions element wrapping a TOSCA Component instance. + * The namespace of the tosca component is used as namespace and + * {@code winery-defs-for-} concatenated with the (unique) ns prefix and + * idOfContainedElement is used as id + * + * @param toscAcomponentId the id of the element the wrapper is used for + * + * @return a definitions element prepared for wrapping a TOSCA component + * instance + */ + public static Definitions createWrapperDefinitions(TOSCAComponentId tcId) { + ObjectFactory of = new ObjectFactory(); + Definitions defs = of.createDefinitions(); + + // set target namespace + // an internal namespace is not possible + // a) tPolicyTemplate and tArtfactTemplate do NOT support the "targetNamespace" attribute + // b) the imports statement would look bad as it always imported the artificial namespace + defs.setTargetNamespace(tcId.getNamespace().getDecoded()); + + // set a unique id to create a valid definitions element + // we do not use UUID to be more human readable and deterministic (for debugging) + String prefix = NamespacesResource.getPrefix(tcId.getNamespace()); + String elId = tcId.getXmlId().getDecoded(); + String id = "winery-defs-for_" + prefix + "-" + elId; + defs.setId(id); + + return defs; + } + + /** + * @throws IOException if content could not be updated in the repository + * @throws IllegalStateException if an JAXBException occurred. This should + * never happen. + */ + public static void persist(Object o, RepositoryFileReference ref, MediaType mediaType) throws IOException { + // We assume that the object is not too large + // Otherwise, http://io-tools.googlecode.com/svn/www/easystream/apidocs/index.html should be used + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Marshaller m; + try { + m = JAXBSupport.createMarshaller(true); + m.marshal(o, out); + } catch (JAXBException e) { + BackendUtils.logger.error("Could not put content to file", e); + throw new IllegalStateException(e); + } + byte[] data = out.toByteArray(); + ByteArrayInputStream in = new ByteArrayInputStream(data); + // this may throw an IOExcpetion. We propagate this exception. + Repository.INSTANCE.putContentToFile(ref, in, mediaType); + } + + /** + * Updates the color if the color is not yet existent + * + * @param name the name of the component. Used as basis for a generated + * color + * @param qname the QName of the color attribute + * @param otherAttributes the plain "XML" attributes. They are used to check + * @param res + */ + public static String getColorAndSetDefaultIfNotExisting(String name, QName qname, Map otherAttributes, TopologyGraphElementEntityTypeResource res) { + String colorStr = otherAttributes.get(qname); + if (colorStr == null) { + colorStr = Util.getColor(name); + otherAttributes.put(qname, colorStr); + BackendUtils.persist(res); + } + return colorStr; + } + + /** + * + * @param tcId The element type id to get the location for + * @param uri uri to use if in XML export mode, null if in CSAR export mode + * @param wrapperElementLocalName the local name of the wrapper element + * @return + */ + public static String getImportLocationForWinerysPropertiesDefinitionXSD(EntityTypeId tcId, URI uri, String wrapperElementLocalName) { + String loc = BackendUtils.getPathInsideRepo(tcId); + loc = loc + "propertiesdefinition/"; + loc = Utils.getURLforPathInsideRepo(loc); + if (uri == null) { + loc = loc + wrapperElementLocalName + ".xsd"; + // for the import later, we need "../" in front + loc = "../" + loc; + } else { + loc = uri + loc + "xsd"; + } + return loc; + } + + /** + * @param ref the file to read from + */ + public static XSModel getXSModel(final RepositoryFileReference ref) { + if (ref == null) { + return null; + } + final InputStream is; + try { + is = Repository.INSTANCE.newInputStream(ref); + } catch (IOException e) { + BackendUtils.logger.debug("Could not create input stream", e); + return null; + } + + // we rely on xerces to parse the XSD + // idea based on http://stackoverflow.com/a/5165177/873282 + XSImplementation impl = new XSImplementationImpl(); + XSLoader schemaLoader = impl.createXSLoader(null); + + // minimal LSInput implementation sufficient for XSLoader in Oracle's JRE7 + LSInput input = new LSInput() { + + @Override + public void setSystemId(String systemId) { + } + + @Override + public void setStringData(String stringData) { + } + + @Override + public void setPublicId(String publicId) { + } + + @Override + public void setEncoding(String encoding) { + } + + @Override + public void setCharacterStream(Reader characterStream) { + } + + @Override + public void setCertifiedText(boolean certifiedText) { + } + + @Override + public void setByteStream(InputStream byteStream) { + } + + @Override + public void setBaseURI(String baseURI) { + } + + @Override + public String getSystemId() { + return null; + } + + @Override + public String getStringData() { + return null; + } + + @Override + public String getPublicId() { + return BackendUtils.getPathInsideRepo(ref); + } + + @Override + public String getEncoding() { + return "UTF-8"; + } + + @Override + public Reader getCharacterStream() { + try { + return new InputStreamReader(is, "UTF-8"); + } catch (UnsupportedEncodingException e) { + System.out.println("exeption"); + throw new IllegalStateException("UTF-8 is unkown", e); + } + } + + @Override + public boolean getCertifiedText() { + return false; + } + + @Override + public InputStream getByteStream() { + return null; + } + + @Override + public String getBaseURI() { + return null; + } + }; + XSModel model = schemaLoader.load(input); + return model; + } + + /** + * Derives Winery's Properties Definition from an existing properties + * definition + * + * @param ci the entity type to try to modify the WPDs + * @param errors the list to add errors to + */ + public static void deriveWPD(TEntityType ci, List errors) { + BackendUtils.logger.trace("deriveWPD"); + PropertiesDefinition propertiesDefinition = ci.getPropertiesDefinition(); + QName element = propertiesDefinition.getElement(); + if (element == null) { + BackendUtils.logger.debug("only works for an element definition, not for types"); + } else { + BackendUtils.logger.debug("Looking for the definition of {" + element.getNamespaceURI() + "}" + element.getLocalPart()); + // fetch the XSD defining the element + XSDImportsResource importsRes = new XSDImportsResource(); + Map mapFromLocalNameToXSD = importsRes.getMapFromLocalNameToXSD(element.getNamespaceURI(), false); + RepositoryFileReference ref = mapFromLocalNameToXSD.get(element.getLocalPart()); + if (ref == null) { + String msg = "XSD not found for " + element.getNamespaceURI() + " / " + element.getLocalPart(); + BackendUtils.logger.debug(msg); + errors.add(msg); + return; + } + + XSModel xsModel = BackendUtils.getXSModel(ref); + XSElementDeclaration elementDeclaration = xsModel.getElementDeclaration(element.getLocalPart(), element.getNamespaceURI()); + if (elementDeclaration == null) { + String msg = "XSD model claimed to contain declaration for {" + element.getNamespaceURI() + "}" + element.getLocalPart() + ", but it did not."; + BackendUtils.logger.debug(msg); + errors.add(msg); + return; + } + + // go through the XSD definition and + XSTypeDefinition typeDefinition = elementDeclaration.getTypeDefinition(); + if (typeDefinition instanceof XSComplexTypeDefinition) { + XSComplexTypeDefinition cTypeDefinition = (XSComplexTypeDefinition) typeDefinition; + XSParticle particle = cTypeDefinition.getParticle(); + if (particle == null) { + BackendUtils.logger.debug("XSD does not follow the requirements put by winery: Complex type does not contain particles"); + } else { + XSTerm term = particle.getTerm(); + if (term instanceof XSModelGroup) { + XSModelGroup modelGroup = (XSModelGroup) term; + if (modelGroup.getCompositor() == XSModelGroup.COMPOSITOR_SEQUENCE) { + XSObjectList particles = modelGroup.getParticles(); + int len = particles.getLength(); + boolean everyThingIsASimpleType = true; + PropertyDefinitionKVList list = new PropertyDefinitionKVList(); + if (len != 0) { + for (int i = 0; i < len; i++) { + XSParticle innerParticle = (XSParticle) particles.item(i); + XSTerm innerTerm = innerParticle.getTerm(); + if (innerTerm instanceof XSElementDeclaration) { + XSElementDeclaration innerElementDeclaration = (XSElementDeclaration) innerTerm; + String name = innerElementDeclaration.getName(); + XSTypeDefinition innerTypeDefinition = innerElementDeclaration.getTypeDefinition(); + if (innerTypeDefinition instanceof XSSimpleType) { + XSSimpleType xsSimpleType = (XSSimpleType) innerTypeDefinition; + String typeNS = xsSimpleType.getNamespace(); + String typeName = xsSimpleType.getName(); + if (typeNS.equals(XMLConstants.W3C_XML_SCHEMA_NS_URI)) { + PropertyDefinitionKV def = new PropertyDefinitionKV(); + def.setKey(name); + // convention at WPD: use "xsd" as prefix for XML Schema Definition + def.setType("xsd:" + typeName); + list.add(def); + } else { + everyThingIsASimpleType = false; + break; + } + } else { + everyThingIsASimpleType = false; + break; + } + } else { + everyThingIsASimpleType = false; + break; + } + } + } + if (everyThingIsASimpleType) { + // everything went allright, we can add a WPD + WinerysPropertiesDefinition wpd = new WinerysPropertiesDefinition(); + wpd.setIsDerivedFromXSD(Boolean.TRUE); + wpd.setElementName(element.getLocalPart()); + wpd.setNamespace(element.getNamespaceURI()); + wpd.setPropertyDefinitionKVList(list); + ModelUtilities.replaceWinerysPropertiesDefinition(ci, wpd); + BackendUtils.logger.debug("Successfully generated WPD"); + } else { + BackendUtils.logger.debug("XSD does not follow the requirements put by winery: Not all types in the sequence are simple types"); + } + } else { + BackendUtils.logger.debug("XSD does not follow the requirements put by winery: Model group is not a sequence"); + } + } else { + BackendUtils.logger.debug("XSD does not follow the requirements put by winery: Not a model group"); + } + } + } else { + BackendUtils.logger.debug("XSD does not follow the requirements put by winery: No Complex Type Definition"); + } + } + } + + /** + * Returns all components available of the given id type + * + * Similar functionality as {@link + * org.eclipse.winery.repository.backend.IGenericRepository. + * getAllTOSCAComponentIds(Class)}, but it crawls through the repository + * + * This method is required as we do not use a database. + * + * @param idClass class of the Ids to search for + * @return empty set if no ids are available + */ + public SortedSet getAllTOSCAElementIds(Class idClass) { + throw new IllegalStateException("Not yet implemented"); + + /* + Implementation idea: + * switch of instance of idClass + * nodetemplate / relationshiptemplate -> fetch all service templates -> crawl through topology -> add all to res + * req/cap do as above, but inspect nodetemplate + * (other special handlings; check spec where each type can be linked from) + */ + } + + /** + * Converts the given collection of TOSCA Component Ids to a collection of + * QNames by using the getQName() method. + * + * This is required for QNameChooser.tag + */ + public static Collection convertTOSCAComponentIdCollectionToQNameCollection(Collection col) { + Collection res = new ArrayList<>(); + for (TOSCAComponentId id : col) { + res.add(id.getQName()); + } + return res; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IGenericRepository.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IGenericRepository.java new file mode 100644 index 0000000000..9e7ba6635f --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IGenericRepository.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.attribute.FileTime; +import java.util.Collection; +import java.util.Date; +import java.util.SortedSet; + +import javax.ws.rs.core.MediaType; + +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.common.ids.elements.TOSCAElementId; +import org.eclipse.winery.common.interfaces.IWineryRepositoryCommon; + +/** + * Enables access to the winery repository via Ids defined in package + * {@link org.eclipse.winery.common.ids} + * + * In contrast to {@link org.eclipse.winery.repository.backend.IRepository}, + * this is NOT dependent on a particular storage format for the properties. + * These two classes exist to make the need for reengineering explicit. + * + * This is a first attempt to offer methods via GenericId. It might happen, that + * methods, where GenericIds make sense, are simply added to "IWineryRepository" + * instead of being added here. + * + * The ultimate goal is to get rid of this class and to have + * IWineryRepositoryCommon only. + * + * Currently, this class is used internally only + */ +interface IGenericRepository extends IWineryRepositoryCommon { + + /** + * Flags the given TOSCA element as existing. The resources itself create + * appropriate data files. + * + * Pre-Condition: !exists(id)
+ * Post-Condition: exists(id) + * + * Typically, the given TOSCA element is created if a configuration is asked + * for + * + * @param id + * @return + */ + public boolean flagAsExisting(GenericId id); + + /** + * Checks whether the associated TOSA element exists + * + * @param id the id to check + * @return true iff the TOSCA element belonging to the given ID exists + */ + public boolean exists(GenericId id); + + /** + * Deletes the referenced object from the repository + * + * @param ref + */ + public void forceDelete(RepositoryFileReference ref) throws IOException; + + /** + * @param ref reference to check + * @return true if the file associated with the given reference exists + */ + public boolean exists(RepositoryFileReference ref); + + /** + * Puts the given content to the given file. Replaces existing content. + * + * If the parent of the reference does not exist, it is created. + * + * @param ref the reference to the file. Must not be null. + * @param content the content to put into the file. Must not be null. + * @param mediaType the media type of the file. Must not be null. + * + * @throws IOException if something goes wrong + */ + public void putContentToFile(RepositoryFileReference ref, String content, MediaType mediaType) throws IOException; + + /** + * Puts the given content to the given file. Replaces existing content. + * + * If the parent of the reference does not exist, it is created. + * + * @param ref the reference to the file + * @param content the content to put into the file + * @throws IOException if something goes wrong + */ + public void putContentToFile(RepositoryFileReference ref, InputStream inputStream, MediaType mediaType) throws IOException; + + /** + * Creates an opened inputStream of the contents referenced by ref. The + * stream has to be closed by the caller. + * + * @param ref the reference to the file + * @return an inputstream + * @throws IOException if something goes wrong + */ + public InputStream newInputStream(RepositoryFileReference ref) throws IOException; + + /** + * Returns the size of the file referenced by ref + * + * @param ref a refernce to the file stored in the repository + * @return the size in bytes + * @throws IOException if something goes wrong + */ + long getSize(RepositoryFileReference ref) throws IOException; + + /** + * Returns the last modification time of the entry. + * + * @param ref the reference to the file + * @return the time of the last modification + * @throws IOException if something goes wrong + */ + FileTime getLastModifiedTime(RepositoryFileReference ref) throws IOException; + + /** + * Returns the mimetype belonging to the reference. + * + * @param ref the reference to the file + * @return the mimetype as string + * @throws IOException if something goes wrong + * @throws IllegalStateException if an internal error occurs, which is not + * an IOException + */ + String getMimeType(RepositoryFileReference ref) throws IOException; + + /** + * @return the last change date of the file belonging to the given + * reference. NULL if the associated file does not exist. + */ + Date getLastUpdate(RepositoryFileReference ref); + + /** + * Returns all components available of the given id type + * + * @param idClass class of the Ids to search for + * @return empty set if no ids are available + */ + public SortedSet getAllTOSCAComponentIds(Class idClass); + + /** + * Returns the set of all ids nested in the given reference + * + * The generated Ids are linked as child to the id associated to the given + * reference + * + * Required for getting plans nested in a service template: plans are nested + * below the PlansOfOneServiceTemplateId + * + * @param ref a reference to the TOSCA element to be checked. The path + * belonging to this element is checked. + * @param idClass + * @return the set of Ids nested in the given reference. Empty set if there + * are no or the reference itself does not exist. + */ + public SortedSet getNestedIds(GenericId ref, Class idClass); + + /** + * Returns the set of files nested in the given reference + */ + public SortedSet getContainedFiles(GenericId id); + + /** + * Returns all namespaces used by all known TOSCA components + */ + public Collection getUsedNamespaces(); + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IRepository.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IRepository.java new file mode 100644 index 0000000000..cb9560b434 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IRepository.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend; + +import java.util.Date; + +import org.apache.commons.configuration.Configuration; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.ids.GenericId; + +/** + * Provides interface to the backend. + * + * Currently a file-based backend is implemented. In the future, a git-based or + * a database-based backend is possible. + * + * The properties are managed by org.apache.commons.configuration. In case a new + * backend is added, the appropriate implementation of + * org.apache.commons.configuration.AbstrctConfiguration has to be chosen. + * + */ +public interface IRepository extends IGenericRepository { + + /** + * Returns the configuration of the specified id + * + * If the associated TOSCA element does not exist, an empty configuration is + * returned. That means, the associated TOSCA element is created (SIDE + * EFFECT) + * + * The returned configuration ensures that autoSave is activated + * + * @param id may be a reference to a TOSCAcomponent or to a nested + * TOSCAelement + * @return a Configuration, where isAutoSave == true + */ + Configuration getConfiguration(GenericId id); + + /** + * Enables resources to define additional properties. Currently used for + * tags. + * + * Currently, more a quick hack. A generic TagsManager should be introduced + * to enable auto completion of tag names + * + * If the associated TOSCA element does not exist, an empty configuration is + * returned. That means, the associated TOSCA element is created (SIDE + * EFFECT) + */ + Configuration getConfiguration(RepositoryFileReference ref); + + /** + * + * @return the last change date of the configuration belonging to the given + * id. NULL if the associated TOSCA element does not exist. + */ + Date getConfigurationLastUpdate(GenericId id); + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IRepositoryAdministration.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IRepositoryAdministration.java new file mode 100644 index 0000000000..a373bdf4e1 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/IRepositoryAdministration.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Interface for low-level repository administration + */ +public interface IRepositoryAdministration { + + /** + * Dumps the content of the repository to the given output stream + * + * @param out stream to use to dump the data to. Currently, a ZIP output + * stream is returned. + * @throws IOException + */ + void doDump(OutputStream out) throws IOException; + + /** + * Removes all data + */ + void doClear(); + + /** + * Imports the content of the given stream into the repsotiry. + * + * @param in the stream to use. Currently, only ZIP input is supported. + */ + void doImport(InputStream in); +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/MockXMLElement.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/MockXMLElement.java new file mode 100644 index 0000000000..8887cb201f --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/MockXMLElement.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * Class for testing getAny() + * + * It has to be in src/main as src/test is not compiled during production, but + * the jaxbcontext is initialized in src/test and cannot be updated in src/main + * + * Included in {@link oorg.eclipse.winery.repository.JAXBSupport.initContext()} + */ +@XmlRootElement +public class MockXMLElement { + + @XmlElement + public String mock = "mock"; +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/Repository.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/Repository.java new file mode 100644 index 0000000000..f333005c20 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/Repository.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend; + +import org.eclipse.winery.repository.Prefs; + +public class Repository { + + public final static IRepository INSTANCE = Prefs.INSTANCE.getRepository(); +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/ResourceCreationResult.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/ResourceCreationResult.java new file mode 100644 index 0000000000..2a75ebabcd --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/ResourceCreationResult.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend; + +import java.net.URI; + +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.common.ids.GenericId; + +public class ResourceCreationResult { + + private Status status = null; + private URI uri = null; + private GenericId id = null; + + + public ResourceCreationResult() { + } + + public ResourceCreationResult(Status status) { + this.setStatus(status); + } + + public ResourceCreationResult(Status status, URI uri, GenericId id) { + this.setStatus(status); + this.setId(id); + this.setUri(uri); + } + + public Status getStatus() { + return this.status; + } + + public void setStatus(Status status) { + this.status = status; + } + + public URI getUri() { + return this.uri; + } + + public void setUri(URI uri) { + this.uri = uri; + } + + public GenericId getId() { + return this.id; + } + + public void setId(GenericId id) { + this.id = id; + } + + public boolean isSuccess() { + return this.getStatus() == Status.CREATED; + } + + /** + * The possibly existing URI is used as location in Response.created + * + * @return a Response created based on the contained data + */ + public Response getResponse() { + Response res; + if (this.getUri() == null) { + res = Response.status(this.getStatus()).build(); + } else { + assert (this.getStatus().equals(Status.CREATED)); + res = Response.created(this.getUri()).build(); + } + return res; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/constants/Filename.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/constants/Filename.java new file mode 100644 index 0000000000..23dc1b83c0 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/constants/Filename.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend.constants; + +/** + * TODO: check which of them can be removed + */ +public class Filename { + + public static final String FILENAME_BIG_ICON = "bigIcon.png"; + public static final String FILENAME_SMALL_ICON = "smallIcon.png"; + + public static final String FILENAME_JSON_NODETEMPLATES = "nodetemplates.json"; + public static final String FILENAME_JSON_PARENTCACHE = "parents.json"; + public static final String FILENAME_JSON_PLAN = "Plan.json"; + public static final String FILENAME_JSON_RELATIONSHIPTEMPLATE = "realtionshiptemplates.json"; + public static final String FILENAME_JSON_TOPOLOGYTEMPLATE = "TopologyTemplate.json"; + public static final String FILENAME_JSON_OPERATION_WSDL = "wsdl.json"; + public static final String FILENAME_JSON_OPERATION_REST = "rest.json"; + public static final String FILENAME_JSON_OPERATION_SCRIPT = "script.json"; + public static final String FILENAME_XML_PLAN = "Plan.xml"; + public static final String FILENAME_PROPERTIES_ARTIFACT = "artifact.properties"; + public static final String FILENAME_PROPERTIES_ARTIFACTTEMPLATE = "artifacttemplate.properties"; + public static final String FILENAME_PROPERTIES_ARTIFACTTYPE = "artifacttype.properties"; + public static final String FILENAME_PROPERTIES_FILEEXTENSIONTOARTIFACTTYPE = "fileextension-to-artifacttype.properties"; + public static final String FILENAME_PROPERTIES_IMPORTS = "imports.properties"; + public static final String FILENAME_PROPERTIES_NODETYPE = "NodeType.properties"; + public static final String FILENAME_PROPERTIES_OPERATION = "operation.properties"; + public static final String FILENAME_PROPERTIES_PLANCONTAINER = "plancontainer.properties"; + public static final String FILENAME_PROPERTIES_PLANLANGUAGES = "planlanguages.properties"; + public static final String FILENAME_PROPERTIES_PLANTYPES = "plantypes.properties"; + public static final String FILENAME_PROPERTIES_PROPERTIES = "properties.properties"; + public static final String FILENAME_PROPERTIES_RELATIONSHIPTYPE = "RelationshipType.properties"; + public static final String FILENAME_PROPERTIES_SERVICETEMPLATE = "ServiceTemplate.properties"; + public static final String FILENAME_PROPERTIES_TAGS = "tags.properties"; + public static final String FILENAME_PROPERTIES_VISUALAPPEARANCE = "VisualAppearance.properties"; + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/constants/MediaTypes.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/constants/MediaTypes.java new file mode 100644 index 0000000000..46fe1034bb --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/constants/MediaTypes.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend.constants; + +import javax.ws.rs.core.MediaType; + +import org.eclipse.winery.common.constants.MimeTypes; + +/** + * see also {@link org.eclipse.winery.common.constants.MimeTypes} + */ +public class MediaTypes { + + public static final MediaType MEDIATYPE_TOSCA_DEFINITIONS = MediaType.valueOf(MimeTypes.MIMETYPE_TOSCA_DEFINITIONS); + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/AutoSaveListener.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/AutoSaveListener.java new file mode 100644 index 0000000000..ce330a10a1 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/AutoSaveListener.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend.filebased; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.configuration.event.ConfigurationEvent; +import org.apache.commons.configuration.event.ConfigurationListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * We do not count loads and saves as in + * {@link org.apache.commons.configuration.builder.AutoSaveListener}, because + * ConfigurationListener is not aware of such things + */ +class AutoSaveListener implements ConfigurationListener { + + private static final Logger logger = LoggerFactory.getLogger(AutoSaveListener.class); + + private final Path path; + private final PropertiesConfiguration configuration; + + + /** + * + * @param path the file path to write to + * @param configuration the configuration, where the change events come + * from. This is needed as event.getSource() does + * not work + */ + public AutoSaveListener(Path path, PropertiesConfiguration configuration) { + this.path = path; + this.configuration = configuration; + } + + @Override + public void configurationChanged(ConfigurationEvent event) { + if (!event.isBeforeUpdate()) { + try { + if (!Files.exists(this.path.getParent())) { + Files.createDirectories(this.path.getParent()); + } + } catch (IOException ce) { + AutoSaveListener.logger.error("Could not update properties file", ce); + return; + } + try (OutputStream out = Files.newOutputStream(this.path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) { + OutputStreamWriter writer = new OutputStreamWriter(out); + this.configuration.save(writer); + } catch (ConfigurationException | IOException ce) { + AutoSaveListener.logger.error("Could not update properties file", ce); + } + } + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/FileUtils.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/FileUtils.java new file mode 100644 index 0000000000..b970f9603d --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/FileUtils.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend.filebased; + +import static java.nio.file.FileVisitResult.CONTINUE; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileUtils { + + private static final Logger logger = LoggerFactory.getLogger(FileUtils.class); + + + /** + * Deletes given path. If path a file, it is directly deleted. If it is a + * directory, the directory is recursively deleted. + * + * Does not try to change read-only files to read-write files + * + * Only uses Java7's nio, does not fall back to Java6. + * + * @param path the path to delete + * @throws IOException + */ + public static void forceDelete(Path path) throws IOException { + if (Files.isDirectory(path)) { + try { + Files.walkFileTree(path, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + try { + Files.delete(file); + } catch (IOException e) { + FileUtils.logger.debug("Could not delete file", e.getMessage()); + } + return CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + if (exc == null) { + try { + Files.delete(dir); + } catch (IOException e) { + FileUtils.logger.debug("Could not delete dir", e); + } + return CONTINUE; + } else { + FileUtils.logger.debug("Could not delete file", exc); + return CONTINUE; + } + } + }); + } catch (IOException e) { + FileUtils.logger.debug("Could not delete dir", e); + } + } else { + try { + Files.delete(path); + } catch (IOException e) { + FileUtils.logger.debug("Could not delete file", e.getMessage()); + } + } + } + + /** + * Creates the given directory including its parent directories, if they do + * not exist. + * + * @param path + * @throws IOException + */ + public static void createDirectory(Path path) throws IOException { + Path parent = path.getParent(); + if (parent == null) { + throw new IOException("No parent found"); + } + if (!Files.exists(parent)) { + FileUtils.createDirectory(parent); + } + if (!Files.exists(path)) { + Files.createDirectory(path); + } + } + + // public static Response readContentFromFile(RepositoryFileReference ref) { + // try { + // Repository.INSTANCE.readContentFromFile(ref); + // } + // } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/FilebasedRepository.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/FilebasedRepository.java new file mode 100644 index 0000000000..0fa405fd44 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/FilebasedRepository.java @@ -0,0 +1,592 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend.filebased; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.nio.charset.Charset; +import java.nio.file.DirectoryStream; +import java.nio.file.FileSystem; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.nio.file.spi.FileSystemProvider; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + +import javax.ws.rs.core.MediaType; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.lang3.SystemUtils; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.definitions.ArtifactTypeId; +import org.eclipse.winery.common.ids.definitions.CapabilityTypeId; +import org.eclipse.winery.common.ids.definitions.NodeTypeId; +import org.eclipse.winery.common.ids.definitions.NodeTypeImplementationId; +import org.eclipse.winery.common.ids.definitions.PolicyTemplateId; +import org.eclipse.winery.common.ids.definitions.PolicyTypeId; +import org.eclipse.winery.common.ids.definitions.RelationshipTypeId; +import org.eclipse.winery.common.ids.definitions.RelationshipTypeImplementationId; +import org.eclipse.winery.common.ids.definitions.RequirementTypeId; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.common.ids.elements.TOSCAElementId; +import org.eclipse.winery.repository.Constants; +import org.eclipse.winery.repository.backend.AbstractRepository; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.IRepository; +import org.eclipse.winery.repository.backend.IRepositoryAdministration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * When it comes to a storage of plain files, we use Java 7's nio internally. + * Therefore, we intend to expose the stream types offered by java.nio.Files: + * BufferedReader/BufferedWriter + */ +public class FilebasedRepository extends AbstractRepository implements IRepository, IRepositoryAdministration { + + private static final Logger logger = LoggerFactory.getLogger(FilebasedRepository.class); + + protected final Path repositoryRoot; + + // convenience variables to have a clean code + private final FileSystem fileSystem; + private final FileSystemProvider provider; + + + private Path makeAbsolute(Path relativePath) { + return this.repositoryRoot.resolve(relativePath); + } + + @Override + public boolean flagAsExisting(GenericId id) { + Path path = this.id2AbsolutePath(id); + try { + FileUtils.createDirectory(path); + } catch (IOException e) { + FilebasedRepository.logger.debug(e.toString()); + return false; + } + return true; + } + + private Path id2AbsolutePath(GenericId id) { + Path relativePath = this.fileSystem.getPath(BackendUtils.getPathInsideRepo(id)); + return this.makeAbsolute(relativePath); + } + + /** + * Converts the given reference to an absolute path of the underlying + * FileSystem + */ + public Path ref2AbsolutePath(RepositoryFileReference ref) { + return this.id2AbsolutePath(ref.getParent()).resolve(ref.getFileName()); + } + + /** + * + * @param repositoryLocation a string pointing to a location on the file + * system. May be null. + */ + public FilebasedRepository(String repositoryLocation) { + this.repositoryRoot = this.determineRepositoryPath(repositoryLocation); + this.fileSystem = this.repositoryRoot.getFileSystem(); + this.provider = this.fileSystem.provider(); + } + + private Path determineRepositoryPath(String repositoryLocation) { + Path repositoryPath; + if (repositoryLocation == null) { + if (SystemUtils.IS_OS_WINDOWS) { + if (new File(Constants.GLOBAL_REPO_PATH_WINDOWS).exists()) { + repositoryLocation = Constants.GLOBAL_REPO_PATH_WINDOWS; + File repo = new File(repositoryLocation); + try { + org.apache.commons.io.FileUtils.forceMkdir(repo); + } catch (IOException e) { + FilebasedRepository.logger.error("Could not create repository directory", e); + } + repositoryPath = repo.toPath(); + } else { + repositoryPath = this.createDefaultRepositoryPath(); + } + } else { + repositoryPath = this.createDefaultRepositoryPath(); + } + } else { + File repo = new File(repositoryLocation); + try { + org.apache.commons.io.FileUtils.forceMkdir(repo); + } catch (IOException e) { + FilebasedRepository.logger.error("Could not create repository directory", e); + } + repositoryPath = repo.toPath(); + } + return repositoryPath; + } + + private Path createDefaultRepositoryPath() { + File repo = null; + boolean operationalFileSystemAccess; + try { + repo = new File(org.apache.commons.io.FileUtils.getUserDirectory(), Constants.DEFAULT_REPO_NAME); + operationalFileSystemAccess = true; + } catch (NullPointerException e) { + // it seems, we run at a system, where we do not have any filesystem + // access + operationalFileSystemAccess = false; + } + + // operationalFileSystemAccess = false; + + Path repositoryPath; + if (operationalFileSystemAccess) { + try { + org.apache.commons.io.FileUtils.forceMkdir(repo); + } catch (IOException e) { + FilebasedRepository.logger.error("Could not create directory", e); + } + repositoryPath = repo.toPath(); + } else { + assert (!operationalFileSystemAccess); + // we do not have access to the file system + throw new IllegalStateException("No write access to file system"); + } + + return repositoryPath; + } + + @Override + public void forceDelete(RepositoryFileReference ref) throws IOException { + Path relativePath = this.fileSystem.getPath(BackendUtils.getPathInsideRepo(ref)); + Path fileToDelete = this.makeAbsolute(relativePath); + try { + this.provider.delete(fileToDelete); + // Quick hack for deletion of the mime type information + // Alternative: superclass: protected void deleteMimeTypeInformation(RepositoryFileReference ref) throws IOException + // However, this would again call this method, where we would have to check for the extension, too. + // Therefore, we directly delete the information file + Path mimeTypeFile = fileToDelete.getParent().resolve(ref.getFileName() + Constants.SUFFIX_MIMETYPE); + this.provider.delete(mimeTypeFile); + } catch (IOException e) { + if (!(e instanceof NoSuchFileException)) { + // only if file did exist and something else went wrong: complain :) + // (otherwise, silently ignore the error) + FilebasedRepository.logger.debug("Could not delete file", e); + throw e; + } + } + } + + @Override + public void forceDelete(GenericId id) throws IOException { + try { + FileUtils.forceDelete(this.id2AbsolutePath(id)); + } catch (IOException e) { + FilebasedRepository.logger.debug("Could not delete id", id); + throw e; + } + } + + @Override + public boolean exists(GenericId id) { + // We do not check for a property file, just for the existence of the + // directory in case of TOSCA components + return Files.exists(this.id2AbsolutePath(id)); + } + + /** + * {@inheritDoc} + */ + @Override + public void putContentToFile(RepositoryFileReference ref, String content, MediaType mediaType) throws IOException { + if (mediaType == null) { + // quick hack for storing mime type called this method + assert (ref.getFileName().endsWith(Constants.SUFFIX_MIMETYPE)); + // we do not need to store the mime type of the file containing the mime type information + } else { + this.setMimeType(ref, mediaType); + } + Path path = this.ref2AbsolutePath(ref); + FileUtils.createDirectory(path.getParent()); + Files.write(path, content.getBytes()); + } + + /** + * {@inheritDoc} + */ + @Override + public void putContentToFile(RepositoryFileReference ref, InputStream inputStream, MediaType mediaType) throws IOException { + if (mediaType == null) { + // quick hack for storing mime type called this method + assert (ref.getFileName().endsWith(Constants.SUFFIX_MIMETYPE)); + // we do not need to store the mime type of the file containing the mime type information + } else { + this.setMimeType(ref, mediaType); + } + Path targetPath = this.ref2AbsolutePath(ref); + // ensure that parent directory exists + FileUtils.createDirectory(targetPath.getParent()); + + try { + Files.copy(inputStream, targetPath, StandardCopyOption.REPLACE_EXISTING); + } catch (IllegalStateException e) { + FilebasedRepository.logger.debug("Guessing that stream with length 0 is to be written to a file", e); + // copy throws an "java.lang.IllegalStateException: Stream already closed" if the InputStream contains 0 bytes + // For instance, this case happens if SugarCE-6.4.2.zip.removed is tried to be uploaded + // We work around the Java7 issue and create an empty file + if (Files.exists(targetPath)) { + // semantics of putContentToFile: existing content is replaced without notification + Files.delete(targetPath); + } + Files.createFile(targetPath); + } + } + + @Override + public boolean exists(RepositoryFileReference ref) { + return Files.exists(this.ref2AbsolutePath(ref)); + } + + @Override + public SortedSet getAllTOSCAComponentIds(Class idClass) { + SortedSet res = new TreeSet(); + String rootPathFragment = Util.getRootPathFragment(idClass); + Path dir = this.repositoryRoot.resolve(rootPathFragment); + if (!Files.exists(dir)) { + // return empty list if no ids are available + return res; + } + assert (Files.isDirectory(dir)); + + final OnlyNonHiddenDirectories onhdf = new OnlyNonHiddenDirectories(); + + // list all directories contained in this directory + try (DirectoryStream ds = Files.newDirectoryStream(dir, onhdf)) { + for (Path nsP : ds) { + // the current path is the namespace + Namespace ns = new Namespace(nsP.getFileName().toString(), true); + try (DirectoryStream idDS = Files.newDirectoryStream(nsP, onhdf)) { + for (Path idP : idDS) { + XMLId xmlId = new XMLId(idP.getFileName().toString(), true); + Constructor constructor; + try { + constructor = idClass.getConstructor(Namespace.class, XMLId.class); + } catch (Exception e) { + FilebasedRepository.logger.debug("Internal error at determining id constructor", e); + // abort everything, return invalid result + return res; + } + T id; + try { + id = constructor.newInstance(ns, xmlId); + } catch (InstantiationException + | IllegalAccessException + | IllegalArgumentException + | InvocationTargetException e) { + FilebasedRepository.logger.debug("Internal error at invocation of id constructor", e); + // abort everything, return invalid result + return res; + } + res.add(id); + } + } + } + } catch (IOException e) { + FilebasedRepository.logger.debug("Cannot close ds", e); + } + + return res; + } + + @Override + public SortedSet getContainedFiles(GenericId id) { + Path dir = this.id2AbsolutePath(id); + SortedSet res = new TreeSet(); + if (!Files.exists(dir)) { + return res; + } + assert (Files.isDirectory(dir)); + // list all directories contained in this directory + try (DirectoryStream ds = Files.newDirectoryStream(dir, new OnlyNonHiddenFiles())) { + for (Path p : ds) { + RepositoryFileReference ref = new RepositoryFileReference(id, p.getFileName().toString()); + res.add(ref); + } + } catch (IOException e) { + FilebasedRepository.logger.debug("Cannot close ds", e); + } + return res; + } + + @Override + public Configuration getConfiguration(RepositoryFileReference ref) { + Path path = this.ref2AbsolutePath(ref); + + PropertiesConfiguration configuration = new PropertiesConfiguration(); + if (Files.exists(path)) { + try (Reader r = Files.newBufferedReader(path, Charset.defaultCharset())) { + configuration.load(r); + } catch (ConfigurationException | IOException e) { + FilebasedRepository.logger.error("Could not read config file", e); + throw new IllegalStateException("Could not read config file", e); + } + } + + configuration.addConfigurationListener(new AutoSaveListener(path, configuration)); + + // We do NOT implement reloading as the configuration is only accessed + // in JAX-RS resources, which are created on a per-request basis + + return configuration; + } + + /** + * @return null if an error occurred + */ + @Override + public Date getLastUpdate(RepositoryFileReference ref) { + Path path = this.ref2AbsolutePath(ref); + Date res; + if (Files.exists(path)) { + FileTime lastModifiedTime; + try { + lastModifiedTime = Files.getLastModifiedTime(path); + res = new Date(lastModifiedTime.toMillis()); + } catch (IOException e) { + FilebasedRepository.logger.debug(e.getMessage(), e); + res = null; + } + } else { + // this branch is taken if the resource directory exists, but the + // configuration itself does not exist. + // For instance, this happens if icons are manually put for a node + // type, but no color configuration is made. + res = Constants.LASTMODIFIEDDATE_FOR_404; + } + return res; + } + + @Override + public SortedSet getNestedIds(GenericId ref, Class idClass) { + Path dir = this.id2AbsolutePath(ref); + SortedSet res = new TreeSet(); + if (!Files.exists(dir)) { + // the id has been generated by the exporter without existance test. + // This test is done here. + return res; + } + assert (Files.isDirectory(dir)); + // list all directories contained in this directory + try (DirectoryStream ds = Files.newDirectoryStream(dir, new OnlyNonHiddenDirectories())) { + for (Path p : ds) { + XMLId xmlId = new XMLId(p.getFileName().toString(), true); + @SuppressWarnings("unchecked") + Constructor[] constructors = (Constructor[]) idClass.getConstructors(); + assert (constructors.length == 1); + Constructor constructor = constructors[0]; + assert (constructor.getParameterTypes().length == 2); + T id; + try { + id = constructor.newInstance(ref, xmlId); + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + FilebasedRepository.logger.debug("Internal error at invocation of id constructor", e); + // abort everything, return invalid result + return res; + } + res.add(id); + } + } catch (IOException e) { + FilebasedRepository.logger.debug("Cannot close ds", e); + } + return res; + } + + @Override + // below, toscaComponents is an array, which is used in an iterator + // As Java does not allow generic arrays, we have to suppress the warning when fetching an element out of the list + @SuppressWarnings("unchecked") + public Collection getUsedNamespaces() { + // @formatter:off + @SuppressWarnings("rawtypes") + Class[] toscaComponentIds = { + ArtifactTemplateId.class, + ArtifactTypeId.class, + CapabilityTypeId.class, + NodeTypeId.class, + NodeTypeImplementationId.class, + PolicyTemplateId.class, + PolicyTypeId.class, + RelationshipTypeId.class, + RelationshipTypeImplementationId.class, + RequirementTypeId.class, + ServiceTemplateId.class + }; + // @formatter:on + + // we use a HashSet to avoid reporting duplicate namespaces + Collection res = new HashSet(); + + for (Class id : toscaComponentIds) { + String rootPathFragment = Util.getRootPathFragment(id); + Path dir = this.repositoryRoot.resolve(rootPathFragment); + if (!Files.exists(dir)) { + continue; + } + assert (Files.isDirectory(dir)); + + final OnlyNonHiddenDirectories onhdf = new OnlyNonHiddenDirectories(); + + // list all directories contained in this directory + try (DirectoryStream ds = Files.newDirectoryStream(dir, onhdf)) { + for (Path nsP : ds) { + // the current path is the namespace + Namespace ns = new Namespace(nsP.getFileName().toString(), true); + res.add(ns); + } + } catch (IOException e) { + FilebasedRepository.logger.debug("Cannot close ds", e); + } + } + return res; + } + + @Override + public void doDump(OutputStream out) throws IOException { + final ZipOutputStream zout = new ZipOutputStream(out); + final int cutLength = this.repositoryRoot.toString().length() + 1; + + Files.walkFileTree(this.repositoryRoot, new SimpleFileVisitor() { + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + if (dir.endsWith(".git")) { + return FileVisitResult.SKIP_SUBTREE; + } else { + return FileVisitResult.CONTINUE; + } + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + String name = file.toString().substring(cutLength); + ZipEntry ze = new ZipEntry(name); + try { + ze.setTime(Files.getLastModifiedTime(file).toMillis()); + ze.setSize(Files.size(file)); + zout.putNextEntry(ze); + Files.copy(file, zout); + zout.closeEntry(); + } catch (IOException e) { + FilebasedRepository.logger.debug(e.getMessage()); + } + return FileVisitResult.CONTINUE; + } + }); + zout.close(); + } + + /** + * Removes all files and dirs except the .git directory + */ + @Override + public void doClear() { + try { + DirectoryStream.Filter noGitDirFilter = new DirectoryStream.Filter() { + + @Override + public boolean accept(Path entry) throws IOException { + return !(entry.getFileName().toString().equals(".git")); + } + }; + + DirectoryStream ds = Files.newDirectoryStream(this.repositoryRoot, noGitDirFilter); + for (Path p : ds) { + FileUtils.forceDelete(p); + } + } catch (IOException e) { + FilebasedRepository.logger.error(e.getMessage()); + e.printStackTrace(); + } + } + + @Override + public void doImport(InputStream in) { + ZipInputStream zis = new ZipInputStream(in); + ZipEntry entry; + try { + while ((entry = zis.getNextEntry()) != null) { + if (!entry.isDirectory()) { + Path path = this.repositoryRoot.resolve(entry.getName()); + FileUtils.createDirectory(path.getParent()); + Files.copy(zis, path); + } + } + } catch (IOException e) { + FilebasedRepository.logger.error(e.getMessage()); + } + } + + /** + * {@inheritDoc} + */ + @Override + public long getSize(RepositoryFileReference ref) throws IOException { + return Files.size(this.ref2AbsolutePath(ref)); + } + + /** + * {@inheritDoc} + */ + @Override + public FileTime getLastModifiedTime(RepositoryFileReference ref) throws IOException { + Path path = this.ref2AbsolutePath(ref); + FileTime res = Files.getLastModifiedTime(path); + return res; + } + + /** + * {@inheritDoc} + */ + @Override + public InputStream newInputStream(RepositoryFileReference ref) throws IOException { + Path path = this.ref2AbsolutePath(ref); + InputStream res = Files.newInputStream(path); + return res; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/GitBasedRepository.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/GitBasedRepository.java new file mode 100644 index 0000000000..a3f3fc8e9e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/GitBasedRepository.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend.filebased; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.eclipse.jgit.api.AddCommand; +import org.eclipse.jgit.api.CleanCommand; +import org.eclipse.jgit.api.CommitCommand; +import org.eclipse.jgit.api.FetchCommand; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.PushCommand; +import org.eclipse.jgit.api.ResetCommand; +import org.eclipse.jgit.api.ResetCommand.ResetType; +import org.eclipse.jgit.api.errors.CheckoutConflictException; +import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.NoHeadException; +import org.eclipse.jgit.api.errors.NoMessageException; +import org.eclipse.jgit.api.errors.UnmergedPathsException; +import org.eclipse.jgit.api.errors.WrongRepositoryStateException; +import org.eclipse.jgit.errors.NoWorkTreeException; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.storage.file.FileRepositoryBuilder; +import org.eclipse.jgit.transport.CredentialsProvider; +import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.winery.repository.Prefs; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Used for testing only. + * + * Allows to reset repository to a certain commit id + */ +public class GitBasedRepository extends FilebasedRepository { + + private static final Logger logger = LoggerFactory.getLogger(GitBasedRepository.class); + + private final Repository gitRepo; + private final Git git; + private final CredentialsProvider cp; + + public static final String PREFERENCE_GIT_USERNAME = "git.username"; + public static final String PREFERENCE_GIT_PASSWORD = "git.password"; + + + /** + * @param repositoryLocation the location of the repository + * @throws IOException thrown if repository does not exist + */ + public GitBasedRepository(String repositoryLocation) throws IOException { + super(repositoryLocation); + FileRepositoryBuilder builder = new FileRepositoryBuilder(); + this.gitRepo = builder.setWorkTree(this.repositoryRoot.toFile()).setMustExist(true).build(); + this.git = new Git(this.gitRepo); + + this.cp = this.initializeCredentialsProvider(); + } + + /** + * Reads the properties stored in ".winery" in the repository + */ + private Properties dotWineryProperties() { + Properties p = new Properties(); + File f = new File(this.repositoryRoot.toFile(), ".winery"); + InputStream is; + try { + is = new FileInputStream(f); + } catch (FileNotFoundException e1) { + // .winery does not exist in the file-based repository + return p; + } + if (is != null) { + try { + p.load(is); + } catch (IOException e) { + GitBasedRepository.logger.debug(e.getMessage(), e); + } + } + return p; + } + + /** + * Uses git.username und git.password from .winery and winery.properties + * + * Considering .winery is useful if the same war file is used on a dev + * server and a stable server. The WAR file cannot contain the credentials + * if committing is only allowed on only one of these servers + */ + private CredentialsProvider initializeCredentialsProvider() { + CredentialsProvider cp; + + Properties wp = this.dotWineryProperties(); + + String gitUserName = wp.getProperty(GitBasedRepository.PREFERENCE_GIT_USERNAME); + if (gitUserName == null) { + gitUserName = Prefs.INSTANCE.getProperties().getProperty(GitBasedRepository.PREFERENCE_GIT_USERNAME); + } + + String gitPassword = wp.getProperty(GitBasedRepository.PREFERENCE_GIT_PASSWORD); + if (gitPassword == null) { + gitPassword = Prefs.INSTANCE.getProperties().getProperty(GitBasedRepository.PREFERENCE_GIT_PASSWORD); + } + + if (gitUserName == null) { + cp = null; + } else if (gitPassword == null) { + cp = null; + } else { + cp = new UsernamePasswordCredentialsProvider(gitUserName, gitPassword); + } + return cp; + } + + public void addCommitPush() throws NoHeadException, NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException, GitAPIException { + AddCommand add = this.git.add(); + add.addFilepattern("."); + add.call(); + + CommitCommand commit = this.git.commit(); + commit.setMessage("Commit through Winery"); + commit.call(); + + PushCommand push = this.git.push(); + if (this.cp != null) { + push.setCredentialsProvider(this.cp); + } + push.call(); + } + + private void clean() throws NoWorkTreeException, GitAPIException { + GitBasedRepository.logger.trace("git clean"); + // remove untracked files + CleanCommand clean = this.git.clean(); + clean.setCleanDirectories(true); + clean.call(); + } + + public void cleanAndResetHard() throws NoWorkTreeException, GitAPIException { + // enable updating by resetting the content of the repository + this.clean(); + + // fetch the newest thing from upstream + GitBasedRepository.logger.trace("git fetch"); + FetchCommand fetch = this.git.fetch(); + if (this.cp != null) { + fetch.setCredentialsProvider(this.cp); + } + fetch.call(); + + // after fetching, reset to the latest version + GitBasedRepository.logger.trace("git reset --hard"); + ResetCommand reset = this.git.reset(); + reset.setMode(ResetType.HARD); + reset.call(); + } + + public void setRevisionTo(String ref) throws CheckoutConflictException, GitAPIException { + this.clean(); + + // reset repository to the desired reference + ResetCommand reset = this.git.reset(); + reset.setMode(ResetType.HARD); + reset.setRef(ref); + reset.call(); + } + + /** + * Returns true if authentification information (for instance, to push to + * upstream) is available + */ + public boolean authenticationInfoAvailable() { + return this.cp != null; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/OnlyNonHiddenDirectories.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/OnlyNonHiddenDirectories.java new file mode 100644 index 0000000000..a5acd8e31b --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/OnlyNonHiddenDirectories.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend.filebased; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; + +public class OnlyNonHiddenDirectories implements DirectoryStream.Filter { + + @Override + public boolean accept(Path entry) throws IOException { + // we return only non-hidden directories + // E.g., DS_Store of Mac OS X is a hidden directory + return Files.isDirectory(entry) && !Files.isHidden(entry); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/OnlyNonHiddenFiles.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/OnlyNonHiddenFiles.java new file mode 100644 index 0000000000..3b788b43dc --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/backend/filebased/OnlyNonHiddenFiles.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.backend.filebased; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.eclipse.winery.repository.Constants; + +/** + * Only non-hidden files. Also excludes file names ending with + * Constants.SUFFIX_MIMETYPE + */ +public class OnlyNonHiddenFiles implements DirectoryStream.Filter { + + @Override + public boolean accept(Path entry) throws IOException { + // we return only non-hidden files + // and we do not return the file "FN.mimetype", which are used to store the mimetype of FN + return !Files.isDirectory(entry) && !Files.isHidden(entry) && (!entry.getFileName().toString().endsWith(Constants.SUFFIX_MIMETYPE)); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/FileMeta.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/FileMeta.java new file mode 100644 index 0000000000..bf25ae76fc --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/FileMeta.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes; + +import java.io.IOException; + +import javax.xml.bind.annotation.XmlRootElement; + +import org.apache.commons.io.FilenameUtils; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.repository.Constants; +import org.eclipse.winery.repository.Prefs; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.Repository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * based on + * https://github.com/blueimp/jQuery-File-Upload/wiki/Google-App-Engine-Java + * + * The getters are named according to the requirements of the template in + * jquery-file-upload-full.jsp + */ +@XmlRootElement +public class FileMeta { + + private static final Logger logger = LoggerFactory.getLogger(FileMeta.class); + + String name; + long size; + String url; + String deleteUrl; + String deleteType = "DELETE"; + String thumbnailUrl; + + + public String getName() { + return this.name; + } + + public long getSize() { + return this.size; + } + + public String getUrl() { + return this.url; + } + + public String getDeleteUrl() { + return this.deleteUrl; + } + + public String getDeleteType() { + return this.deleteType; + } + + public String getThumbnailUrl() { + return this.thumbnailUrl; + } + + public FileMeta(String filename, long size, String url, String thumbnailUrl) { + this.name = filename; + this.size = size; + this.url = url; + this.thumbnailUrl = thumbnailUrl; + this.deleteUrl = url; + } + + public FileMeta(RepositoryFileReference ref) { + this.name = ref.getFileName(); + try { + this.size = Repository.INSTANCE.getSize(ref); + } catch (IOException e) { + FileMeta.logger.error(e.getMessage(), e); + this.size = 0; + } + this.url = Utils.getAbsoluteURL(ref); + this.deleteUrl = this.url; + this.thumbnailUrl = Prefs.INSTANCE.getResourcePath() + Constants.PATH_MIMETYPEIMAGES + FilenameUtils.getExtension(this.name) + Constants.SUFFIX_MIMETYPEIMAGES; + } + + /** + * @param ref the reference to get information from + * @param URLprefix the string which should be prepended the actual URL. + * Including the "/" + */ + public FileMeta(RepositoryFileReference ref, String URLprefix) { + this(ref); + this.url = URLprefix + this.url; + } + + /** + * The constructor is used for JAX-B only. Therefore, the warning "unused" + * is suppressed + */ + @SuppressWarnings("unused") + private FileMeta() { + } + +} \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/TypeWithShortName.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/TypeWithShortName.java new file mode 100644 index 0000000000..eae201d38b --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/TypeWithShortName.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes; + +public class TypeWithShortName implements Comparable { + + private final String type; + // we could have used "URI" as type here but this seems to be unnecessary + // overhead + + // this is a kind of ID + private final String shortName; + + + public TypeWithShortName(String type, String shortName) { + this.type = type; + this.shortName = shortName; + } + + public String getType() { + return this.type; + } + + public String getShortName() { + return this.shortName; + } + + @Override + public boolean equals(Object o) { + if (o instanceof TypeWithShortName) { + return ((TypeWithShortName) o).getType().equals(this.getType()); + } else { + return false; + } + } + + @Override + public int hashCode() { + return this.getType().hashCode(); + } + + @Override + public int compareTo(TypeWithShortName o) { + int c = this.getShortName().compareTo(o.getShortName()); + if (c == 0) { + // not sure if this will ever happen + c = this.getType().compareTo(o.getType()); + } + return c; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/IdNames.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/IdNames.java new file mode 100644 index 0000000000..f06c9173bc --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/IdNames.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes.ids; + +/** + * This class is the brother of {@link org.eclipse.winery.common.id.IdNames} + * + * It includes all id names used additionally in the local ids + */ +public class IdNames { + + // the files belonging to one artifact template are nested in the sub + // directory "files" + public static final String ARTIFACTTEMPLATEDIRECTORY = "files"; + + public static final String CONSTRAINTTYPES = "constrainttypes"; + public static final String NAMESPACES = "namespaces"; + public static final String PLANLANGUAGES = "planlanguages"; + public static final String PLANTYPES = "plantypes"; + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/AdminId.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/AdminId.java new file mode 100644 index 0000000000..3a31b0556b --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/AdminId.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes.ids.admin; + +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.common.ids.XMLId; + +/** + * The Id for the single admin resource holding administrative things such as + * the prefixes of namespaces + */ +public abstract class AdminId extends GenericId { + + protected AdminId(XMLId xmlId) { + super(xmlId); + } + + @Override + public int compareTo(GenericId o) { + if (o instanceof AdminId) { + return this.getXmlId().compareTo(o.getXmlId()); + } else { + throw new IllegalStateException(); + } + } + + @Override + public GenericId getParent() { + return null; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof AdminId) { + return this.getXmlId().equals(((AdminId) obj).getXmlId()); + } else { + return false; + } + } + + @Override + public int hashCode() { + return this.getXmlId().hashCode(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/ConstraintTypesId.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/ConstraintTypesId.java new file mode 100644 index 0000000000..210a2c7be6 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/ConstraintTypesId.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes.ids.admin; + +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.repository.datatypes.ids.IdNames; + +public class ConstraintTypesId extends TypesId { + + private final static XMLId xmlId = new XMLId(IdNames.CONSTRAINTTYPES, false); + + + public ConstraintTypesId() { + super(ConstraintTypesId.xmlId); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/NamespacesId.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/NamespacesId.java new file mode 100644 index 0000000000..4bdb233bbd --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/NamespacesId.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes.ids.admin; + +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.repository.datatypes.ids.IdNames; + +public class NamespacesId extends AdminId { + + private final static XMLId xmlId = new XMLId(IdNames.NAMESPACES, false); + + + public NamespacesId() { + super(NamespacesId.xmlId); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/PlanLanguagesId.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/PlanLanguagesId.java new file mode 100644 index 0000000000..7ebfb7dbb3 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/PlanLanguagesId.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes.ids.admin; + +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.repository.datatypes.ids.IdNames; + +public class PlanLanguagesId extends TypesId { + + private final static XMLId xmlId = new XMLId(IdNames.PLANLANGUAGES, false); + + + public PlanLanguagesId() { + super(PlanLanguagesId.xmlId); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/PlanTypesId.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/PlanTypesId.java new file mode 100644 index 0000000000..e44cd2b904 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/PlanTypesId.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes.ids.admin; + +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.repository.datatypes.ids.IdNames; + +public class PlanTypesId extends TypesId { + + private final static XMLId xmlId = new XMLId(IdNames.PLANTYPES, false); + + + public PlanTypesId() { + super(PlanTypesId.xmlId); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/TypesId.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/TypesId.java new file mode 100644 index 0000000000..db40780916 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/admin/TypesId.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes.ids.admin; + +import org.eclipse.winery.common.ids.XMLId; + +public abstract class TypesId extends AdminId { + + protected TypesId(XMLId xmlId) { + super(xmlId); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/ArtifactTemplateDirectoryId.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/ArtifactTemplateDirectoryId.java new file mode 100644 index 0000000000..cce2d53b0b --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/ArtifactTemplateDirectoryId.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes.ids.elements; + +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.elements.TOSCAElementId; +import org.eclipse.winery.repository.datatypes.ids.IdNames; + +public class ArtifactTemplateDirectoryId extends TOSCAElementId { + + private final static XMLId xmlID = new XMLId(IdNames.ARTIFACTTEMPLATEDIRECTORY, false); + + + public ArtifactTemplateDirectoryId(ArtifactTemplateId parent) { + super(parent, ArtifactTemplateDirectoryId.xmlID); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/SelfServiceMetaDataId.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/SelfServiceMetaDataId.java new file mode 100644 index 0000000000..6bd5db8958 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/SelfServiceMetaDataId.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes.ids.elements; + +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.common.ids.elements.TOSCAElementId; + +public class SelfServiceMetaDataId extends TOSCAElementId { + + public SelfServiceMetaDataId(ServiceTemplateId parent) { + super(parent, new XMLId("SELFSERVICE-Metadata", true)); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/VisualAppearanceId.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/VisualAppearanceId.java new file mode 100644 index 0000000000..9b7784fbc5 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/ids/elements/VisualAppearanceId.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes.ids.elements; + +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.TopologyGraphElementEntityTypeId; +import org.eclipse.winery.common.ids.elements.TOSCAElementId; + +/** + * ID for a pseudo-TOSCA-Element holding the data for the visual appearance + * (e.g., icons for node types) + */ +public class VisualAppearanceId extends TOSCAElementId { + + public VisualAppearanceId(TopologyGraphElementEntityTypeId parent) { + super(parent, new XMLId("appearance", true)); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/Select2DataItem.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/Select2DataItem.java new file mode 100644 index 0000000000..1b8fb9a052 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/Select2DataItem.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.datatypes.select2; + +/** + * Models a data item for select2. In case optgroups have to be returned, use + * this element in a TreeMap + */ +public class Select2DataItem implements Comparable { + + private final String id; + private final String text; + + + public Select2DataItem(String id, String text) { + this.id = id; + this.text = text; + } + + public String getId() { + return this.id; + } + + public String getText() { + return this.text; + } + + /** + * Sort order is based on text + */ + @Override + public int compareTo(Select2DataItem o) { + return this.getText().compareTo(o.getText()); + } + + /** + * Equality is checked at id level + */ + @Override + public boolean equals(Object o) { + if (!(o instanceof Select2DataItem)) { + return false; + } + return this.getId().equals(((Select2DataItem) o).getId()); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/Select2OptGroup.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/Select2OptGroup.java new file mode 100644 index 0000000000..326cc8c026 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/Select2OptGroup.java @@ -0,0 +1,54 @@ +package org.eclipse.winery.repository.datatypes.select2; + +import java.util.SortedSet; +import java.util.TreeSet; + +public class Select2OptGroup implements Comparable { + + private final String text; + private final SortedSet children; + + + public Select2OptGroup(String text) { + this.text = text; + this.children = new TreeSet(); + } + + public String getText() { + return this.text; + } + + /** + * Returns the internal SortedSet for data items. + */ + public SortedSet getChildren() { + return this.children; + } + + public void addItem(Select2DataItem item) { + this.children.add(item); + } + + /** + * Quick hack to test Select2OptGroups for equality. Only the text is + * tested, not the contained children. This might cause issues later, but + * currently not. + */ + @Override + public boolean equals(Object o) { + if (!(o instanceof Select2OptGroup)) { + return false; + } + return this.text.equals(((Select2OptGroup) o).text); + } + + /** + * Quick hack to compare Select2OptGroups. Only the text is compared, not + * the contained children. This might cause issues later, but currently not. + */ + @Override + public int compareTo(Select2OptGroup o) { + return this.getText().compareTo(o.getText()); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/package-info.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/package-info.java new file mode 100644 index 0000000000..ee1fbafeaa --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/datatypes/select2/package-info.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ + +/** + * This package collects all datatypes required to generate valid select2 data objects + * {@see http://ivaynberg.github.io/select2/}: Example Hierarchical Data + */ +package org.eclipse.winery.repository.datatypes.select2; \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/CSARExporter.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/CSARExporter.java new file mode 100644 index 0000000000..d968168c33 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/CSARExporter.java @@ -0,0 +1,296 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Kálmán Képes - initial API and implementation and/or initial documentation + * Oliver Kopp - adapted to new storage model and to TOSCA v1.0 + *******************************************************************************/ +package org.eclipse.winery.repository.export; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.bind.JAXBException; +import javax.xml.stream.XMLStreamException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.commons.compress.archivers.ArchiveEntry; +import org.apache.commons.compress.archivers.ArchiveException; +import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.ArchiveStreamFactory; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.io.IOUtils; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.constants.MimeTypes; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.model.selfservice.Application; +import org.eclipse.winery.model.selfservice.Application.Options; +import org.eclipse.winery.model.selfservice.ApplicationOption; +import org.eclipse.winery.repository.Constants; +import org.eclipse.winery.repository.Prefs; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.datatypes.ids.admin.NamespacesId; +import org.eclipse.winery.repository.datatypes.ids.elements.SelfServiceMetaDataId; +import org.eclipse.winery.repository.resources.admin.NamespacesResource; +import org.eclipse.winery.repository.resources.servicetemplates.selfserviceportal.SelfServicePortalResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; + +/** + * This class exports a CSAR crawling from the the given GenericId
+ * Currently, only ServiceTemplates are supported
+ * commons-compress is used as an output stream should be provided. An + * alternative implementation is to use Java7's Zip File System Provider + */ +public class CSARExporter { + + public static final String PATH_TO_NAMESPACES_PROPERTIES = "winery/Namespaces.properties"; + + private static final Logger logger = LoggerFactory.getLogger(CSARExporter.class); + + private static final String DEFINITONS_PATH_PREFIX = "Definitions/"; + + + /** + * Returns a unique name for the given definitions to be used as filename + */ + private static String getDefinitionsName(TOSCAComponentId id) { + // the prefix is globally unique and the id locally in a namespace + // therefore a concatenation of both is also unique + String res = NamespacesResource.getPrefix(id.getNamespace()) + "__" + id.getXmlId().getEncoded(); + return res; + } + + public static String getDefinitionsFileName(TOSCAComponentId id) { + return CSARExporter.getDefinitionsName(id) + Constants.SUFFIX_TOSCA_DEFINITIONS; + } + + public static String getDefinitionsPathInsideCSAR(TOSCAComponentId id) { + return CSARExporter.DEFINITONS_PATH_PREFIX + CSARExporter.getDefinitionsFileName(id); + } + + /** + * Writes a complete CSAR containing all necessary things reachable from the + * given service template + * + * @param id the id of the service template to export + * @param out the outputstream to write to + * @throws JAXBException + */ + public void writeCSAR(TOSCAComponentId entryId, OutputStream out) throws ArchiveException, IOException, XMLStreamException, JAXBException { + Map refMap = new HashMap(); + Collection definitionNames = new ArrayList<>(); + + final ArchiveOutputStream zos = new ArchiveStreamFactory().createArchiveOutputStream("zip", out); + + TOSCAExportUtil exporter = new TOSCAExportUtil(); + Map conf = new HashMap<>(); + + ExportedState exportedState = new ExportedState(); + + TOSCAComponentId currentId = entryId; + do { + String defName = CSARExporter.getDefinitionsPathInsideCSAR(currentId); + definitionNames.add(defName); + + zos.putArchiveEntry(new ZipArchiveEntry(defName)); + Collection referencedIds; + try { + referencedIds = exporter.exportTOSCA(currentId, zos, refMap, conf); + } catch (IllegalStateException e) { + // thrown if something went wrong inside the repo + out.close(); + // we just rethrow as there currently is no error stream. + throw e; + } + zos.closeArchiveEntry(); + + exportedState.flagAsExported(currentId); + exportedState.flagAsExportRequired(referencedIds); + + currentId = exportedState.pop(); + } while (currentId != null); + + // if we export a ServiceTemplate, data for the self-service portal might exist + if (entryId instanceof ServiceTemplateId) { + this.addSelfServiceMetaData((ServiceTemplateId) entryId, refMap); + } + + // now, refMap contains all files to be added to the CSAR + + // write manifest directly after the definitions to have it more at the beginning of the ZIP rather than having it at the very end + this.addManifest(entryId, definitionNames, refMap, zos); + + // used for generated XSD schemas + TransformerFactory tFactory = TransformerFactory.newInstance(); + Transformer transformer; + try { + transformer = tFactory.newTransformer(); + } catch (TransformerConfigurationException e1) { + CSARExporter.logger.debug(e1.getMessage(), e1); + throw new IllegalStateException("Could not instantiate transformer", e1); + } + + // write all referenced files + for (RepositoryFileReference ref : refMap.keySet()) { + String archivePath = refMap.get(ref); + ArchiveEntry archiveEntry = new ZipArchiveEntry(archivePath); + zos.putArchiveEntry(archiveEntry); + if (ref instanceof DummyRepositoryFileReferenceForGeneratedXSD) { + // special treatment for generated XSDs + Document document = ((DummyRepositoryFileReferenceForGeneratedXSD) ref).getDocument(); + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(zos); + try { + transformer.transform(source, result); + } catch (TransformerException e) { + CSARExporter.logger.debug("Could not serialize generated xsd", e); + } + } else { + try (InputStream is = Repository.INSTANCE.newInputStream(ref)) { + IOUtils.copy(is, zos); + } catch (Exception e) { + CSARExporter.logger.error("Could not copy file content to ZIP outputstream", e); + } + } + zos.closeArchiveEntry(); + } + + this.addNamespacePrefixes(zos); + + zos.finish(); + zos.close(); + } + + /** + * Writes the configured mapping namespaceprefix -> namespace to the archive + * + * This is kind of a quick hack. TODO: during the import, the prefixes + * should be extracted using JAXB and stored in the NamespacesResource + * + * @throws IOException + */ + private void addNamespacePrefixes(ArchiveOutputStream zos) throws IOException { + Configuration configuration = Repository.INSTANCE.getConfiguration(new NamespacesId()); + if (configuration instanceof PropertiesConfiguration) { + // Quick hack: direct serialization only works for PropertiesConfiguration + PropertiesConfiguration pconf = (PropertiesConfiguration) configuration; + ArchiveEntry archiveEntry = new ZipArchiveEntry(CSARExporter.PATH_TO_NAMESPACES_PROPERTIES); + zos.putArchiveEntry(archiveEntry); + try { + pconf.save(zos); + } catch (ConfigurationException e) { + CSARExporter.logger.debug(e.getMessage(), e); + zos.write("#Could not export properties".getBytes()); + zos.write(("#" + e.getMessage()).getBytes()); + } + zos.closeArchiveEntry(); + } + } + + private void addSelfServiceMetaData(ServiceTemplateId entryId, Map refMap) { + SelfServiceMetaDataId id = new SelfServiceMetaDataId(entryId); + if (Repository.INSTANCE.exists(id)) { + SelfServicePortalResource res = new SelfServicePortalResource(entryId); + + refMap.put(res.data_xml_ref, Constants.DIRNAME_SELF_SERVICE_METADATA + "/" + "data.xml"); + + // The schema says that the images have to exist + // However, at a quick modeling, there might be no images + // Therefore, we check for existence + if (Repository.INSTANCE.exists(res.icon_jpg_ref)) { + refMap.put(res.icon_jpg_ref, Constants.DIRNAME_SELF_SERVICE_METADATA + "/" + "icon.jpg"); + } + if (Repository.INSTANCE.exists(res.image_jpg_ref)) { + refMap.put(res.image_jpg_ref, Constants.DIRNAME_SELF_SERVICE_METADATA + "/" + "image.jpg"); + } + + Application application = res.getApplication(); + Options options = application.getOptions(); + if (options != null) { + for (ApplicationOption option : options.getOption()) { + String url = option.getIconUrl(); + if (Util.isRelativeURI(url)) { + RepositoryFileReference ref = new RepositoryFileReference(id, url); + if (Repository.INSTANCE.exists(ref)) { + refMap.put(ref, Constants.DIRNAME_SELF_SERVICE_METADATA + "/" + url); + } else { + CSARExporter.logger.error("Data corrupt: pointing to non-existent file " + ref); + } + } + + url = option.getPlanInputMessageUrl(); + if (Util.isRelativeURI(url)) { + RepositoryFileReference ref = new RepositoryFileReference(id, url); + if (Repository.INSTANCE.exists(ref)) { + refMap.put(ref, Constants.DIRNAME_SELF_SERVICE_METADATA + "/" + url); + } else { + CSARExporter.logger.error("Data corrupt: pointing to non-existent file " + ref); + } + } + } + } + } + } + + private void addManifest(TOSCAComponentId id, Collection definitionNames, Map refMap, ArchiveOutputStream out) throws IOException { + String entryDefinitionsReference = CSARExporter.getDefinitionsPathInsideCSAR(id); + + out.putArchiveEntry(new ZipArchiveEntry("TOSCA-Metadata/TOSCA.meta")); + PrintWriter pw = new PrintWriter(out); + // Setting Versions + pw.println("TOSCA-Meta-Version: 1.0"); + pw.println("CSAR-Version: 1.0"); + String versionString = "Created-By: Winery " + Prefs.INSTANCE.getVersion(); + pw.println(versionString); + // Winery currently is unaware of tDefinitions, therefore, we use the + // name of the service template + pw.println("Entry-Definitions: " + entryDefinitionsReference); + pw.println(); + + assert (definitionNames.contains(entryDefinitionsReference)); + for (String name : definitionNames) { + pw.println("Name: " + name); + pw.println("Content-Type: " + org.eclipse.winery.common.constants.MimeTypes.MIMETYPE_TOSCA_DEFINITIONS); + pw.println(); + } + + // Setting other files, mainly files belonging to artifacts + for (RepositoryFileReference ref : refMap.keySet()) { + String archivePath = refMap.get(ref); + pw.println("Name: " + archivePath); + String mimeType; + if (ref instanceof DummyRepositoryFileReferenceForGeneratedXSD) { + mimeType = MimeTypes.MIMETYPE_XSD; + } else { + mimeType = Repository.INSTANCE.getMimeType(ref); + } + pw.println("Content-Type: " + mimeType); + pw.println(); + } + pw.flush(); + out.closeArchiveEntry(); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/DummyParentForGeneratedXSDRef.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/DummyParentForGeneratedXSDRef.java new file mode 100644 index 0000000000..05c7ce1a30 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/DummyParentForGeneratedXSDRef.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.export; + +import org.eclipse.winery.common.ids.GenericId; +import org.eclipse.winery.common.ids.XMLId; + +public class DummyParentForGeneratedXSDRef extends GenericId { + + protected DummyParentForGeneratedXSDRef() { + super(new XMLId("dummy", false)); + } + + @Override + public int compareTo(GenericId o) { + throw new IllegalStateException("Should never be called."); + } + + @Override + public GenericId getParent() { + throw new IllegalStateException("Should never be called."); + } + + @Override + public boolean equals(Object obj) { + return (obj instanceof DummyParentForGeneratedXSDRef); + } + + @Override + public int hashCode() { + return 0; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/DummyRepositoryFileReferenceForGeneratedXSD.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/DummyRepositoryFileReferenceForGeneratedXSD.java new file mode 100644 index 0000000000..fe4cba42af --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/DummyRepositoryFileReferenceForGeneratedXSD.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.export; + +import org.eclipse.winery.common.RepositoryFileReference; +import org.w3c.dom.Document; + +/** + * Class used to indicate reference to a generated XSD + */ +public class DummyRepositoryFileReferenceForGeneratedXSD extends RepositoryFileReference { + + private final Document document; + + + /** + * @param document the W3C DOM Document holding the generated XSD + */ + public DummyRepositoryFileReferenceForGeneratedXSD(Document document) { + super(new DummyParentForGeneratedXSDRef(), "xsd"); + this.document = document; + } + + public Document getDocument() { + return this.document; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/ExportedState.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/ExportedState.java new file mode 100644 index 0000000000..609d4d64e9 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/ExportedState.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.export; + +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.HashSet; +import java.util.Queue; + +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; + +/** + * Holds the state of ids regarding the export
+ * + * Required as we do not know at the entry point (usually a service template), + * which other components are linked
+ * + * Users can call flagAsExportRequired more than once for the same id. If an id + * is already exported, it is not flagged as exported again + */ +public class ExportedState { + + private final Collection exported = new HashSet<>(); + private final Queue exportRequired = new ArrayDeque<>(); + + + /** + * @return the first tosca component id to be exported, null if no more + * elements are in the queue + */ + public TOSCAComponentId pop() { + return this.exportRequired.poll(); + } + + public void flagAsExported(TOSCAComponentId id) { + this.exportRequired.remove(id); + this.exported.add(id); + } + + /** + * Flags the given id as required for export, if not already exported + * + * @param id the id to flag + */ + public void flagAsExportRequired(TOSCAComponentId id) { + if (!this.exported.contains(id)) { + this.exportRequired.add(id); + } + } + + public void flagAsExportRequired(Collection ids) { + for (TOSCAComponentId id : ids) { + if ((!this.exported.contains(id)) && (!this.exportRequired.contains(id))) { + this.exportRequired.add(id); + } + } + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/TOSCAExportUtil.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/TOSCAExportUtil.java new file mode 100644 index 0000000000..6bfe624c82 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/export/TOSCAExportUtil.java @@ -0,0 +1,789 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Kálmán Képes - initial API and implementation and/or initial documentation + * Oliver Kopp - adapted to new storage model and to TOSCA v1.0 + *******************************************************************************/ +package org.eclipse.winery.repository.export; + +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; + +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.namespace.QName; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.constants.QNames; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.definitions.ArtifactTypeId; +import org.eclipse.winery.common.ids.definitions.CapabilityTypeId; +import org.eclipse.winery.common.ids.definitions.EntityTypeId; +import org.eclipse.winery.common.ids.definitions.NodeTypeId; +import org.eclipse.winery.common.ids.definitions.NodeTypeImplementationId; +import org.eclipse.winery.common.ids.definitions.PolicyTemplateId; +import org.eclipse.winery.common.ids.definitions.PolicyTypeId; +import org.eclipse.winery.common.ids.definitions.RelationshipTypeId; +import org.eclipse.winery.common.ids.definitions.RelationshipTypeImplementationId; +import org.eclipse.winery.common.ids.definitions.RequirementTypeId; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.common.ids.definitions.TopologyGraphElementEntityTypeId; +import org.eclipse.winery.common.ids.definitions.imports.GenericImportId; +import org.eclipse.winery.common.ids.elements.PlanId; +import org.eclipse.winery.common.ids.elements.PlansId; +import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition; +import org.eclipse.winery.model.tosca.Definitions; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions.Policies; +import org.eclipse.winery.model.tosca.TCapability; +import org.eclipse.winery.model.tosca.TCapabilityDefinition; +import org.eclipse.winery.model.tosca.TDeploymentArtifact; +import org.eclipse.winery.model.tosca.TDeploymentArtifacts; +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.model.tosca.TEntityType; +import org.eclipse.winery.model.tosca.TEntityType.PropertiesDefinition; +import org.eclipse.winery.model.tosca.TImplementationArtifact; +import org.eclipse.winery.model.tosca.TImplementationArtifacts; +import org.eclipse.winery.model.tosca.TImport; +import org.eclipse.winery.model.tosca.TNodeTemplate; +import org.eclipse.winery.model.tosca.TNodeTemplate.Capabilities; +import org.eclipse.winery.model.tosca.TNodeTemplate.Requirements; +import org.eclipse.winery.model.tosca.TNodeType; +import org.eclipse.winery.model.tosca.TNodeType.CapabilityDefinitions; +import org.eclipse.winery.model.tosca.TNodeType.RequirementDefinitions; +import org.eclipse.winery.model.tosca.TPolicy; +import org.eclipse.winery.model.tosca.TRelationshipTemplate; +import org.eclipse.winery.model.tosca.TRelationshipType; +import org.eclipse.winery.model.tosca.TRelationshipType.ValidSource; +import org.eclipse.winery.model.tosca.TRelationshipType.ValidTarget; +import org.eclipse.winery.model.tosca.TRequirement; +import org.eclipse.winery.model.tosca.TRequirementDefinition; +import org.eclipse.winery.repository.JAXBSupport; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.backend.constants.Filename; +import org.eclipse.winery.repository.datatypes.ids.elements.ArtifactTemplateDirectoryId; +import org.eclipse.winery.repository.datatypes.ids.elements.VisualAppearanceId; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal; +import org.eclipse.winery.repository.resources.AbstractComponentsResource; +import org.eclipse.winery.repository.resources.EntityTypeResource; +import org.eclipse.winery.repository.resources.entitytemplates.artifacttemplates.ArtifactTemplateResource; +import org.eclipse.winery.repository.resources.entitytemplates.policytemplates.PolicyTemplateResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.nodetypeimplementations.NodeTypeImplementationResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.relationshiptypeimplementations.RelationshipTypeImplementationResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; +import org.eclipse.winery.repository.resources.entitytypes.relationshiptypes.RelationshipTypeResource; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; +import org.w3c.dom.Document; + +public class TOSCAExportUtil { + + private static final XLogger logger = XLoggerFactory.getXLogger(TOSCAExportUtil.class); + + /* + * these two are GLOBAL VARIABLES leading to the fact that this class has to + * be constructed for each export + */ + + // collects the references to be put in the CSAR and the assigned path in + // the CSAR MANIFEST + // this allows to use other paths in the CSAR than on the local storage + private Map referencesToPathInCSARMap = null; + + /** + * Currently a very simple approach to configure the export + */ + private Map exportConfiguration; + + + public enum ExportProperties { + INCLUDEXYCOORDINATES, REPOSITORY_URI + }; + + + /** + * Writes the complete tosca xml into the given outputstream + * + * @param id the id of the TOSCA component instance to export + * @param out outputstream to write to + * @param addRelatedComponents true: all referenced components + * (artifactTemplates, artifactTypes, ...) are added, false: only + * the XML belonging to the id is exported. If XML types are + * generated by Winery (e.g., the properties XSD for node types), + * these XML types are also exported + * @param exportConfiguration the configuration map for the export. Uses + * @param exportedState exportedState object to modify. ExportProperties + * provides the possible keys + * @return a collection of TOSCAcomponentIds referenced by the given + * component + * @throws JAXBException + */ + public Collection exportTOSCA(TOSCAComponentId id, OutputStream out, Map exportConfiguration) throws IOException, JAXBException { + this.exportConfiguration = exportConfiguration; + this.initializeExport(); + return this.writeDefinitionsElement(id, out); + } + + private void initializeExport() { + this.setDefaultExportConfiguration(); + // quick hack to avoid NPE + if (this.referencesToPathInCSARMap == null) { + this.referencesToPathInCSARMap = new HashMap<>(); + } + } + + /** + * Quick hack to set defaults. Typically, a configuration builder or similar + * is used + */ + private void setDefaultExportConfiguration() { + this.checkConfig(ExportProperties.INCLUDEXYCOORDINATES, Boolean.FALSE); + } + + private void checkConfig(ExportProperties propKey, Boolean bo) { + if (!this.exportConfiguration.containsKey(propKey.toString())) { + this.exportConfiguration.put(propKey.toString(), bo); + } + } + + /** + * Writes the complete TOSCA XML into the given outputstream. + * Additionally, a the artifactMap is filled to enable the CSAR exporter to + * create necessary entries in TOSCA-Meta and to add them to the CSAR itself + * + * @param id the component instance to export + * @param out outputstream to write to + * @param exportConfiguration Configures the exporter + * @param referencesToPathInCSARMap collects the references to export. It is + * updated during the export + * @return a collection of TOSCAcomponentIds referenced by the given + * component + * @throws JAXBException + */ + protected Collection exportTOSCA(TOSCAComponentId id, OutputStream out, Map referencesToPathInCSARMap, Map exportConfiguration) throws IOException, JAXBException { + this.referencesToPathInCSARMap = referencesToPathInCSARMap; + return this.exportTOSCA(id, out, exportConfiguration); + } + + /** + * Called when the entry resource is definitions backed + * + * @throws JAXBException + */ + private void writeDefinitionsElement(Definitions entryDefinitions, OutputStream out) throws JAXBException { + Marshaller m = JAXBSupport.createMarshaller(true); + m.marshal(entryDefinitions, out); + } + + /** + * Writes the Definitions belonging to the given TOSCA component to the + * outputstream + * + * @return a collection of TOSCAcomponentIds referenced by the given + * component + * + * @throws IOException + * @throws JAXBException + * @throws IllegalStateException if tcId does not exist + */ + private Collection writeDefinitionsElement(TOSCAComponentId tcId, OutputStream out) throws IOException, JAXBException { + if (!Repository.INSTANCE.exists(tcId)) { + throw new IllegalStateException("Component instance " + tcId.toString() + " does not exist."); + } + + AbstractComponentInstanceResource res = AbstractComponentsResource.getComponentInstaceResource(tcId); + Definitions entryDefinitions = res.getDefinitions(); + + // BEGIN: Definitions modification + // the "imports" collection contains the imports of Definitions, not of other definitions + // the other definitions are stored in entryDefinitions.getImport() + // we modify the internal definitions object directly. It is not written back to the storage. Therefore, we do not need to clone it + + // the imports (pointing to not-definitions (xsd, wsdl, ...)) already have a correct relative URL. (quick hack) + URI uri = (URI) this.exportConfiguration.get(TOSCAExportUtil.ExportProperties.REPOSITORY_URI.toString()); + if (uri != null) { + // we are in the plain-XML mode, the URLs of the imports have to be adjusted + for (TImport i : entryDefinitions.getImport()) { + String loc = i.getLocation(); + assert (loc.startsWith("../")); + loc = loc.substring(3); + loc = uri + loc; + // now the location is an absolute URL + i.setLocation(loc); + } + } + + // files of imports have to be added to the CSAR, too + for (TImport i : entryDefinitions.getImport()) { + String loc = i.getLocation(); + if (Util.isRelativeURI(loc)) { + // locally stored, add to CSAR + GenericImportId iid = new GenericImportId(i); + String fileName = Util.getLastURIPart(loc); + fileName = Util.URLdecode(fileName); + RepositoryFileReference ref = new RepositoryFileReference(iid, fileName); + this.putRefAsReferencedItemInCSAR(ref); + } + } + + // adjust imports: add imports of definitions to it + Collection referencedTOSCAComponentIds = this.getReferencedTOSCAComponentIds(tcId); + Collection imports = new ArrayList<>(); + for (TOSCAComponentId id : referencedTOSCAComponentIds) { + this.addToImports(id, imports); + } + entryDefinitions.getImport().addAll(imports); + + if (res.getElement() instanceof TEntityType) { + // we have an entity type with a possible properties definition + EntityTypeResource entityTypeRes = (EntityTypeResource) res; + WinerysPropertiesDefinition wpd = ModelUtilities.getWinerysPropertiesDefinition(entityTypeRes.getEntityType()); + if (wpd != null) { + if (wpd.getIsDerivedFromXSD() == null) { + // Write WPD only to file if it exists and is NOT derived from an XSD (which may happen during import) + + String wrapperElementNamespace = wpd.getNamespace(); + String wrapperElementLocalName = wpd.getElementName(); + + // BEGIN: add import and put into CSAR + + TImport imp = new TImport(); + entryDefinitions.getImport().add(imp); + + // fill known import values + imp.setImportType(XMLConstants.W3C_XML_SCHEMA_NS_URI); + imp.setNamespace(wrapperElementNamespace); + // add "winerysPropertiesDefinition" flag to import tag to support + Map otherAttributes = imp.getOtherAttributes(); + otherAttributes.put(QNames.QNAME_WINERYS_PROPERTIES_DEFINITION_ATTRIBUTE, "true"); + + // Determine location + String loc = BackendUtils.getImportLocationForWinerysPropertiesDefinitionXSD((EntityTypeId) tcId, uri, wrapperElementLocalName); + if (uri == null) { + // CSAR Export mode + // XSD has to be put into the CSAR + Document document = ModelUtilities.getWinerysPropertiesDefinitionXSDAsDocument(wpd); + + // loc in import is URLencoded, loc on filesystem isn't + String locInCSAR = Util.URLdecode(loc); + // furthermore, the path has to start from the root of the CSAR; currently, it starts from Definitions/ + locInCSAR = locInCSAR.substring(3); + this.referencesToPathInCSARMap.put(new DummyRepositoryFileReferenceForGeneratedXSD(document), locInCSAR); + } + imp.setLocation(loc); + + // END: add import and put into CSAR + + // BEGIN: generate TOSCA conforming PropertiesDefinition + + TEntityType entityType = entityTypeRes.getEntityType(); + PropertiesDefinition propertiesDefinition = new PropertiesDefinition(); + propertiesDefinition.setType(new QName(wrapperElementNamespace, wrapperElementLocalName)); + entityType.setPropertiesDefinition(propertiesDefinition); + + // END: generate TOSCA conforming PropertiesDefinition + } else { + // otherwise WPD exists, but is derived from XSD + // we DO NOT have to remove the winery properties definition from the output to allow "debugging" of the CSAR + } + } + } + + // END: Definitions modification + + this.writeDefinitionsElement(entryDefinitions, out); + + return referencedTOSCAComponentIds; + } + + private Collection getReferencedTOSCAComponentIds(EntityTypeId id) { + return this.getReferencedTOSCAComponentIdOfParentForAnAbstractComponentsWithTypeReferenceResource(id); + } + + /** + * There is now equivalent id class for + * AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal, + * therefore we take the super type and hope that the caller knows what he + * does. + */ + private Collection getReferencedTOSCAComponentIdOfParentForAnAbstractComponentsWithTypeReferenceResource(TOSCAComponentId id) { + AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal res = (AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal) AbstractComponentsResource.getComponentInstaceResource(id); + String derivedFrom = res.getInheritanceManagement().getDerivedFrom(); + if (StringUtils.isEmpty(derivedFrom)) { + return Collections.emptySet(); + } else { + // Instantiate an id with the same class as the current id + TOSCAComponentId parentId; + QName qname = QName.valueOf(derivedFrom); + + Constructor constructor; + try { + constructor = id.getClass().getConstructor(QName.class); + } catch (NoSuchMethodException | SecurityException e1) { + throw new IllegalStateException("Could get constructor to instantiate parent id", e1); + } + try { + parentId = constructor.newInstance(qname); + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + throw new IllegalStateException("Could not instantiate id for parent", e); + } + + Collection result = new ArrayList<>(1); + result.add(parentId); + return result; + } + } + + /** + * This method is intended to be used by exportTOSCA. However, + * org.eclipse.winery.repository.client requires an XML representation of a + * component instances without a surrounding definitions element. + * + * We name this method differently to prevent wrong calling due to + * inheritance + * + * @param definitionsElement the parent XML element + */ + private Collection getReferencedTOSCAComponentIds(TOSCAComponentId id) { + Collection referencedTOSCAComponentIds; + + // first of all, handle the concrete elements + if (id instanceof ServiceTemplateId) { + referencedTOSCAComponentIds = this.prepareForExport((ServiceTemplateId) id); + } else if (id instanceof NodeTypeId) { + referencedTOSCAComponentIds = this.getReferencedTOSCAComponentIds((NodeTypeId) id); + } else if (id instanceof NodeTypeImplementationId) { + referencedTOSCAComponentIds = this.getReferencedTOSCAComponentIds((NodeTypeImplementationId) id); + } else if (id instanceof RelationshipTypeId) { + referencedTOSCAComponentIds = this.getReferencedTOSCAComponentIds((RelationshipTypeId) id); + } else if (id instanceof RelationshipTypeImplementationId) { + referencedTOSCAComponentIds = this.getReferencedTOSCAComponentIds((RelationshipTypeImplementationId) id); + } else if (id instanceof RequirementTypeId) { + referencedTOSCAComponentIds = this.getReferencedTOSCAComponentIds((RequirementTypeId) id); + } else if (id instanceof CapabilityTypeId) { + referencedTOSCAComponentIds = this.getReferencedTOSCAComponentIds((CapabilityTypeId) id); + } else if (id instanceof ArtifactTypeId) { + referencedTOSCAComponentIds = this.getReferencedTOSCAComponentIds((ArtifactTypeId) id); + } else if (id instanceof ArtifactTemplateId) { + referencedTOSCAComponentIds = this.prepareForExport((ArtifactTemplateId) id); + } else if (id instanceof PolicyTypeId) { + referencedTOSCAComponentIds = this.getReferencedTOSCAComponentIds((PolicyTypeId) id); + } else if (id instanceof PolicyTemplateId) { + referencedTOSCAComponentIds = this.getReferencedTOSCAComponentIds((PolicyTemplateId) id); + } else if (id instanceof GenericImportId) { + // in case of imports, there are no other ids referenced + referencedTOSCAComponentIds = Collections.emptyList(); + } else { + throw new IllegalStateException("Unhandled id class " + id.getClass()); + } + + // Then, handle the super classes, which support inheritance + // Currently, it is EntityType and EntityTypeImplementation only + // Since the latter does not exist in the TOSCA MetaModel, we just handle EntityType here + if (id instanceof EntityTypeId) { + Collection additionalRefs = this.getReferencedTOSCAComponentIds((EntityTypeId) id); + // the original referenceTOSCAComponentIds could be unmodifiable + // we just create a new one... + referencedTOSCAComponentIds = new ArrayList<>(referencedTOSCAComponentIds); + // ...and add the new reference + referencedTOSCAComponentIds.addAll(additionalRefs); + } + + return referencedTOSCAComponentIds; + } + + /** + * Adds the given id as import to the given imports collection + */ + private void addToImports(TOSCAComponentId id, Collection imports) { + TImport imp = new TImport(); + imp.setImportType(org.eclipse.winery.common.constants.Namespaces.TOSCA_NAMESPACE); + imp.setNamespace(id.getNamespace().getDecoded()); + URI uri = (URI) this.exportConfiguration.get(TOSCAExportUtil.ExportProperties.REPOSITORY_URI.toString()); + if (uri == null) { + // self-contained mode + // all Definitions are contained in "Definitions" directory, therefore, we provide the filename only + // references are resolved relatively from a definitions element (COS01, line 425) + String fn = CSARExporter.getDefinitionsFileName(id); + fn = Util.URLencode(fn); + imp.setLocation(fn); + } else { + String path = Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(id)); + path = path + "?definitions"; + URI absoluteURI = uri.resolve(path); + imp.setLocation(absoluteURI.toString()); + } + imports.add(imp); + + // FIXME: Currently the depended elements (such as the artifact templates linked to a node type implementation) are gathered by the corresponding "addXY" method. + // Reason: the corresponding TDefinitions element is *not* updated if a related element is added/removed. + // That means: The imports are not changed. + // The current issue is that TOSCA allows imports of Definitions only and the repository has the concrete elements as main structure + // Although during save the import can be updated (by fetching the associated resource and get the definitions of it), + // The concrete definitions cannot be determined without + // a) having a complete index of all definitions in the repository + // b) crawling through the *complete* repository + // Possibly the current solution, just lazily adding all dependent elements is the better solution. + } + + private Collection getReferencedTOSCAComponentIds(NodeTypeImplementationId id) { + // We have to use a HashSet to ensure that no duplicate ids are added + // There may be multiple DAs/IAs referencing the same type + Collection ids = new HashSet<>(); + + NodeTypeImplementationResource res = new NodeTypeImplementationResource(id); + + // DAs + TDeploymentArtifacts deploymentArtifacts = res.getNTI().getDeploymentArtifacts(); + if (deploymentArtifacts != null) { + for (TDeploymentArtifact da : deploymentArtifacts.getDeploymentArtifact()) { + QName qname; + if ((qname = da.getArtifactRef()) != null) { + ids.add(new ArtifactTemplateId(qname)); + } + ids.add(new ArtifactTypeId(da.getArtifactType())); + } + } + + // IAs + TImplementationArtifacts implementationArtifacts = res.getNTI().getImplementationArtifacts(); + if (implementationArtifacts != null) { + for (TImplementationArtifact ia : implementationArtifacts.getImplementationArtifact()) { + QName qname; + if ((qname = ia.getArtifactRef()) != null) { + ids.add(new ArtifactTemplateId(qname)); + } + ids.add(new ArtifactTypeId(ia.getArtifactType())); + } + } + + // inheritance + ids.addAll(this.getReferencedTOSCAComponentIdOfParentForAnAbstractComponentsWithTypeReferenceResource(id)); + + return ids; + } + + private Collection getReferencedTOSCAComponentIds(RelationshipTypeImplementationId id) { + // We have to use a HashSet to ensure that no duplicate ids are added + // There may be multiple IAs referencing the same type + Collection ids = new HashSet<>(); + + RelationshipTypeImplementationResource res = new RelationshipTypeImplementationResource(id); + + // IAs + for (TImplementationArtifact ia : res.getRTI().getImplementationArtifacts().getImplementationArtifact()) { + QName qname; + if ((qname = ia.getArtifactRef()) != null) { + ids.add(new ArtifactTemplateId(qname)); + } + ids.add(new ArtifactTypeId(ia.getArtifactType())); + } + + // inheritance + ids.addAll(this.getReferencedTOSCAComponentIdOfParentForAnAbstractComponentsWithTypeReferenceResource(id)); + + return ids; + } + + private Collection getReferencedTOSCAComponentIds(RequirementTypeId id) { + return Collections.emptyList(); + } + + private Collection getReferencedTOSCAComponentIds(CapabilityTypeId id) { + return Collections.emptyList(); + } + + private Collection getReferencedTOSCAComponentIds(PolicyTypeId id) { + return Collections.emptyList(); + } + + private Collection getReferencedTOSCAComponentIds(PolicyTemplateId id) { + Collection ids = new ArrayList<>(); + PolicyTemplateResource res = new PolicyTemplateResource(id); + ids.add(new PolicyTypeId(res.getType())); + return ids; + } + + /** + * Synchronizes the plan model references and returns the referenced TOSCA + * Component Ids. + */ + private Collection prepareForExport(ServiceTemplateId id) { + // We have to use a HashSet to ensure that no duplicate ids are added + // E.g., there may be multiple relationship templates having the same type + Collection ids = new HashSet<>(); + ServiceTemplateResource res = new ServiceTemplateResource(id); + + // ensure that the plans stored locally are the same ones as stored in the definitions + res.synchronizeReferences(); + + // add all plans as reference in the CSAR + // the data model is consistent with the repository + // we crawl through the repository to as putRefAsReferencedItemInCSAR expects a repository file reference + PlansId plansContainerId = new PlansId(id); + SortedSet nestedPlans = Repository.INSTANCE.getNestedIds(plansContainerId, PlanId.class); + for (PlanId planId : nestedPlans) { + SortedSet containedFiles = Repository.INSTANCE.getContainedFiles(planId); + // even if we currently support only one file in the directory, we just add everything + for (RepositoryFileReference ref : containedFiles) { + this.putRefAsReferencedItemInCSAR(ref); + } + } + + // add included things to export queue + + TBoundaryDefinitions boundaryDefs; + if ((boundaryDefs = res.getServiceTemplate().getBoundaryDefinitions()) != null) { + Policies policies = boundaryDefs.getPolicies(); + if (policies != null) { + for (TPolicy policy : policies.getPolicy()) { + PolicyTypeId policyTypeId = new PolicyTypeId(policy.getPolicyType()); + ids.add(policyTypeId); + } + } + + // reqs and caps don't have to be exported here as they are references to existing reqs/caps (of nested node templates) + } + + if (res.getServiceTemplate().getTopologyTemplate() != null) { + for (TEntityTemplate entityTemplate : res.getServiceTemplate().getTopologyTemplate().getNodeTemplateOrRelationshipTemplate()) { + QName qname = entityTemplate.getType(); + if (entityTemplate instanceof TNodeTemplate) { + ids.add(new NodeTypeId(qname)); + TNodeTemplate n = (TNodeTemplate) entityTemplate; + + // crawl through deployment artifacts + TDeploymentArtifacts deploymentArtifacts = n.getDeploymentArtifacts(); + if (deploymentArtifacts != null) { + List das = deploymentArtifacts.getDeploymentArtifact(); + for (TDeploymentArtifact da : das) { + ids.add(new ArtifactTypeId(da.getArtifactType())); + if ((qname = da.getArtifactRef()) != null) { + ids.add(new ArtifactTemplateId(qname)); + } + } + } + + // crawl through reqs/caps + Requirements requirements = n.getRequirements(); + if (requirements != null) { + for (TRequirement req : requirements.getRequirement()) { + QName type = req.getType(); + RequirementTypeId rtId = new RequirementTypeId(type); + ids.add(rtId); + } + } + Capabilities capabilities = n.getCapabilities(); + if (capabilities != null) { + for (TCapability cap : capabilities.getCapability()) { + QName type = cap.getType(); + CapabilityTypeId ctId = new CapabilityTypeId(type); + ids.add(ctId); + } + } + + // crawl through policies + org.eclipse.winery.model.tosca.TNodeTemplate.Policies policies = n.getPolicies(); + if (policies != null) { + for (TPolicy pol : policies.getPolicy()) { + QName type = pol.getPolicyType(); + PolicyTypeId ctId = new PolicyTypeId(type); + ids.add(ctId); + } + } + } else { + assert (entityTemplate instanceof TRelationshipTemplate); + ids.add(new RelationshipTypeId(qname)); + } + } + } + + return ids; + } + + private Collection getReferencedTOSCAComponentIds(ArtifactTypeId id) { + // no recursive crawling needed + return Collections.emptyList(); + } + + /** + * Determines the referenced TOSCA Component Ids and also updates the + * references in the Artifact Template + * + * @return a collection of referenced TOCSA Component Ids + */ + private Collection prepareForExport(ArtifactTemplateId id) { + Collection ids = new ArrayList<>(); + + ArtifactTemplateResource res = new ArtifactTemplateResource(id); + + // "Export" type + QName type = res.getType(); + if (type == null) { + throw new IllegalStateException("Type is null for " + id.toString()); + } + ids.add(new ArtifactTypeId(type)); + + // Export files + + // This method is called BEFORE the concrete definitions element is written. + // Therefore, we adapt the content of the attached files to the really existing files + res.synchronizeReferences(); + + ArtifactTemplateDirectoryId fileDir = new ArtifactTemplateDirectoryId(id); + SortedSet files = Repository.INSTANCE.getContainedFiles(fileDir); + for (RepositoryFileReference ref : files) { + // Even if writing a TOSCA only (!this.writingCSAR), + // we put the virtual path in the TOSCA + // Reason: Winery is mostly used as a service and local storage + // reference to not make sense + // The old implementation had absolutePath.toUri().toString(); + // there, but this does not work when using a cloud blob store. + + this.putRefAsReferencedItemInCSAR(ref); + } + + return ids; + } + + /** + * Puts the given reference as item in the CSAR + * + * Thereby, it uses the global variable referencesToPathInCSARMap + */ + private void putRefAsReferencedItemInCSAR(RepositoryFileReference ref) { + // Determine path + String path = BackendUtils.getPathInsideRepo(ref); + + // put mapping reference to path into global map + // the path is the same as put in "synchronizeReferences" + this.referencesToPathInCSARMap.put(ref, path); + } + + private Collection getReferencedTOSCAComponentIds(RelationshipTypeId id) { + Collection ids = new ArrayList<>(); + + // add all implementations + Collection allTypeImplementations = BackendUtils.getAllElementsRelatedWithATypeAttribute(RelationshipTypeImplementationId.class, id.getQName()); + for (RelationshipTypeImplementationId ntiId : allTypeImplementations) { + ids.add(ntiId); + } + + RelationshipTypeResource res = new RelationshipTypeResource(id); + TRelationshipType relationshipType = (TRelationshipType) res.getElement(); + + ValidSource validSource = relationshipType.getValidSource(); + if (validSource != null) { + QName typeRef = validSource.getTypeRef(); + // can be a node type or a requirement type + + // similar code as for valid target (difference: req/cap) + NodeTypeId ntId = new NodeTypeId(typeRef); + if (Repository.INSTANCE.exists(ntId)) { + ids.add(ntId); + } else { + RequirementTypeId rtId = new RequirementTypeId(typeRef); + ids.add(rtId); + } + } + + ValidTarget validTarget = relationshipType.getValidTarget(); + if (validTarget != null) { + QName typeRef = validTarget.getTypeRef(); + // can be a node type or a capability type + + // similar code as for valid target (difference: req/cap) + NodeTypeId ntId = new NodeTypeId(typeRef); + if (Repository.INSTANCE.exists(ntId)) { + ids.add(ntId); + } else { + CapabilityTypeId capId = new CapabilityTypeId(typeRef); + ids.add(capId); + } + } + + this.addVisualAppearanceToCSAR(id); + + return ids; + } + + private Collection getReferencedTOSCAComponentIds(NodeTypeId id) { + Collection ids = new ArrayList<>(); + Collection allNodeTypeImplementations = BackendUtils.getAllElementsRelatedWithATypeAttribute(NodeTypeImplementationId.class, id.getQName()); + for (NodeTypeImplementationId ntiId : allNodeTypeImplementations) { + ids.add(ntiId); + } + + NodeTypeResource res = new NodeTypeResource(id); + TNodeType nodeType = (TNodeType) res.getElement(); + + // add all referenced requirement types + RequirementDefinitions reqDefsContainer = nodeType.getRequirementDefinitions(); + if (reqDefsContainer != null) { + List reqDefs = reqDefsContainer.getRequirementDefinition(); + for (TRequirementDefinition reqDef : reqDefs) { + RequirementTypeId reqTypeId = new RequirementTypeId(reqDef.getRequirementType()); + ids.add(reqTypeId); + } + } + + // add all referenced capability types + CapabilityDefinitions capDefsContainer = nodeType.getCapabilityDefinitions(); + if (capDefsContainer != null) { + List capDefs = capDefsContainer.getCapabilityDefinition(); + for (TCapabilityDefinition capDef : capDefs) { + CapabilityTypeId capTypeId = new CapabilityTypeId(capDef.getCapabilityType()); + ids.add(capTypeId); + } + } + + this.addVisualAppearanceToCSAR(id); + + return ids; + } + + private void addVisualAppearanceToCSAR(TopologyGraphElementEntityTypeId id) { + VisualAppearanceId visId = new VisualAppearanceId(id); + if (Repository.INSTANCE.exists(visId)) { + // we do NOT check for the id, but simply check for bigIcon.png (only exists in NodeType) and smallIcon.png (exists in NodeType and RelationshipType) + + RepositoryFileReference ref = new RepositoryFileReference(visId, Filename.FILENAME_BIG_ICON); + if (Repository.INSTANCE.exists(ref)) { + this.referencesToPathInCSARMap.put(ref, BackendUtils.getPathInsideRepo(ref)); + } + + ref = new RepositoryFileReference(visId, Filename.FILENAME_SMALL_ICON); + if (Repository.INSTANCE.exists(ref)) { + this.referencesToPathInCSARMap.put(ref, BackendUtils.getPathInsideRepo(ref)); + } + } + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/importing/CSARImporter.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/importing/CSARImporter.java new file mode 100644 index 0000000000..9d02e397de --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/importing/CSARImporter.java @@ -0,0 +1,1070 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Kálmán Képes - initial API and implementation and/or initial documentation + * Oliver Kopp - adapted to new storage model and to TOSCA v1.0 + *******************************************************************************/ +package org.eclipse.winery.repository.importing; + +import static java.nio.file.FileVisitResult.CONTINUE; +import static java.nio.file.FileVisitResult.SKIP_SUBTREE; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import javax.ws.rs.core.MediaType; +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.io.FilenameUtils; +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.constants.MimeTypes; +import org.eclipse.winery.common.constants.Namespaces; +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.definitions.EntityTypeId; +import org.eclipse.winery.common.ids.definitions.NodeTypeId; +import org.eclipse.winery.common.ids.definitions.RelationshipTypeId; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.common.ids.definitions.imports.GenericImportId; +import org.eclipse.winery.common.ids.definitions.imports.XSDImportId; +import org.eclipse.winery.common.ids.elements.PlanId; +import org.eclipse.winery.common.ids.elements.PlansId; +import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition; +import org.eclipse.winery.model.csar.toscametafile.TOSCAMetaFile; +import org.eclipse.winery.model.csar.toscametafile.TOSCAMetaFileParser; +import org.eclipse.winery.model.tosca.Definitions; +import org.eclipse.winery.model.tosca.TArtifactReference; +import org.eclipse.winery.model.tosca.TArtifactReference.Exclude; +import org.eclipse.winery.model.tosca.TArtifactReference.Include; +import org.eclipse.winery.model.tosca.TArtifactTemplate; +import org.eclipse.winery.model.tosca.TArtifactTemplate.ArtifactReferences; +import org.eclipse.winery.model.tosca.TDefinitions; +import org.eclipse.winery.model.tosca.TDefinitions.Types; +import org.eclipse.winery.model.tosca.TEntityType; +import org.eclipse.winery.model.tosca.TEntityType.PropertiesDefinition; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TImport; +import org.eclipse.winery.model.tosca.TNodeType; +import org.eclipse.winery.model.tosca.TPlan; +import org.eclipse.winery.model.tosca.TPlan.PlanModelReference; +import org.eclipse.winery.model.tosca.TPlans; +import org.eclipse.winery.model.tosca.TRelationshipType; +import org.eclipse.winery.model.tosca.TServiceTemplate; +import org.eclipse.winery.repository.Constants; +import org.eclipse.winery.repository.JAXBSupport; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.backend.constants.Filename; +import org.eclipse.winery.repository.backend.filebased.FileUtils; +import org.eclipse.winery.repository.datatypes.ids.elements.ArtifactTemplateDirectoryId; +import org.eclipse.winery.repository.datatypes.ids.elements.SelfServiceMetaDataId; +import org.eclipse.winery.repository.datatypes.ids.elements.VisualAppearanceId; +import org.eclipse.winery.repository.export.CSARExporter; +import org.eclipse.winery.repository.resources.admin.NamespacesResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Element; + +/** + * Imports a CSAR into the storage. As the internal storage format does not have + * CSARs as the topmost artifacts, but one TDefinition, the CSAR has to be split + * up into several components. + * + * Existing components are not replaced, but silently skipped + * + * Minor errors are logged and not further propagated / notified. That means, a + * user cannot see minor errors. Major errors are immediately thrown. + * + * One instance for each import + */ +public class CSARImporter { + + private static final Logger logger = LoggerFactory.getLogger(CSARImporter.class); + + + /** + * Reads the CSAR from the given inputstream + * + * @param in the inputstream to read from + * @param errorList the list of errors during the import. Has to be non-null + * + * @throws InvalidCSARException if the CSAR is invalid + */ + public void readCSAR(InputStream in, List errors) throws IOException { + // we have to extract the file to a temporary directory as + // the .definitions file does not necessarily have to be the first entry in the archive + Path csarDir = Files.createTempDirectory("winery"); + + try (ZipInputStream zis = new ZipInputStream(in)) { + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (!entry.isDirectory()) { + Path targetPath = csarDir.resolve(entry.getName()); + Files.createDirectories(targetPath.getParent()); + Files.copy(zis, targetPath); + } + } + this.importFromDir(csarDir, errors); + } catch (Exception e) { + CSARImporter.logger.debug("Could not import CSAR", e); + throw e; + } finally { + // cleanup: delete all contents of the temporary directory + FileUtils.forceDelete(csarDir); + } + } + + /** + * Import an extracted CSAR from a directory + * + * @param path the root path of an extraced CSAR file + * @throws InvalidCSARException + * @throws IOException + */ + void importFromDir(final Path path, final List errors) throws IOException { + Path toscaMetaPath = path.resolve("TOSCA-Metadata/TOSCA.meta"); + if (!Files.exists(toscaMetaPath)) { + errors.add("TOSCA.meta does not exist"); + return; + } + final TOSCAMetaFileParser tmfp = new TOSCAMetaFileParser(); + final TOSCAMetaFile tmf = tmfp.parse(toscaMetaPath); + + // we do NOT do any sanity checks, of TOSAC.meta + // and just start parsing + + if (tmf.getEntryDefinitions() != null) { + // we obey the entry definitions and "just" import that + // imported definitions are added recursively + Path defsPath = path.resolve(tmf.getEntryDefinitions()); + this.importDefinitions(tmf, defsPath, errors); + + this.importSelfServiceMetaData(tmf, path, defsPath, errors); + } else { + // no explicit entry definitions found + // we import all available definitions + // The specification says (cos01, Section 16.1, line 2935) that all definitions are contained in the "Definitions" directory + // The alternative is to go through all entries in the TOSCA Meta File, but there is no guarantee that this list is complete + Path definitionsDir = path.resolve("Definitions"); + if (!Files.exists(definitionsDir)) { + errors.add("No entry definitions defined and Definitions directory does not exist."); + return; + } + final List exceptions = new ArrayList(); + Files.walkFileTree(definitionsDir, new SimpleFileVisitor() { + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + if (dir.endsWith("Definitions")) { + return FileVisitResult.CONTINUE; + } else { + return FileVisitResult.SKIP_SUBTREE; + } + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + try { + CSARImporter.this.importDefinitions(tmf, file, errors); + } catch (IOException e) { + exceptions.add(e); + return FileVisitResult.TERMINATE; + } + return FileVisitResult.CONTINUE; + } + }); + + if (!exceptions.isEmpty()) { + // something went wrong during parsing + // we rethrow the exception + throw exceptions.get(0); + } + } + + this.importNamespacePrefixes(path); + } + + + private static final Pattern GENERATED_PREFIX_PATTERN = Pattern.compile("^ns\\d+$"); + + + /** + * Import namespace prefixes. This is kind of a quick hack. TODO: during the + * import, the prefixes should be extracted using JAXB and stored in the + * NamespacesResource + * + * @param rootPath the root path of the extracted CSAR + */ + private void importNamespacePrefixes(Path rootPath) { + Path properties = rootPath.resolve(CSARExporter.PATH_TO_NAMESPACES_PROPERTIES); + if (Files.exists(properties)) { + PropertiesConfiguration pconf; + try { + pconf = new PropertiesConfiguration(properties.toFile()); + } catch (ConfigurationException e) { + CSARImporter.logger.debug(e.getMessage(), e); + return; + } + Iterator namespaces = pconf.getKeys(); + while (namespaces.hasNext()) { + boolean addToStorage = false; + String namespace = namespaces.next(); + if (NamespacesResource.INSTANCE.getIsPrefixKnownForNamespace(namespace)) { + String storedPrefix = NamespacesResource.getPrefix(namespace); + // QUICK HACK to check whether the prefix is a generated one + // We assume we know the internal generation routine + Matcher m = CSARImporter.GENERATED_PREFIX_PATTERN.matcher(storedPrefix); + if (m.matches()) { + // the stored prefix is a generated one + // replace it by the one stored in the exported properties + addToStorage = true; + } + } else { + addToStorage = true; + } + if (addToStorage) { + String prefix = pconf.getString(namespace); + NamespacesResource.INSTANCE.addNamespace(namespace, prefix); + } + } + } + } + + /** + * Imports a self-service meta data description (if available) + * + * The first service template in the provided entry definitions is taken + * + * @param tmf + * + * @param errors + */ + private void importSelfServiceMetaData(final TOSCAMetaFile tmf, final Path rootPath, Path entryDefinitions, final List errors) { + final Path selfServiceDir = rootPath.resolve(Constants.DIRNAME_SELF_SERVICE_METADATA); + if (!Files.exists(selfServiceDir)) { + CSARImporter.logger.debug("Self-service Portal directory does not exist in CSAR"); + return; + } + if (!Files.exists(entryDefinitions)) { + CSARImporter.logger.debug("Entry definitions does not exist."); + return; + } + + Unmarshaller um = JAXBSupport.createUnmarshaller(); + TDefinitions defs; + try { + defs = (TDefinitions) um.unmarshal(entryDefinitions.toFile()); + } catch (JAXBException e) { + errors.add("Could not unmarshal definitions " + entryDefinitions.getFileName() + " " + e.getMessage()); + return; + } catch (ClassCastException e) { + errors.add("Definitions " + entryDefinitions.getFileName() + " is not a TDefinitions " + e.getMessage()); + return; + } + + final int cutLength = selfServiceDir.toString().length() + 1; + Iterator iterator = defs.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().iterator(); + boolean found = false; + TExtensibleElements next = null; + while (iterator.hasNext() && !found) { + next = iterator.next(); + if (next instanceof TServiceTemplate) { + found = true; + } + } + + if (found) { + TServiceTemplate serviceTemplate = (TServiceTemplate) next; + String namespace = serviceTemplate.getTargetNamespace(); + if (namespace == null) { + namespace = defs.getTargetNamespace(); + } + ServiceTemplateId stId = new ServiceTemplateId(namespace, serviceTemplate.getId(), false); + final SelfServiceMetaDataId id = new SelfServiceMetaDataId(stId); + + // QUICK HACK: We just import all data without any validation + // Reason: the metadata resource can deal with nearly arbitrary formats of the data, therefore we do not do any checking here + + try { + Files.walkFileTree(selfServiceDir, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + String name = file.toString().substring(cutLength); + // check: if name contains "/", this could lead to exceptions + RepositoryFileReference ref = new RepositoryFileReference(id, name); + CSARImporter.this.importFile(file, ref, tmf, rootPath, errors); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + CSARImporter.logger.debug(e.getMessage(), e); + errors.add("Self-service Meta Data: " + e.getMessage()); + } + } + + } + + /** + * Recursively imports the given definitions + * + * @param tmf the TOSCAMetaFile object holding the parsed content of a TOSCA + * meta file + * @param definitions the path to the defintions to imprt + * + * @throws IOException + */ + private void importDefinitions(TOSCAMetaFile tmf, Path defsPath, final List errors) throws IOException { + if (tmf == null) { + throw new IllegalStateException("tmf must not be null"); + } + if (defsPath == null) { + throw new IllegalStateException("path to definitions must not be null"); + } + if (!Files.exists(defsPath)) { + errors.add(String.format("Definitions %1$s does not exist", defsPath.getFileName())); + return; + } + + Unmarshaller um = JAXBSupport.createUnmarshaller(); + TDefinitions defs; + try { + defs = (TDefinitions) um.unmarshal(defsPath.toFile()); + } catch (JAXBException e) { + Throwable cause = e; + String eMsg = ""; + do { + String msg = cause.getMessage(); + if (msg != null) { + eMsg = eMsg + msg + "; "; + } + cause = cause.getCause(); + } while (cause != null); + errors.add("Could not unmarshal definitions " + defsPath.getFileName() + " " + eMsg); + CSARImporter.logger.debug("Unmarshalling error", e); + return; + } catch (ClassCastException e) { + errors.add("Definitions " + defsPath.getFileName() + " is not a TDefinitions " + e.getMessage()); + return; + } + + List imports = defs.getImport(); + this.importImports(defsPath.getParent(), tmf, imports, errors); + // imports has been modified to contain necessary imports only + + // this method adds new imports to defs which may not be imported using "importImports". + // Therefore, "importTypes" has to be called *after* importImports + this.importTypes(defs, errors); + + String defaultNamespace = defs.getTargetNamespace(); + List componentInstanceList = defs.getServiceTemplateOrNodeTypeOrNodeTypeImplementation(); + for (TExtensibleElements ci : componentInstanceList) { + // Determine namespace + String namespace = this.getNamespace(ci, defaultNamespace); + // Ensure that element has the namespace + this.setNamespace(ci, namespace); + + // Determine id + String id = ModelUtilities.getId(ci); + + // Determine WineryId + Class widClass = org.eclipse.winery.repository.Utils.getComponentIdClassForTExtensibleElements(ci.getClass()); + TOSCAComponentId wid = BackendUtils.getTOSCAcomponentId(widClass, namespace, id, false); + + if (Repository.INSTANCE.exists(wid)) { + String msg = String.format("Skipped %1$s %2$s, because it already exists", ci.getClass().getName(), wid.getQName().toString()); + CSARImporter.logger.debug(msg); + // this is not displayed in the UI as we currently do not distinguish between pre-existing types and types created during the import. + continue; + } + + // Create a fresh definitions object without the other data. + Definitions newDefs = BackendUtils.createWrapperDefinitions(wid); + + // copy over the inputs determined by this.importImports + newDefs.getImport().addAll(imports); + + // add the current TExtensibleElements as the only content to it + newDefs.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().add(ci); + + if (ci instanceof TArtifactTemplate) { + // convention: Definitions are stored in the "Definitions" directory, therefore going to levels up (Definitions dir -> root dir) resolves to the root dir + // COS01, line 2663 states that the path has to be resolved from the *root* of the CSAR + this.adjustArtifactTemplate(defsPath.getParent().getParent(), tmf, (ArtifactTemplateId) wid, (TArtifactTemplate) ci, errors); + } else if (ci instanceof TNodeType) { + this.adjustNodeType(defsPath.getParent().getParent(), (TNodeType) ci, (NodeTypeId) wid, tmf, errors); + } else if (ci instanceof TRelationshipType) { + this.adjustRelationshipType(defsPath.getParent().getParent(), (TRelationshipType) ci, (RelationshipTypeId) wid, tmf, errors); + } else if (ci instanceof TServiceTemplate) { + this.adjustServiceTemplate(defsPath.getParent().getParent(), tmf, (ServiceTemplateId) wid, (TServiceTemplate) ci, errors); + } + + // node types and relationship types are subclasses of TEntityType + // Therefore, we check the entity type separately here + if (ci instanceof TEntityType) { + this.adjustEntityType((TEntityType) ci, (EntityTypeId) wid, newDefs, errors); + } + + this.storeDefinitions(wid, newDefs); + } + } + + /** + * Imports the specified types into the repository. The types are converted + * to an import statement + * + * @param errors Container for error messages + */ + private void importTypes(TDefinitions defs, final List errors) { + Types typesContainer = defs.getTypes(); + if (typesContainer != null) { + List types = typesContainer.getAny(); + for (Object type : types) { + if (type instanceof Element) { + Element element = (Element) type; + + // generate id part of ImportId out of definitions' id + // we do not use the name as the name has to be URLencoded again and we have issues with the interplay with org.eclipse.winery.common.ids.definitions.imports.GenericImportId.getId(TImport) then. + String id = defs.getId(); + // try to make the id unique by hashing the "content" of the definition + id = id + "-" + Integer.toHexString(element.hashCode()); + + // set importId + TOSCAComponentId importId; + String ns; + if (element.getNamespaceURI().equals(XMLConstants.W3C_XML_SCHEMA_NS_URI)) { + ns = element.getAttribute("targetNamespace"); + importId = new XSDImportId(ns, id, false); + } else { + // Quick hack for non-XML-Schema-definitions + ns = "unknown"; + importId = new GenericImportId(ns, id, false, element.getNamespaceURI()); + } + + // Following code is adapted from importOtherImports + + TDefinitions wrapperDefs = BackendUtils.createWrapperDefinitions(importId); + TImport imp = new TImport(); + String fileName = id + ".xsd"; + imp.setLocation(fileName); + imp.setImportType(XMLConstants.W3C_XML_SCHEMA_NS_URI); + imp.setNamespace(ns); + wrapperDefs.getImport().add(imp); + this.storeDefinitions(importId, wrapperDefs); + + // put the file itself to the repo + // ref is required to generate fileRef + RepositoryFileReference ref = BackendUtils.getRefOfDefinitions(importId); + RepositoryFileReference fileRef = new RepositoryFileReference(ref.getParent(), fileName); + // convert element to document + // QUICK HACK. Alternative: Add new method Repository.INSTANCE.getOutputStream and transform DOM node to OuptputStream + String content = Util.getXMLAsString(element); + try { + Repository.INSTANCE.putContentToFile(fileRef, content, MediaType.APPLICATION_XML_TYPE); + } catch (IOException e) { + CSARImporter.logger.debug("Could not put XML Schema definition to file " + fileRef.toString(), e); + errors.add("Could not put XML Schema definition to file " + fileRef.toString()); + } + + // add import to definitions + + // adapt path - similar to importOtherImport + String newLoc = "../" + Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(fileRef)); + imp.setLocation(newLoc); + defs.getImport().add(imp); + } else { + // This is a known type. Otherwise JAX-B would render it as Element + errors.add("There is a Type of class " + type.getClass().toString() + " which is unknown to Winery. The type element is imported as is"); + } + } + } + } + + /** + * All EntityTypes may contain properties definition. In case a winery + * properties definition is found, the TOSCA conforming properties + * definition is removed + * + * @param ci the entity type + * @param wid the Winery id of the entitytype + * @param newDefs the definitions, the entiy type is contained in. The + * imports might be adjusted here + * @param errors + */ + private void adjustEntityType(TEntityType ci, EntityTypeId wid, Definitions newDefs, final List errors) { + PropertiesDefinition propertiesDefinition = ci.getPropertiesDefinition(); + if (propertiesDefinition != null) { + WinerysPropertiesDefinition winerysPropertiesDefinition = ModelUtilities.getWinerysPropertiesDefinition(ci); + boolean deriveWPD; + if (winerysPropertiesDefinition == null) { + deriveWPD = true; + } else { + if (winerysPropertiesDefinition.getIsDerivedFromXSD() == null) { + // if the winery's properties are defined by Winery itself, + // remove the TOSCA conforming properties definition as a Winery properties definition exists (and which takes precedence) + ci.setPropertiesDefinition(null); + + // no derivation from properties required as the properties are generated by Winery + deriveWPD = false; + + // we have to remove the import, too + // Determine the location + String elementName = winerysPropertiesDefinition.getElementName(); + String loc = BackendUtils.getImportLocationForWinerysPropertiesDefinitionXSD(wid, null, elementName); + // remove the import matching that location + List imports = newDefs.getImport(); + boolean found = false; + if (imports != null) { + Iterator iterator = imports.iterator(); + TImport imp; + while (iterator.hasNext()) { + imp = iterator.next(); + // TODO: add check for QNames.QNAME_WINERYS_PROPERTIES_DEFINITION_ATTRIBUTE instead of import location. The current routine, however, works, too. + if (imp.getLocation().equals(loc)) { + found = true; + break; + } + } + if (found) { + // imp with Winery's k/v location found + iterator.remove(); + // the XSD has been imported in importOtherImport + // it was too difficult to do the location check there, therefore we just remove the XSD from the repository here + XSDImportId importId = new XSDImportId(winerysPropertiesDefinition.getNamespace(), elementName, false); + try { + Repository.INSTANCE.forceDelete(importId); + } catch (IOException e) { + CSARImporter.logger.debug("Could not delete Winery's generated XSD definition", e); + errors.add("Could not delete Winery's generated XSD definition"); + } + } else { + // K/V properties definition was incomplete + } + } + } else { + // winery's properties are derived from an XSD + // The export does NOT add an imports statement: only the wpd exists + // We remove that as + ModelUtilities.removeWinerysPropertiesDefinition(ci); + // derive the WPDs again from the properties definition + deriveWPD = true; + } + } + if (deriveWPD) { + BackendUtils.deriveWPD(ci, errors); + } + } + } + + /** + * In case plans are provided, the plans are imported into Winery's storage + * + * @param rootPath the root path of the extracted csar + * @param tmf the TOSCAMetaFile object used to determine the mime type of + * the plan + * @param wid Winery's internal id of the service template + * @param st the the service template to be imported {@inheritDoc} + * + * @throws InvalidCSARException + */ + private void adjustServiceTemplate(Path rootPath, TOSCAMetaFile tmf, ServiceTemplateId wid, TServiceTemplate st, final List errors) { + TPlans plans = st.getPlans(); + if (plans != null) { + for (TPlan plan : plans.getPlan()) { + PlanModelReference refContainer = plan.getPlanModelReference(); + if (refContainer != null) { + String ref = refContainer.getReference(); + if (ref != null) { + // URLs are stored encoded -> undo the encoding + ref = Util.URLdecode(ref); + URI refURI; + try { + refURI = new URI(ref); + } catch (URISyntaxException e) { + errors.add(String.format("Invalid URI %1$s", ref)); + continue; + } + if (refURI.isAbsolute()) { + // Points to somewhere external + // This is a linked plan + // We have to do nothing + continue; + } + Path path = rootPath.resolve(ref); + if (!Files.exists(path)) { + // possibly, the reference is relative to the Definitions subfolder + // COS01 does not make any explicit statement how to resolve the reference here + path = rootPath.resolve("Definitions").resolve(ref); + if (!Files.exists(path)) { + errors.add(String.format("Plan reference %1$s not found", ref)); + // we quickly remove the reference to reflect the not-found in the data + refContainer.setReference(null); + continue; + } + } + PlansId plansId = new PlansId(wid); + PlanId pid = new PlanId(plansId, new XMLId(plan.getId(), false)); + if (Files.isDirectory(path)) { + errors.add(String.format("Reference %1$s is a directory and Winery currently does not support importing directories", ref)); + continue; + } + RepositoryFileReference fref = new RepositoryFileReference(pid, path.getFileName().toString()); + this.importFile(path, fref, tmf, rootPath, errors); + + // file is imported + // Adjust the reference + refContainer.setReference("../" + Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(fref))); + } + } + } + } + } + + /** + * Adds a color to the given relationship type + */ + private void adjustRelationshipType(Path rootPath, TRelationshipType ci, RelationshipTypeId wid, TOSCAMetaFile tmf, final List errors) { + VisualAppearanceId visId = new VisualAppearanceId(wid); + this.importIcons(rootPath, visId, tmf, errors); + } + + private void adjustNodeType(Path rootPath, TNodeType ci, NodeTypeId wid, TOSCAMetaFile tmf, final List errors) { + VisualAppearanceId visId = new VisualAppearanceId(wid); + this.importIcons(rootPath, visId, tmf, errors); + } + + private void importIcons(Path rootPath, VisualAppearanceId visId, TOSCAMetaFile tmf, final List errors) { + String pathInsideRepo = BackendUtils.getPathInsideRepo(visId); + Path visPath = rootPath.resolve(pathInsideRepo); + this.importIcon(visId, visPath, Filename.FILENAME_BIG_ICON, tmf, rootPath, errors); + } + + private void importIcon(VisualAppearanceId visId, Path visPath, String fileName, TOSCAMetaFile tmf, Path rootPath, final List errors) { + Path file = visPath.resolve(fileName); + if (Files.exists(file)) { + RepositoryFileReference ref = new RepositoryFileReference(visId, fileName); + this.importFile(file, ref, tmf, rootPath, errors); + } + } + + /** + * Adjusts the given artifact template to conform with the repository format + * + * We import the files given at the artifact references + * + * @throws InvalidCSARException + * @throws IOException + */ + private void adjustArtifactTemplate(Path rootPath, TOSCAMetaFile tmf, ArtifactTemplateId atid, TArtifactTemplate ci, final List errors) throws IOException { + ArtifactReferences refs = ci.getArtifactReferences(); + if (refs == null) { + // no references stored - break + return; + } + List refList = refs.getArtifactReference(); + for (TArtifactReference ref : refList) { + String reference = ref.getReference(); + // URLs are stored encoded -> undo the encoding + reference = Util.URLdecode(reference); + Path path = rootPath.resolve(reference); + if (!Files.exists(path)) { + errors.add(String.format("Reference %1$s not found", reference)); + return; + } + Set allFiles; + if (Files.isRegularFile(path)) { + allFiles = new HashSet(); + allFiles.add(path); + } else { + assert (Files.isDirectory(path)); + Path localRoot = rootPath.resolve(path); + List includeOrExclude = ref.getIncludeOrExclude(); + + if (includeOrExclude.get(0) instanceof TArtifactReference.Exclude) { + // Implicit semantics of an exclude listed first: + // include all files and then exclude the files matched by the pattern + allFiles = this.getAllFiles(localRoot); + } else { + // semantics if include lited as first: + // same as listed at other places + allFiles = new HashSet<>(); + } + + for (Object object : includeOrExclude) { + if (object instanceof TArtifactReference.Include) { + this.handleInclude((TArtifactReference.Include) object, localRoot, allFiles); + } else { + assert (object instanceof TArtifactReference.Exclude); + this.handleExclude((TArtifactReference.Exclude) object, localRoot, allFiles); + } + } + } + this.importAllFiles(allFiles, atid, tmf, rootPath, errors); + } + + // everything is imported, we don't need the references stored locally + // they are generated on the fly when exporting + ci.setArtifactReferences(null); + } + + /** + * Imports a file from the filesystem to the repository + * + * @param p the file to read from + * @param fref the "file" to put the content to + * @param tmf the TOSCAMetaFile object used to determine the mimetype + * @param rootPath used to relativize p to determine the mime type + * @throws InvalidCSARException + */ + private void importFile(Path p, RepositoryFileReference fref, TOSCAMetaFile tmf, Path rootPath, final List errors) { + try (InputStream is = Files.newInputStream(p); + BufferedInputStream bis = new BufferedInputStream(is)) { + String mediaType = tmf.getMimeType(p.relativize(rootPath).toString()); + if (mediaType == null) { + // Manually find out mime type + try { + mediaType = Utils.getMimeType(bis, p.getFileName().toString()); + } catch (IOException e) { + errors.add(String.format("No MimeType given for %1$s (%2$s)", p.getFileName(), e.getMessage())); + return; + } + if (mediaType == null) { + errors.add(String.format("No MimeType given for %1$s", p.getFileName())); + return; + } + } + try { + Repository.INSTANCE.putContentToFile(fref, bis, MediaType.valueOf(mediaType)); + } catch (IllegalArgumentException | IOException e) { + throw new IllegalStateException(e); + } + } catch (IOException e1) { + throw new IllegalStateException("Could not work on generated temporary files", e1); + } + } + + private void importAllFiles(Collection allFiles, ArtifactTemplateId atid, TOSCAMetaFile tmf, Path rootPath, final List errors) { + // import all files to repository + ArtifactTemplateDirectoryId fileDir = new ArtifactTemplateDirectoryId(atid); + for (Path p : allFiles) { + if (!Files.exists(p)) { + errors.add(String.format("File %1$s does not exist", p.toString())); + return; + } + RepositoryFileReference fref = new RepositoryFileReference(fileDir, p.getFileName().toString()); + this.importFile(p, fref, tmf, rootPath, errors); + } + + } + + /** + * Modifies given allFiles object to exclude all files given by the excl + * pattern + * + * Semantics: Remove all files from the set, which match the given pattern + */ + private void handleExclude(Exclude excl, Path localRoot, Set allFiles) { + PathMatcher pathMatcher = localRoot.getFileSystem().getPathMatcher("glob:" + excl.getPattern()); + Iterator it = allFiles.iterator(); + while (it.hasNext()) { + Path curPath = it.next(); + if (pathMatcher.matches(curPath)) { + it.remove(); + } + } + } + + /** + * Modifies given allFiles object to include all files given by the incl + * pattern + * + * Semantics: Add all files from localRoot to allFiles matching the pattern + */ + private void handleInclude(final Include incl, final Path localRoot, final Set allFiles) { + final PathMatcher pathMatcher = localRoot.getFileSystem().getPathMatcher("glob:" + incl.getPattern()); + try { + Files.walkFileTree(localRoot, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Path relFile = localRoot.relativize(file); + if (pathMatcher.matches(relFile)) { + allFiles.add(file); + } + return CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + if (pathMatcher.matches(dir)) { + Set filesToAdd = CSARImporter.this.getAllFiles(dir); + allFiles.addAll(filesToAdd); + return SKIP_SUBTREE; + } else { + return CONTINUE; + } + } + }); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + /** + * Lists all files contained in the given path + */ + private Set getAllFiles(Path startPath) { + final Set res = new HashSet<>(); + try { + Files.walkFileTree(startPath, new SimpleFileVisitor() { + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + res.add(file); + return CONTINUE; + } + }); + } catch (IOException e) { + throw new IllegalStateException(e); + } + return res; + } + + /** + * Sets the namespace on the CI if CI offers the method "setTargetNamespace" + * + * @param ci the component instance to set the namespace + * @param namespace the namespace to set + */ + private void setNamespace(TExtensibleElements ci, String namespace) { + Method method; + try { + method = ci.getClass().getMethod("setTargetNamespace", String.class); + method.invoke(ci, namespace); + } catch (NoSuchMethodException ne) { + // this is OK, because we do not check, whether the method really exists + // Special case for TArtifactTemplate not offering setTargetNamespace + // just ignore it + } catch (Exception e) { + throw new IllegalStateException("Could not set target namespace", e); + } + } + + /** + * @param ci the component instance to get the namespace from + * @param defaultNamespace the namespace to use if the TExtensibleElements + * has no targetNamespace + */ + private String getNamespace(TExtensibleElements ci, String defaultNamespace) { + Method method; + Object res; + try { + method = ci.getClass().getMethod("getTargetNamespace"); + res = method.invoke(ci); + } catch (Exception e) { + // we are at TArtifactTemplate, which does not offer getTargetNamespace + res = null; + } + String ns = (String) res; + if (ns == null) { + ns = defaultNamespace; + } + return ns; + } + + /** + * @param basePath the base path where to resolve files from. This is the + * directory of the Definitions + * @param imports the list of imports to import. SIDE EFFECT: this list is + * modified. After this method has run, the list contains the + * imports to be put into the wrapper element + */ + private void importImports(Path basePath, TOSCAMetaFile tmf, List imports, final List errors) throws IOException { + for (Iterator iterator = imports.iterator(); iterator.hasNext();) { + TImport imp = iterator.next(); + String importType = imp.getImportType(); + String namespace = imp.getNamespace(); + String loc = imp.getLocation(); + + if (namespace == null) { + errors.add("not namespace-qualified imports are not supported."); + continue; + } + + if (loc == null) { + errors.add("Empty location imports are not supported."); + } else { + if (importType.equals(Namespaces.TOSCA_NAMESPACE)) { + if (!Util.isRelativeURI(loc)) { + errors.add("Absolute URIs for definitions import not supported."); + continue; + } + + // URIs are encoded + loc = Util.URLdecode(loc); + + Path defsPath = basePath.resolve(loc); + // fallback for older CSARs, where the location is given from the root + if (!Files.exists(defsPath)) { + defsPath = basePath.getParent().resolve(loc); + // the real existance check is done in importDefinitions + } + this.importDefinitions(tmf, defsPath, errors); + // imports of definitions don't have to be kept as these are managed by Winery + iterator.remove(); + } else { + this.importOtherImport(basePath, imp, errors, importType); + } + } + } + } + + /** + * SIDE EFFECT: modifies the location of imp to point to the correct + * relative location (when read from the exported CSAR) + * + * @param rootPath the absolute path where to resolve files from + */ + private void importOtherImport(Path rootPath, TImport imp, final List errors, String type) { + assert (!type.equals(Namespaces.TOSCA_NAMESPACE)); + String loc = imp.getLocation(); + + if (!Util.isRelativeURI(loc)) { + // This is just an information message + errors.add("Absolute URIs are not resolved by Winery (" + loc + ")"); + return; + } + + // location URLs are encoded: http://www.w3.org/TR/2001/WD-charmod-20010126/#sec-URIs, RFC http://www.ietf.org/rfc/rfc2396.txt + loc = Util.URLdecode(loc); + Path path; + try { + path = rootPath.resolve(loc); + } catch (Exception e) { + // java.nio.file.InvalidPathException could be thrown which is a RuntimeException + errors.add(e.getMessage()); + return; + } + if (!Files.exists(path)) { + // fallback for older CSARs, where the location is given from the root + path = rootPath.getParent().resolve(loc); + if (!Files.exists(path)) { + errors.add(String.format("File %1$s does not exist", loc)); + return; + } + } + String namespace = imp.getNamespace(); + String fileName = path.getFileName().toString(); + String id = fileName; + id = FilenameUtils.removeExtension(id); + // Convention: id of import is filename without extension + + GenericImportId rid; + if (type.equals(XMLConstants.W3C_XML_SCHEMA_NS_URI)) { + rid = new XSDImportId(namespace, id, false); + } else { + rid = new GenericImportId(namespace, id, false, type); + } + + boolean importDataExistsInRepo = Repository.INSTANCE.exists(rid); + + if (!importDataExistsInRepo) { + // We have to + // a) create a .definitions file + // b) put the file itself in the repo + + // Create the definitions file + TDefinitions defs = BackendUtils.createWrapperDefinitions(rid); + defs.getImport().add(imp); + // QUICK HACK: We change the imp object's location here and below again + // This is "OK" as "storeDefinitions" serializes the current state and not the future state of the imp object + // change the location to point to the file in the folder of the .definitions file + imp.setLocation(fileName); + + // put the definitions file to the repository + this.storeDefinitions(rid, defs); + } + + // put the file itself to the repo + // ref is required to generate fileRef + RepositoryFileReference ref = BackendUtils.getRefOfDefinitions(rid); + RepositoryFileReference fileRef = new RepositoryFileReference(ref.getParent(), fileName); + + // location is relative to Definitions/ + // even if the import already exists, we have to adapt the path + // URIs are encoded + String newLoc = "../" + Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(fileRef)); + imp.setLocation(newLoc); + + if (!importDataExistsInRepo) { + // finally write the file to the storage + try (InputStream is = Files.newInputStream(path); + BufferedInputStream bis = new BufferedInputStream(is)) { + MediaType mediaType; + if (type.equals(XMLConstants.W3C_XML_SCHEMA_NS_URI)) { + mediaType = MediaType.valueOf(MimeTypes.MIMETYPE_XSD); + } else { + String mimeType = Utils.getMimeType(bis, path.getFileName().toString()); + mediaType = MediaType.valueOf(mimeType); + } + Repository.INSTANCE.putContentToFile(fileRef, bis, mediaType); + } catch (IllegalArgumentException | IOException e) { + throw new IllegalStateException(e); + } + + // we have to update the cache in case of a new XSD to speedup usage of winery + if (rid instanceof XSDImportId) { + CSARImporter.logger.debug("Updating XSD import cache data"); + // We call the queries without storing the result: + // We use the SIDEEFFECT that a cache is created + Utils.getAllXSDElementDefinitionsForTypeAheadSelection(); + Utils.getAllXSDTypeDefinitionsForTypeAheadSelection(); + CSARImporter.logger.debug("Updated XSD import cache data"); + } + } + } + + private void storeDefinitions(TOSCAComponentId id, TDefinitions defs) { + RepositoryFileReference ref = BackendUtils.getRefOfDefinitions(id); + String s = Utils.getXMLAsString(defs, true); + try { + Repository.INSTANCE.putContentToFile(ref, s, MediaType.valueOf(MimeTypes.MIMETYPE_TOSCA_DEFINITIONS)); + } catch (IllegalArgumentException | IOException e) { + throw new IllegalStateException(e); + } + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/json/TTopologyTemplateSerializer.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/json/TTopologyTemplateSerializer.java new file mode 100644 index 0000000000..72d222053d --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/json/TTopologyTemplateSerializer.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.json; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.model.tosca.TNodeTemplate; +import org.eclipse.winery.model.tosca.TRelationshipTemplate; +import org.eclipse.winery.model.tosca.TTopologyTemplate; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +public class TTopologyTemplateSerializer extends JsonSerializer { + + /** + * Does NOT wrap the result into an object. Assumes that the current + * position at jgen is in an object + * + * @param value the list of entity templates to serialize + */ + public void serialize(List value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + List relationshipTemplates = new ArrayList(); + + jgen.writeFieldName("nodeTemplates"); + jgen.writeStartObject(); + for (TEntityTemplate template : value) { + if (template instanceof TNodeTemplate) { + // write out as : + jgen.writeFieldName(template.getId()); + provider.defaultSerializeValue(template, jgen); + + } else { + assert (template instanceof TRelationshipTemplate); + relationshipTemplates.add((TRelationshipTemplate) template); + } + } + jgen.writeEndObject(); + + jgen.writeFieldName("relationshipTemplates"); + jgen.writeStartObject(); + for (TRelationshipTemplate template : relationshipTemplates) { + // write out as : + jgen.writeFieldName(template.getId()); + provider.defaultSerializeValue(template, jgen); + } + jgen.writeEndObject(); + } + + @Override + public void serialize(TTopologyTemplate topologyTemplate, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { + jgen.writeStartObject(); + + // write out the other fields unmodified + jgen.writeFieldName("documentation"); + provider.defaultSerializeValue(topologyTemplate.getDocumentation(), jgen); + jgen.writeFieldName("any"); + provider.defaultSerializeValue(topologyTemplate.getAny(), jgen); + jgen.writeFieldName("otherAttributes"); + provider.defaultSerializeValue(topologyTemplate.getOtherAttributes(), jgen); + + // finally, write the topology template + this.serialize(topologyTemplate.getNodeTemplateOrRelationshipTemplate(), jgen, provider); + + jgen.writeEndObject(); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/json/TopologyTemplateModule.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/json/TopologyTemplateModule.java new file mode 100644 index 0000000000..e5d99508b0 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/json/TopologyTemplateModule.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.json; + +import org.eclipse.winery.model.tosca.TTopologyTemplate; + +import com.fasterxml.jackson.databind.module.SimpleModule; + +@SuppressWarnings("serial") +public class TopologyTemplateModule extends SimpleModule { + + public TopologyTemplateModule() { + this.addSerializer(TTopologyTemplate.class, new TTopologyTemplateSerializer()); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceResource.java new file mode 100644 index 0000000000..2cf09a8e51 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceResource.java @@ -0,0 +1,509 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.StreamingOutput; +import javax.ws.rs.core.UriInfo; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; + +import org.eclipse.winery.model.tosca.Definitions; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TImport; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.TOSCADocumentBuilderFactory; +import org.eclipse.winery.common.constants.MimeTypes; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.repository.JAXBSupport; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.backend.constants.MediaTypes; +import org.eclipse.winery.repository.export.TOSCAExportUtil; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources.documentation.DocumentationsResource; +import org.eclipse.winery.repository.resources.imports.genericimports.GenericImportResource; +import org.eclipse.winery.repository.resources.tags.TagsResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import com.sun.jersey.api.view.Viewable; + +/** + * Resource for a component ( + *
    + *
  • ServiceTemplates,
  • + *
  • EntityTypes,
  • + *
  • EntityTypeImplementations,
  • + *
  • EntityTemplates
  • + *
+ * ). A component is directly nested in a TDefinitions element. See also + * {@link org.eclipse.winery.common.ids.definitions.TOSCAComponentId} + * + * Bundles all operations required for all components. e.g., namespace+XMLid, + * object comparison, import, export, tags + * + * Uses a TDefinitions document as storage. + * + * Additional setters and getters are added if it comes to Winery's extensions + * such as the color of a relationship type + */ +public abstract class AbstractComponentInstanceResource implements Comparable, IPersistable { + + private static final Logger logger = LoggerFactory.getLogger(AbstractComponentInstanceResource.class); + + protected final TOSCAComponentId id; + + private final RepositoryFileReference ref; + + // the object representing the data of this resource + private Definitions definitions = null; + + // shortcut for this.definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().get(0); + protected TExtensibleElements element = null; + + + /** + * Instantiates the resource. Assumes that the resource should exist + * (assured by the caller) + * + * The caller should not create the resource by other ways. E.g., + * by instantiating this resource and then adding data. + */ + public AbstractComponentInstanceResource(TOSCAComponentId id) { + this.id = id; + + // the resource itself exists + assert (Repository.INSTANCE.exists(id)); + + // the data file might not exist + this.ref = BackendUtils.getRefOfDefinitions(id); + if (Repository.INSTANCE.exists(this.ref)) { + this.load(); + } else { + this.createNew(); + } + } + + /** + * Convenience method for getId().getNamespace() + */ + public final Namespace getNamespace() { + return this.id.getNamespace(); + } + + /** + * Convenience method for getId().getXmlId() + */ + public final XMLId getXmlId() { + return this.id.getXmlId(); + } + + /** + * Convenience method for getId().getQName(); + * + * @return the QName associated with this resource + */ + public final QName getQName() { + return this.getId().getQName(); + } + + /** + * Returns the id associated with this resource + */ + public final TOSCAComponentId getId() { + return this.id; + } + + /** + * called from AbstractComponentResource + */ + @DELETE + public final Response onDelete() { + Response res = BackendUtils.delete(this.id); + return res; + } + + @Override + public final int compareTo(AbstractComponentInstanceResource o) { + return this.id.compareTo(o.id); + } + + @Override + public final boolean equals(Object o) { + if (o instanceof String) { + throw new IllegalStateException(); + } else if (o instanceof AbstractComponentInstanceResource) { + if (o.getClass().equals(this.getClass())) { + // only compare if the two objects are from the same class + return ((AbstractComponentInstanceResource) o).getId().equals(this.getId()); + } else { + throw new IllegalStateException(); + } + } else { + throw new IllegalStateException(); + } + } + + @Override + public final int hashCode() { + return this.getId().hashCode(); + } + + @GET + @Path("id") + public String getTOSCAId() { + return this.id.getXmlId().getDecoded(); + } + + @PUT + @Path("id") + public Response putId(@FormParam("id") String id) { + // this renames the entity type resource + // TODO: implement rename functionality + return Response.serverError().entity("not yet implemented").build(); + } + + /** + * Main page + */ + // @Produces(MediaType.TEXT_HTML) // not true because of ?thor leads to send + // a thor. We nevertheless have to annotate that to be able to get a JSON + // representation required for the file upload (in {@link + // ArtifactTemplateResource}) + // + // we cannot issue a request expecting content-type application/zip as it is + // not possible to offer the result in a "save-as"-dialog: + // http://stackoverflow.com/questions/7464665/ajax-response-content-disposition-attachment + @GET + @Produces(MediaType.TEXT_HTML) + public final Response getHTML(@QueryParam(value = "definitions") String definitions, @QueryParam(value = "csar") String csar, @Context UriInfo uriInfo) { + if (!Repository.INSTANCE.exists(this.id)) { + return Response.status(Status.NOT_FOUND).build(); + } + if (definitions != null) { + return Utils.getDefinitionsOfSelectedResource(this, uriInfo.getBaseUri()); + } else if (csar != null) { + return this.getCSAR(); + } else { + String type = Utils.getTypeForInstance(this.getClass()); + String viewableName = "/jsp/" + Utils.getIntermediateLocationStringForType(type, "/") + "/" + type.toLowerCase() + ".jsp"; + Viewable viewable = new Viewable(viewableName, this); + + return Response.ok().entity(viewable).build(); + + // we can't do the following as the GET request from the browser + // cannot set the accept header properly + // "vary: accept" header has to be set as we may also return a THOR + // on the same URL + // return Response.ok().header(HttpHeaders.VARY, + // HttpHeaders.ACCEPT).entity(viewable).build(); + } + } + + @GET + @Produces(MimeTypes.MIMETYPE_ZIP) + public final Response getCSAR() { + if (!Repository.INSTANCE.exists(this.id)) { + return Response.status(Status.NOT_FOUND).build(); + } + return Utils.getCSARofSelectedResource(this); + } + + /** + * Returns the definitions of this resource. Includes required imports of + * other definitions + */ + @GET + @Produces({MimeTypes.MIMETYPE_TOSCA_DEFINITIONS, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) + public Response getDefinitionsAsResponse() { + if (!Repository.INSTANCE.exists(this.id)) { + return Response.status(Status.NOT_FOUND).build(); + } + StreamingOutput so = new StreamingOutput() { + + @Override + public void write(OutputStream output) throws IOException, WebApplicationException { + TOSCAExportUtil exporter = new TOSCAExportUtil(); + // we include everything related + Map conf = new HashMap<>(); + try { + exporter.exportTOSCA(AbstractComponentInstanceResource.this.id, output, conf); + } catch (JAXBException e) { + throw new WebApplicationException(e); + } + } + }; + return Response.ok().type(MediaType.TEXT_XML).entity(so).build(); + } + + /** + * @throws IllegalStateException if an IOException occurred. We opted not to + * propagate the IOException directly as this exception occurs + * seldom and is a not an exception to be treated by all callers + * in the prototype. + */ + private void load() { + try { + InputStream is = Repository.INSTANCE.newInputStream(this.ref); + Unmarshaller u = JAXBSupport.createUnmarshaller(); + this.definitions = (Definitions) u.unmarshal(is); + } catch (Exception e) { + AbstractComponentInstanceResource.logger.error("Could not read content from file " + this.ref, e); + throw new IllegalStateException(e); + } + try { + this.element = this.definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().get(0); + } catch (IndexOutOfBoundsException e) { + if (this instanceof GenericImportResource) { + // everything allright: + // ImportResource is a quick hack using 99% of the functionality offered here + // As only 1% has to be "quick hacked", we do that instead of a clean design + // Clean design: Introduce a class between this and AbstractComponentInstanceResource, where this class and ImportResource inhertis from + // A clean design introducing a super class AbstractDefinitionsBackedResource does not work, as we currently also support PropertiesBackedResources and such a super class would required multi-inheritance + } else { + throw new IllegalStateException("Wrong storage format: No ServiceTemplateOrNodeTypeOrNodeTypeImplementation found."); + } + } + } + + @Override + public void persist() throws IOException { + BackendUtils.persist(this.definitions, this.ref, MediaTypes.MEDIATYPE_TOSCA_DEFINITIONS); + } + + /** + * Creates a new instance of the object represented by this resource + */ + private void createNew() { + this.definitions = BackendUtils.createWrapperDefinitions(this.getId()); + + // create empty element + this.element = this.createNewElement(); + + // add the element to the definitions + this.definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().add(this.element); + + // copy ns + id + this.copyIdToFields(); + + // ensure that the definitions is persisted. Ensures that export works. + BackendUtils.persist(this); + } + + /** + * Creates an empty instance of an Element. + * + * The implementors do nothave to copy the ns and the id to the + * appropriate fields. + * + * we have two implementation possibilities: + *
    + *
  • a) each subclass implements this method and returns the appropriate + * object
  • + *
  • b) we use java reflection to invoke the right constructor as done in + * the resources
  • + *
+ * We opted for a) to increase readability of the code + */ + protected abstract TExtensibleElements createNewElement(); + + /** + * Copies the current id of the resource to the appropriate fields in the + * element. + * + * For instance, the id is put in the "name" field for EntityTypes + * + * We opted for a separate method from createNewElement to enable renaming + * of the object + */ + protected abstract void copyIdToFields(); + + /** + * Returns the Element belonging to this resource. As Java does not allow + * overriding returned classes, we expect the caller to either cast right or + * to use "getXY" defined by each subclass, where XY is the concrete type + * + * Shortcut for + * getDefinitions().getServiceTemplateOrNodeTypeOrNodeTypeImplementation + * ().get(0); + * + * @return TCapabilityType|... + */ + public TExtensibleElements getElement() { + return this.element; + } + + /** + * @return the reference to the internal list of imports. Can be changed if + * some imports are required or should be removed + * @throws IllegalStateException if definitions was not loaded or not + * initialized + */ + protected List getImport() { + if (this.definitions == null) { + throw new IllegalStateException("Trying to access uninitalized definitions object"); + } + return this.definitions.getImport(); + } + + /** + * Returns an XML representation of the definitions + * + * We return the complete definitions to allow the user changes to it, such + * as adding imports, etc. + */ + public String getDefinitionsAsXMLString() { + StringWriter w = new StringWriter(); + Marshaller m = JAXBSupport.createMarshaller(true); + try { + m.marshal(this.definitions, w); + } catch (JAXBException e) { + AbstractComponentInstanceResource.logger.error("Could not marshal definitions", e); + throw new IllegalStateException(e); + } + String res = w.toString(); + return res; + } + + /** + * @return the reference to the internal Definitions object + */ + public Definitions getDefinitions() { + return this.definitions; + } + + @PUT + @Consumes({MimeTypes.MIMETYPE_TOSCA_DEFINITIONS, MediaType.APPLICATION_XML, MediaType.TEXT_XML}) + public Response updateDefinitions(InputStream requestBodyStream) { + Unmarshaller u; + Definitions defs; + Document doc; + final StringBuilder sb = new StringBuilder(); + try { + DocumentBuilder db = TOSCADocumentBuilderFactory.INSTANCE.getTOSCADocumentBuilder(); + db.setErrorHandler(new ErrorHandler() { + + @Override + public void warning(SAXParseException exception) throws SAXException { + // we don't care + } + + @Override + public void fatalError(SAXParseException exception) throws SAXException { + sb.append("Fatal Error: "); + sb.append(exception.getMessage()); + sb.append("\n"); + } + + @Override + public void error(SAXParseException exception) throws SAXException { + sb.append("Fatal Error: "); + sb.append(exception.getMessage()); + sb.append("\n"); + } + }); + doc = db.parse(requestBodyStream); + if (sb.length() > 0) { + // some error happened + // doc is not null, because the parser parses even if it is not XSD conforming + return Response.status(Status.BAD_REQUEST).entity(sb.toString()).build(); + } + } catch (SAXException | IOException e) { + AbstractComponentInstanceResource.logger.debug("Could not parse XML", e); + return Utils.getResponseForException(e); + } + try { + u = JAXBSupport.createUnmarshaller(); + defs = (Definitions) u.unmarshal(doc); + } catch (JAXBException e) { + AbstractComponentInstanceResource.logger.debug("Could not unmarshal from request body stream", e); + return Utils.getResponseForException(e); + } + + // initial validity check + + // we allow changing the target namespace and the id + // This allows for inserting arbitrary definitions XML + // if (!this.definitions.getTargetNamespace().equals(this.id.getNamespace().getDecoded())) { + // return Response.status(Status.BAD_REQUEST).entity("Changing of the namespace is not supported").build(); + // } + // this.definitions.setTargetNamespace(this.id.getNamespace().getDecoded()); + + // TODO: check the provided definitions for validity + + TExtensibleElements tExtensibleElements = defs.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().get(0); + if (!tExtensibleElements.getClass().equals(this.createNewElement().getClass())) { + return Response.status(Status.BAD_REQUEST).entity("First type in Definitions is not matching the type modeled by this resource").build(); + } + + this.definitions = defs; + + // replace existing element by retrieved data + this.element = this.definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation().get(0); + + // ensure that ids did not change + // TODO: future work: raise error if user changed id or namespace + this.copyIdToFields(); + + return BackendUtils.persist(this); + } + + @GET + @Path("xml/") + @Produces(MediaType.TEXT_HTML) + public Response getXML() { + Viewable viewable = new Viewable("/jsp/xmlSource.jsp", this); + return Response.ok().entity(viewable).build(); + } + + @Path("documentation/") + public DocumentationsResource getDocumentationsResource() { + return new DocumentationsResource(this, this.getElement().getDocumentation()); + } + + @Path("tags/") + public final TagsResource getTags() { + return new TagsResource(this.id); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.java new file mode 100644 index 0000000000..eed78eef51 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.lang.reflect.Method; + +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.xml.namespace.QName; + +import org.eclipse.winery.model.tosca.TBoolean; +import org.eclipse.winery.model.tosca.TEntityType.DerivedFrom; +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Models a component instance with name, derived from, abstract, and final
+ * Tags are provided by AbstractComponentInstanceResource + * + * This class mirrors + * AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinalConfigurationBacked + * . We did not include interfaces as the getters are currently only called at + * the jsp + */ +public abstract class AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal extends AbstractComponentInstanceResource { + + private static final Logger logger = LoggerFactory.getLogger(AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.class); + + + protected AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal(TOSCAComponentId id) { + super(id); + } + + /** + * @return The associated name of this resource. CSDPR01 foresees a NCName + * name and no ID for an entity type. Therefore, we use the ID as + * unique identification and convert it to a name when a read + * request is put. + */ + @GET + @Path("name") + public String getName() { + return ModelUtilities.getName(this.getElement()); + } + + @PUT + @Path("name") + public Response putName(String name) { + ModelUtilities.setName(this.getElement(), name); + return BackendUtils.persist(this); + } + + @GET + @Path("derivedFrom") + public String getDerivedFrom() { + // TOSCA does not introduce a type like WithNameDerivedFromAbstractFinal + // We could enumerate all possible implementing classes + // Or use java reflection, what we're doing now. + Method method; + // We have three different "DerivedFrom", for NodeTypeImplementation and RelationshipTypeImplementation, we have to assign to a different "DerivedFrom" + // This has to be done in the derived resources + DerivedFrom derivedFrom; + try { + method = this.getElement().getClass().getMethod("getDerivedFrom"); + derivedFrom = (DerivedFrom) method.invoke(this.getElement()); + } catch (ClassCastException e) { + AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Seems that *Implementation is now Definitions backed, but not yet fully implented", e); + throw new IllegalStateException(e); + } catch (Exception e) { + AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Could not get derivedFrom", e); + throw new IllegalStateException(e); + } + if (derivedFrom == null) { + return null; + } + QName typeRef = derivedFrom.getTypeRef(); + if (typeRef == null) { + return null; + } else { + return typeRef.toString(); + } + } + + @PUT + @Path("derivedFrom") + public Response putDerivedFrom(String type) { + QName qname = QName.valueOf(type); + + // see getDerivedFrom for verbose comments + Method method; + DerivedFrom derivedFrom = new DerivedFrom(); + derivedFrom.setTypeRef(qname); + try { + method = this.getElement().getClass().getMethod("setDerivedFrom", DerivedFrom.class); + method.invoke(this.getElement(), derivedFrom); + } catch (ClassCastException e) { + AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Seems that *Implementation is now Definitions backed, but not yet fully implemented", e); + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build(); + } catch (Exception e) { + AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Could not set derivedFrom", e); + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build(); + } + + return BackendUtils.persist(this); + } + + /** + * @param methodName the method to call: getAbstract|getFinal + * @return {@inheritDoc} + */ + private String getTBoolean(String methodName) { + // see getDerivedFrom for verbose comments + Method method; + TBoolean tBoolean; + try { + method = this.getElement().getClass().getMethod(methodName); + tBoolean = (TBoolean) method.invoke(this.getElement()); + } catch (Exception e) { + AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Could not get boolean " + methodName, e); + throw new IllegalStateException(e); + } + if (tBoolean == null) { + return null; + } else { + return tBoolean.value(); + } + } + + /** + * @param methodName the method to call: setAbstract|setFinal + * @return {@inheritDoc} + */ + private Response putTBoolean(String tBooleanStr, String methodName) { + // see getDerivedFrom for verbose comments + + Method method; + TBoolean tBoolean = TBoolean.fromValue(tBooleanStr); + try { + method = this.getElement().getClass().getMethod(methodName, TBoolean.class); + method.invoke(this.getElement(), tBoolean); + } catch (Exception e) { + AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Could not set tBoolean " + methodName, e); + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build(); + } + + return BackendUtils.persist(this); + } + + /** + * Method name is not "getAbstract" as ${it.abstract} does not work as + * "abstract" is not allowed at that place + */ + @GET + @Path("abstract") + public String getIsAbstract() { + return this.getTBoolean("getAbstract"); + } + + @PUT + @Path("abstract") + public Response putIsAbstract(String isAbstract) { + return this.putTBoolean(isAbstract, "setAbstract"); + } + + @GET + @Path("final") + public String getIsFinal() { + return this.getTBoolean("getFinal"); + } + + @PUT + @Path("final") + public Response putIsFinal(String isFinal) { + return this.putTBoolean(isFinal, "setFinal"); + } + + /** + * @return resource managaing abstract, final, derivedFrom + */ + @Path("inheritance/") + public InheritanceResource getInheritanceManagement() { + return new InheritanceResource(this); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceWithReferencesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceWithReferencesResource.java new file mode 100644 index 0000000000..3b63b0fb05 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentInstanceWithReferencesResource.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import javax.ws.rs.core.Response; + +import org.eclipse.winery.model.tosca.Definitions; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; + +public abstract class AbstractComponentInstanceWithReferencesResource extends AbstractComponentInstanceResource { + + public AbstractComponentInstanceWithReferencesResource(TOSCAComponentId id) { + super(id); + } + + /** + * Ensures that the presented XML is in line with the stored files + */ + @Override + public Response getXML() { + this.synchronizeReferences(); + return super.getXML(); + } + + @Override + public String getDefinitionsAsXMLString() { + this.synchronizeReferences(); + return super.getDefinitionsAsXMLString(); + } + + @Override + public Definitions getDefinitions() { + this.synchronizeReferences(); + return super.getDefinitions(); + } + + /** + * Synchronizes the artifact references with the files stored in the + * repository + */ + public abstract void synchronizeReferences(); + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentsResource.java new file mode 100644 index 0000000000..2c2f258fc1 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentsResource.java @@ -0,0 +1,278 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.io.StringWriter; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.SortedSet; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.xml.namespace.QName; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.definitions.PolicyTemplateId; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.backend.ResourceCreationResult; +import org.eclipse.winery.repository.resources.entitytemplates.artifacttemplates.ArtifactTemplatesResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; +import com.sun.jersey.api.NotFoundException; +import com.sun.jersey.api.view.Viewable; + +/** + * Resource handling of a set of components. Each component has to provide a + * class to handle the set. This is required to provide the correct instances of + * TOSCAcomponentIds. + * + * TODO: Add generics here! + * {@link Utils.getComponentIdClassForComponentContainer} is then obsolete + */ +public abstract class AbstractComponentsResource { + + protected static final Logger logger = LoggerFactory.getLogger(AbstractComponentsResource.class); + + + @GET + @Produces(MediaType.TEXT_HTML) + public Response getHTML() { + return Response.ok().entity(new Viewable("/jsp/genericcomponentpage.jsp", new GenericComponentPageData(this.getClass()))).build(); + } + + /** + * Creates a new component instance in the given namespace + * + * @param namespace plain namespace + * @param id plain id + */ + protected ResourceCreationResult onPost(String namespace, String name) { + ResourceCreationResult res; + if (StringUtils.isEmpty(namespace) || StringUtils.isEmpty(name)) { + res = new ResourceCreationResult(Status.BAD_REQUEST); + } else { + String id = Utils.createXMLidAsString(name); + TOSCAComponentId tcId; + try { + tcId = this.getTOSCAcomponentId(namespace, id, false); + res = this.createComponentInstance(tcId); + // in case the resource additionally supports a name attribute, we set the original name + if (res.getStatus().equals(Status.CREATED)) { + if ((tcId instanceof ServiceTemplateId) || (tcId instanceof ArtifactTemplateId) || (tcId instanceof PolicyTemplateId)) { + // these three types have an additional name (instead of a pure id) + // we store the name + IHasName resource = (IHasName) AbstractComponentsResource.getComponentInstaceResource(tcId); + resource.setName(name); + } + } + } catch (Exception e) { + AbstractComponentsResource.logger.debug("Could not create id instance", e); + res = new ResourceCreationResult(Status.INTERNAL_SERVER_ERROR); + } + } + return res; + } + + /** + * Creates a new component instance in the given namespace + * + * @param namespace plain namespace + * @param id plain id + * @param ignored this parameter is ignored, but necessary for + * {@link ArtifactTemplatesResource} to be able to accept the + * artifact type at a post + */ + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + public Response onPost(@FormParam("namespace") String namespace, @FormParam("name") String name, String ignored) { + ResourceCreationResult res = this.onPost(namespace, name); + return res.getResponse(); + } + + /** + * Creates a TOSCAcomponentId for the given namespace / id combination + * + * Uses reflection to create a new instance + */ + protected TOSCAComponentId getTOSCAcomponentId(String namespace, String id, boolean URLencoded) throws Exception { + Class idClass = Utils.getComponentIdClassForComponentContainer(this.getClass()); + return BackendUtils.getTOSCAcomponentId(idClass, namespace, id, URLencoded); + } + + /** + * Creates a new instance of the current component + * + * @return
    + *
  • Status.CREATED (201) if the resource has been created,
  • + *
  • Status.CONFLICT if the resource already exists,
  • + *
  • Status.INTERNAL_SERVER_ERROR (500) if something went wrong
  • + *
+ */ + protected ResourceCreationResult createComponentInstance(TOSCAComponentId tcId) { + return BackendUtils.create(tcId); + } + + @SuppressWarnings("unchecked") + private static Class getComponentInstanceResourceClassForType(String type) { + // Guess the package + String pkg = "org.eclipse.winery.repository.resources."; + + pkg += Utils.getIntermediateLocationStringForType(type, "."); + + // naming convention: Instance is named after container, but without the + // plural s + String className = pkg + "." + type + "Resource"; + try { + return (Class) Class.forName(className); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("Could not find id class for component instance", e); + } + } + + /** + * + * @param namespace encoded namespace + * @param id encoded id + * @return an instance of the requested resource + */ + @Path("{namespace}/{id}/") + public AbstractComponentInstanceResource getComponentInstaceResource(@PathParam("namespace") String namespace, @PathParam("id") String id) { + return this.getComponentInstaceResource(namespace, id, true); + } + + /** + * @param encoded specifies whether namespace and id are encoded + * @return an instance of the requested resource + */ + public AbstractComponentInstanceResource getComponentInstaceResource(String namespace, String id, boolean encoded) { + TOSCAComponentId tcId; + try { + tcId = this.getTOSCAcomponentId(namespace, id, encoded); + } catch (Exception e) { + throw new IllegalStateException("Could not create id instance", e); + } + return AbstractComponentsResource.getComponentInstaceResource(tcId); + } + + /** + * @return an instance of the requested resource + */ + public AbstractComponentInstanceResource getComponentInstaceResource(QName qname) { + return this.getComponentInstaceResource(qname.getNamespaceURI(), qname.getLocalPart(), false); + } + + /** + * @return an instance of the requested resource + * @throws NotFoundException if resource doesn't exist. + */ + public static AbstractComponentInstanceResource getComponentInstaceResource(TOSCAComponentId tcId) { + String type = Util.getTypeForComponentId(tcId.getClass()); + if (!Repository.INSTANCE.exists(tcId)) { + AbstractComponentsResource.logger.debug("TOSCA component id " + tcId.toString() + " not found"); + throw new NotFoundException("TOSCA component id " + tcId.toString() + " not found"); + } + Class newResource = AbstractComponentsResource.getComponentInstanceResourceClassForType(type); + Constructor[] constructors = newResource.getConstructors(); + assert (constructors.length == 1); + AbstractComponentInstanceResource newInstance; + try { + newInstance = (AbstractComponentInstanceResource) constructors[0].newInstance(tcId); + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + AbstractComponentsResource.logger.error("Could not instantiate sub resource " + tcId); + throw new IllegalStateException("Could not instantiate sub resource", e); + } + return newInstance; + } + + /** + * Returns resources for all known component instances + * + * Required by topologytemplateedit.jsp + */ + public Collection getAll() { + Class idClass = Utils.getComponentIdClassForComponentContainer(this.getClass()); + SortedSet allTOSCAcomponentIds = Repository.INSTANCE.getAllTOSCAComponentIds(idClass); + ArrayList res = new ArrayList(allTOSCAcomponentIds.size()); + for (TOSCAComponentId id : allTOSCAcomponentIds) { + AbstractComponentInstanceResource r = AbstractComponentsResource.getComponentInstaceResource(id); + res.add(r); + } + return res; + } + + /** + * Used by org.eclipse.winery.repository.repository.client and by the + * artifactcreationdialog.tag. Especially the "name" field is used there at + * the UI + * + * @return A list of all ids of all instances of this component type. If the + * "name" attribute is required, that name is used as id
+ * Format: + * [({"namespace": "", "id": ""},)* ]. A + * name field is added if the model allows an additional name attribute + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public String getListOfAllIds() { + Class idClass = Utils.getComponentIdClassForComponentContainer(this.getClass()); + boolean supportsNameAttribute = Util.instanceSupportsNameAttribute(idClass); + SortedSet allTOSCAcomponentIds = Repository.INSTANCE.getAllTOSCAComponentIds(idClass); + JsonFactory jsonFactory = new JsonFactory(); + StringWriter sw = new StringWriter(); + + try { + JsonGenerator jg = jsonFactory.createGenerator(sw); + // We produce org.eclipse.winery.repository.client.WineryRepositoryClient.NamespaceAndId by hand here + // Refactoring could move this class to common and fill it here + jg.writeStartArray(); + for (TOSCAComponentId id : allTOSCAcomponentIds) { + jg.writeStartObject(); + jg.writeStringField("namespace", id.getNamespace().getDecoded()); + jg.writeStringField("id", id.getXmlId().getDecoded()); + if (supportsNameAttribute) { + AbstractComponentInstanceResource componentInstaceResource = AbstractComponentsResource.getComponentInstaceResource(id); + String name = ((IHasName) componentInstaceResource).getName(); + jg.writeStringField("name", name); + } + jg.writeEndObject(); + } + jg.writeEndArray(); + jg.close(); + } catch (Exception e) { + AbstractComponentsResource.logger.error(e.getMessage(), e); + return "[]"; + } + return sw.toString(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentsWithTypeReferenceResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentsWithTypeReferenceResource.java new file mode 100644 index 0000000000..c57196c2ff --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/AbstractComponentsWithTypeReferenceResource.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.repository.backend.ResourceCreationResult; +import org.restdoc.annotations.RestDocParam; + +/** + * This class does NOT inherit from TEntityTemplatesResource + * as these templates are directly nested in a TDefinitionsElement + */ +public class AbstractComponentsWithTypeReferenceResource extends AbstractComponentsResource { + + /** + * Creates the resource and sets the specified type + * + * In contrast to the other component instances in this package, we + * additionally need the parameter "type" to set the type of the artifact + * template. + * + * @param namespace Namespace of the template + * @param name name attribute of the template + * @param type: QName of the type, format: {namespace}localname is retrieved + * from namespace manager + * + * @return URI of the created Resource, null if resource already exists, + * URI_internalServerError if an internal server error occurred + */ + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + @Override + public Response onPost(@RestDocParam(description = "Namespace of the component") @FormParam("namespace") String namespace, @RestDocParam(description = "name attribute of the component") @FormParam("name") String name, @RestDocParam(description = "QName of the type, format: {namespace}localname") @FormParam("type") String type) { + // only check for type parameter as namespace and name are checked in super.onPost + if (StringUtils.isEmpty(type)) { + return Response.status(Status.BAD_REQUEST).build(); + } + ResourceCreationResult creationResult = super.onPost(namespace, name); + if (!creationResult.isSuccess()) { + return creationResult.getResponse(); + } + if (creationResult.getStatus().equals(Status.CREATED)) { + IHasTypeReference resource = (IHasTypeReference) AbstractComponentsResource.getComponentInstaceResource((TOSCAComponentId) creationResult.getId()); + resource.setType(type); + // we assume that setType succeeded and just return the result of the + // creation of the artifact template resource + // Thus, we do NOT change res + } + return creationResult.getResponse(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/ConstraintResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/ConstraintResource.java new file mode 100644 index 0000000000..b9eb3459ed --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/ConstraintResource.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.eclipse.winery.model.tosca.TConstraint; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; + +public class ConstraintResource extends EntityWithoutIdResource { + + /** + * + * @param constraint the current constraint value + * @param list the list this constraint belongs to + * @param res the node type resource this constraint belongs to. Required + * for saving + */ + public ConstraintResource(TConstraint constraint, int idx, List list, NodeTypeResource res) { + super(constraint, idx, list, res); + } + + /** + * Required for collectionResource + * + * @throws ClassCastException of !(res instanceof NodeTypeResource) + */ + public ConstraintResource(TConstraint constraint, int idx, List list, AbstractComponentInstanceResource res) { + this(constraint, idx, list, (NodeTypeResource) res); + } + + private TConstraint getConstraint() { + return this.o; + } + + @GET + @Path("type") + @Produces(MediaType.TEXT_PLAIN) + public String getConstraintType() { + return this.getConstraint().getConstraintType(); + } + + @PUT + @Path("type") + @Consumes(MediaType.TEXT_PLAIN) + public Response putConstraintType(String constraintType) { + this.getConstraint().setConstraintType(constraintType); + return BackendUtils.persist(this.res); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/ConstraintsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/ConstraintsResource.java new file mode 100644 index 0000000000..8aea92ffc9 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/ConstraintsResource.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.util.List; + +import org.eclipse.winery.model.tosca.TConstraint; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdCollectionResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; + +public class ConstraintsResource extends EntityWithoutIdCollectionResource { + + private static final Logger logger = LoggerFactory.getLogger(ConstraintsResource.class); + + + public ConstraintsResource(List constraints, NodeTypeResource res) { + super(ConstraintResource.class, TConstraint.class, constraints, res); + } + + @Override + public Viewable getHTML() { + // TODO Auto-generated method stub + throw new IllegalStateException("Not yet implemented."); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/EntityTypeResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/EntityTypeResource.java new file mode 100644 index 0000000000..b70561b921 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/EntityTypeResource.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.model.tosca.TEntityType; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.datatypes.select2.Select2DataItem; +import org.eclipse.winery.repository.datatypes.select2.Select2OptGroup; +import org.eclipse.winery.repository.resources.entitytypes.properties.PropertiesDefinitionResource; + +public abstract class EntityTypeResource extends AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal { + + protected EntityTypeResource(TOSCAComponentId id) { + super(id); + } + + @Override + protected void copyIdToFields() { + TEntityType entityType = this.getEntityType(); + entityType.setTargetNamespace(this.getId().getNamespace().getDecoded()); + entityType.setName(this.getId().getXmlId().getDecoded()); + } + + /** + * Convenience method to avoid casting. Required by + * PropertiesDefinitionResource's jsp + */ + public TEntityType getEntityType() { + return (TEntityType) this.element; + } + + /** + * Models PropertiesDefinition + */ + @Path("propertiesdefinition/") + public PropertiesDefinitionResource getPropertiesDefinitionResource() { + return new PropertiesDefinitionResource(this); + } + + /** + * Used by children to implement getListOfAllInstances() + */ + protected SortedSet getListOfAllInstances(Class clazz) { + Map idx = new HashMap<>(); + + Collection instanceIds = BackendUtils.getAllElementsRelatedWithATypeAttribute(clazz, this.id.getQName()); + + for (TOSCAComponentId instanceId : instanceIds) { + String groupText = instanceId.getNamespace().getDecoded(); + Select2OptGroup optGroup = idx.get(groupText); + if (optGroup == null) { + optGroup = new Select2OptGroup(groupText); + idx.put(groupText, optGroup); + } + + String text = BackendUtils.getName(instanceId); + Select2DataItem item = new Select2DataItem(instanceId.getQName().toString(), text); + optGroup.addItem(item); + } + + // convert the index to the real result + SortedSet res = new TreeSet<>(); + for (Select2OptGroup optGroup : idx.values()) { + res.add(optGroup); + } + + return res; + } + + /** + * Returns an array suitable for processing in a {@code select2} field See + * {@link http://ivaynberg.github.io/select2} + * + * Each element: {id: "{ns}localname", text: "name/id"} + */ + @Path("instances/") + @GET + @Produces(MediaType.APPLICATION_JSON) + public SortedSet getListOfAllInstances() { + Response res = Response.status(Status.INTERNAL_SERVER_ERROR).entity("not yet implemented").build(); + throw new WebApplicationException(res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericComponentPageData.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericComponentPageData.java new file mode 100644 index 0000000000..a2a8533dee --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericComponentPageData.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.util.Collection; +import java.util.Collections; +import java.util.SortedSet; + +import org.eclipse.winery.common.ids.definitions.ArtifactTypeId; +import org.eclipse.winery.common.ids.definitions.NodeTypeId; +import org.eclipse.winery.common.ids.definitions.PolicyTypeId; +import org.eclipse.winery.common.ids.definitions.RelationshipTypeId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources.entitytemplates.artifacttemplates.ArtifactTemplatesResource; +import org.eclipse.winery.repository.resources.entitytemplates.policytemplates.PolicyTemplatesResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.nodetypeimplementations.NodeTypeImplementationsResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.relationshiptypeimplementations.RelationshipTypeImplementationsResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class GenericComponentPageData { + + private static final Logger logger = LoggerFactory.getLogger(GenericComponentPageData.class); + + private final SortedSet componentInstanceIds; + + private final Class resourceClass; + + + public GenericComponentPageData(Class resourceClass) { + this.resourceClass = resourceClass; + Class cIdClass = Utils.getComponentIdClassForComponentContainer(resourceClass); + this.componentInstanceIds = Repository.INSTANCE.getAllTOSCAComponentIds(cIdClass); + } + + /** + * Outputs the data for GenericComponentPage (Name / Id / Namespace) needed + * for the genericcomponentpage.jsp + */ + public SortedSet getComponentInstanceIds() { + return this.componentInstanceIds; + } + + public String getType() { + return Utils.getTypeForComponentContainer(this.resourceClass); + } + + public String getCSSclass() { + // The resources do NOT know their CSS class + // Layout is far away from a resource + // Instead of a huge if/else-cascade, we derive the CSS name from the + // class name + String type = this.getType(); + // convention: first letter in small letters + String res = type.substring(0, 1).toLowerCase() + type.substring(1); + // this generated "xSDImport" as CSS class for XSDImport + return res; + } + + public String getLabel() { + String type = this.getType(); + // E.g., convert ArtifactTemplate to Artifact Template + String res = type.replaceAll("(\\p{Lower})(\\p{Upper})", "$1 $2"); + return res; + } + + /** + * Required for genericcomponentpage.jsp -> addComponentInstance.jsp + * + * May only be used if the component supports the type (e.g., artifact + * templates) + * + * @return the list of all known types + */ + public Collection getTypeSelectorData() { + Class typeIdClass; + if (this.resourceClass.equals(ArtifactTemplatesResource.class)) { + typeIdClass = ArtifactTypeId.class; + } else if (this.resourceClass.equals(NodeTypeImplementationsResource.class)) { + typeIdClass = NodeTypeId.class; + } else if (this.resourceClass.equals(RelationshipTypeImplementationsResource.class)) { + typeIdClass = RelationshipTypeId.class; + } else if (this.resourceClass.equals(PolicyTemplatesResource.class)) { + typeIdClass = PolicyTypeId.class; + } else { + return Collections.emptyList(); + } + SortedSet allTOSCAcomponentIds = Repository.INSTANCE.getAllTOSCAComponentIds(typeIdClass); + return allTOSCAcomponentIds; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericKeyValueResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericKeyValueResource.java new file mode 100644 index 0000000000..5845195cad --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericKeyValueResource.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.Iterator; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.StreamingOutput; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.XMLPropertiesConfiguration; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.backend.Repository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GenericKeyValueResource { + + private static final Logger logger = LoggerFactory.getLogger(GenericKeyValueResource.class); + + protected final Configuration configuration; + + + public GenericKeyValueResource(RepositoryFileReference ref) { + this.configuration = Repository.INSTANCE.getConfiguration(ref); + } + + @GET + @Path("{name}/") + @Produces(MediaType.TEXT_PLAIN) + public Response getValue(@PathParam("name") String name) { + name = Util.URLdecode(name); + if (this.configuration.containsKey(name)) { + String value = this.configuration.getString(name); + return Response.ok(value).build(); + } else { + return Response.status(Status.NOT_FOUND).build(); + } + } + + @DELETE + @Path("{name}/") + public Response deleteValue(@PathParam("name") String name) { + name = Util.URLdecode(name); + if (this.configuration.containsKey(name)) { + this.configuration.clearProperty(name); + // according to http://stackoverflow.com/a/2342589/873282, HTTP 204 + // NO CONTENT should be sent instead of HTTP 200 OK if no entity is + // included in the answer + return Response.noContent().build(); + } else { + return Response.status(Status.NOT_FOUND).build(); + } + } + + /** + * @param name the key to set + * @param value the value to put. Contained in the body of the message. + * @return + */ + @PUT + @Path("{name}/") + public Response createOrUpdateValue(@PathParam("name") String name, String value) { + this.configuration.setProperty(name, value); + return Response.noContent().build(); + } + + /** + * Note that this is implemented differently in PropertiesDefinition. There, + * a JSON object is returned instead of an XML document + * + * @return an XML following http://java.sun.com/dtd/properties.dtd + */ + @GET + @Produces(MediaType.TEXT_XML) + public Response getAllProperties() { + final XMLPropertiesConfiguration xmlConf = new XMLPropertiesConfiguration(); + Iterator keys = this.configuration.getKeys(); + // copy over the whole configuration to the xml configuration + while (keys.hasNext()) { + String key = keys.next(); + xmlConf.addProperty(key, this.configuration.getProperty(key)); + } + StreamingOutput so = new StreamingOutput() { + + @Override + public void write(OutputStream output) throws IOException, WebApplicationException { + try (Writer w = new OutputStreamWriter(output, "UTF-8");) { + xmlConf.save(w); + } catch (ConfigurationException e) { + GenericKeyValueResource.logger.error(e.getMessage(), e); + } + } + }; + return Response.ok().entity(so).build(); + + } + + /** + * Returns a reference to the internal data structure. Used by the exporter + * for serialization + * + * @return reference to internal data structure + */ + public Configuration getConfiguration() { + return this.configuration; + } + + /** + * Replaces the configuration values by the configuration values provided + * + * @param configuration the configuration values that should replace the + * current configuration + */ + public void setConfiguration(Configuration configuration) { + this.configuration.clear(); + // we have to copy the configuration manually as Configuration does not offer copying a complete configuration + Iterator keys = configuration.getKeys(); + while (keys.hasNext()) { + String key = keys.next(); + this.configuration.setProperty(key, configuration.getProperty(key)); + } + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericVisualAppearanceResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericVisualAppearanceResource.java new file mode 100644 index 0000000000..f717e73a6c --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/GenericVisualAppearanceResource.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.io.InputStream; +import java.net.URI; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.apache.commons.configuration.Configuration; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.ids.elements.TOSCAElementId; +import org.eclipse.winery.repository.Prefs; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.backend.constants.Filename; +import org.eclipse.winery.repository.datatypes.ids.elements.VisualAppearanceId; +import org.eclipse.winery.repository.resources.entitytypes.TopologyGraphElementEntityTypeResource; + +//import com.fasterxml.jackson.annotation.JsonIgnore; // currently not required +import com.sun.jersey.multipart.FormDataBodyPart; +import com.sun.jersey.multipart.FormDataParam; + +/** + * Contains methods for both visual appearance for + *
    + *
  • node types
  • + *
  • relationship types
  • + *
+ */ +public abstract class GenericVisualAppearanceResource { + + protected final Map otherAttributes; + protected final TopologyGraphElementEntityTypeResource res; + protected final TOSCAElementId id; + protected Configuration configuration; + + + @DELETE + public Response onDelete() { + return BackendUtils.delete(this.id); + } + + /** + * Used for GUI when accessing the resource as data E.g., for topology + * template + */ + //@JsonIgnore + public URI getAbsoluteURL() { + String URI = Prefs.INSTANCE.getResourcePath(); + URI = URI + "/" + Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(this.id)); + return Utils.createURI(URI); + } + + //@JsonIgnore + public TOSCAElementId getId() { + return this.id; + } + + /** + * @param res + * @param otherAttributes the other attributes of the node/relationship type + * @param id the id of this subresource required for storing the images + */ + public GenericVisualAppearanceResource(TopologyGraphElementEntityTypeResource res, Map otherAttributes, VisualAppearanceId id) { + this.id = id; + this.configuration = Repository.INSTANCE.getConfiguration(id); + this.res = res; + this.otherAttributes = otherAttributes; + } + + /** + * Determines repository reference to file in repo + */ + protected RepositoryFileReference getRepoFileRef(String name) { + return new RepositoryFileReference(this.id, name); + } + + protected Response getImage(String name, String modified) { + RepositoryFileReference target = this.getRepoFileRef(name); + return BackendUtils.returnRepoPath(target, modified); + } + + /** + * Arbitrary images are supported. There currently is no check for valid + * image media types + */ + protected Response putImage(String name, InputStream uploadedInputStream, MediaType mediaType) { + RepositoryFileReference target = this.getRepoFileRef(name); + return BackendUtils.putContentToFile(target, uploadedInputStream, mediaType); + } + + @GET + @Path("16x16") + public Response get16x16Image(@HeaderParam("If-Modified-Since") String modified) { + // Even if the extension is "png", it might contain a jpg, too + // We keep the file extension as the windows explorer can display previews even if the content is not a png + return this.getImage(Filename.FILENAME_SMALL_ICON, modified); + } + + @PUT + @Path("16x16") + @Consumes(MediaType.MULTIPART_FORM_DATA) + public Response post16x16Image(@FormDataParam("file") InputStream uploadedInputStream, @FormDataParam("file") FormDataBodyPart body) { + return this.putImage(Filename.FILENAME_SMALL_ICON, uploadedInputStream, body.getMediaType()); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/IHasName.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/IHasName.java new file mode 100644 index 0000000000..08a3696ccd --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/IHasName.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.restdoc.annotations.RestDoc; + +/** + * Ensures that the AbstractComponentInstance has a getName method + */ +public interface IHasName { + + @GET + @Path("name") + // @formatter:off + @RestDoc(methodDescription = "Returns the name of the element. " + + "Defaults to the ID of the element. " + + "Some other ComponentInstances either carry a name or an ID. ") + // @formatter:on + @Produces(MediaType.TEXT_PLAIN) + public String getName(); + + @PUT + @Path("name") + public Response setName(@FormParam("value") String name); + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/IHasTypeReference.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/IHasTypeReference.java new file mode 100644 index 0000000000..cb42158f9f --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/IHasTypeReference.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +public interface IHasTypeReference { + + /** + * @return the QName of the type with full namespace, never null (according + * to spec) + */ + public QName getType(); + + /** + * Sets the type and directly persists the resource + */ + public Response setType(QName type); + + /** + * Calls setType(QName) with QName.valueOf(typeStr) + * + * Directly persists the resource + * + * @param typeStr a textual representation of a QName + */ + public Response setType(String typeStr); + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTemplateResourceOrNodeTypeImplementationResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTemplateResourceOrNodeTypeImplementationResource.java new file mode 100644 index 0000000000..c8438efe3c --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTemplateResourceOrNodeTypeImplementationResource.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +/** + * Implementors can have DAs attached + */ +public interface INodeTemplateResourceOrNodeTypeImplementationResource extends INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource { + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource.java new file mode 100644 index 0000000000..7bd178e037 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import org.eclipse.winery.common.ids.Namespace; + +/** + * Implementors can have IAs or DAs attached + */ +public interface INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource { + + Namespace getNamespace(); + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTypeImplementationResourceOrRelationshipTypeImplementationResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTypeImplementationResourceOrRelationshipTypeImplementationResource.java new file mode 100644 index 0000000000..892a7cbc73 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/INodeTypeImplementationResourceOrRelationshipTypeImplementationResource.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +/** + * Implementors can have IAs attached + */ +public interface INodeTypeImplementationResourceOrRelationshipTypeImplementationResource extends INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource { + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/InheritanceResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/InheritanceResource.java new file mode 100644 index 0000000000..7cc878ad80 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/InheritanceResource.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.ws.rs.GET; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.repository.backend.Repository; + +import com.sun.jersey.api.view.Viewable; + +/** + * Class for managing inheritance properties: abstract, final, derivedFromn + * + * The linking in the resources tree is different than the others. Here, there + * is no additional Id generated. + * + * We separated the code here to have the collection of valid super types in a + * separate class. We think, this is less confusing than including this + * functionality in + * AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinalDefinitionsBacked + */ +public class InheritanceResource { + + private AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal managedResource; + + + public InheritanceResource(AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal res) { + this.managedResource = res; + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML() { + return new Viewable("/jsp/inheritance.jsp", this); + } + + public String getIsAbstract() { + return this.managedResource.getIsAbstract(); + } + + public String getIsFinal() { + return this.managedResource.getIsAbstract(); + } + + public String getDerivedFrom() { + return this.managedResource.getDerivedFrom(); + } + + /** JSP Data **/ + + public SortedSet getPossibleSuperTypes() { + // sorted by Name, not by namespace + SortedSet allTOSCAcomponentIds = Repository.INSTANCE.getAllTOSCAComponentIds(this.managedResource.getId().getClass()); + SortedSet res = new TreeSet<>(allTOSCAcomponentIds); + res.remove(this.managedResource.getId()); + // FEATURE: Possibly exclude all subtypes to avoid circles. However, this could be disappointing for users who know what they are doing + return res; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/MainResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/MainResource.java new file mode 100644 index 0000000000..3d2e46c56e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/MainResource.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.importing.CSARImporter; +import org.eclipse.winery.repository.resources.admin.AdminTopResource; +import org.eclipse.winery.repository.resources.entitytemplates.artifacttemplates.ArtifactTemplatesResource; +import org.eclipse.winery.repository.resources.entitytemplates.policytemplates.PolicyTemplatesResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.nodetypeimplementations.NodeTypeImplementationsResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.relationshiptypeimplementations.RelationshipTypeImplementationsResource; +import org.eclipse.winery.repository.resources.entitytypes.artifacttypes.ArtifactTypesResource; +import org.eclipse.winery.repository.resources.entitytypes.capabilitytypes.CapabilityTypesResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypesResource; +import org.eclipse.winery.repository.resources.entitytypes.policytypes.PolicyTypesResource; +import org.eclipse.winery.repository.resources.entitytypes.relationshiptypes.RelationshipTypesResource; +import org.eclipse.winery.repository.resources.entitytypes.requirementtypes.RequirementTypesResource; +import org.eclipse.winery.repository.resources.imports.ImportsResource; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplatesResource; +import org.restdoc.annotations.RestDoc; +import org.restdoc.annotations.RestDocReturnCode; + +import com.sun.jersey.api.view.Viewable; +import com.sun.jersey.core.header.FormDataContentDisposition; +import com.sun.jersey.multipart.FormDataParam; + +/** + * All paths listed here have to be listed in Jersey's filter configuration + */ +@Path("/") +public class MainResource { + + @Path("artifacttemplates/") + public ArtifactTemplatesResource artifacttemplates() { + return new ArtifactTemplatesResource(); + } + + @Path("artifacttypes/") + public ArtifactTypesResource artifactypes() { + return new ArtifactTypesResource(); + } + + @Path("admin/") + public AdminTopResource admin() { + return new AdminTopResource(); + } + + @Path("capabilitytypes/") + public CapabilityTypesResource capabilitytypes() { + return new CapabilityTypesResource(); + } + + @Path("imports/") + public ImportsResource imports() { + return new ImportsResource(); + } + + @Path("nodetypes/") + public NodeTypesResource nodetypes() { + return new NodeTypesResource(); + } + + @Path("nodetypeimplementations/") + public NodeTypeImplementationsResource nodetypeimplementations() { + return new NodeTypeImplementationsResource(); + } + + @Path("other/") + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getOtherElements() { + return new Viewable("/jsp/otherElements.jsp"); + } + + @Path("policytemplates/") + public PolicyTemplatesResource policytemplates() { + return new PolicyTemplatesResource(); + } + + @Path("policytypes/") + public PolicyTypesResource policytypes() { + return new PolicyTypesResource(); + } + + @Path("relationshiptypes/") + public RelationshipTypesResource relationshiptypes() { + return new RelationshipTypesResource(); + } + + @Path("requirementtypes/") + public RequirementTypesResource requirementtypes() { + return new RequirementTypesResource(); + } + + @Path("relationshiptypeimplementations/") + public RelationshipTypeImplementationsResource relationshiptypeimplementations() { + return new RelationshipTypeImplementationsResource(); + } + + @Path("servicetemplates/") + public ServiceTemplatesResource servicetemplates() { + return new ServiceTemplatesResource(); + } + + /** + * Returns the main page of winery. + */ + @GET + @Produces(MediaType.TEXT_HTML) + public Response onGet() { + return Response.temporaryRedirect(Utils.createURI("servicetemplates/")).build(); + } + + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @RestDoc(methodDescription = "Imports the given CSAR (sent by simplesinglefileupload.jsp)") + @RestDocReturnCode(code = "200", description = "If the CSAR could be partially imported, the points where it failed are returned in the body") + public Response importCSAR(@FormDataParam("file") InputStream uploadedInputStream, @FormDataParam("file") FormDataContentDisposition fileDetail) { + CSARImporter importer = new CSARImporter(); + List errors = new ArrayList(); + try { + importer.readCSAR(uploadedInputStream, errors); + } catch (Exception e) { + return Response.serverError().entity("Could not import CSAR").entity(e.getMessage()).build(); + } + if (errors.isEmpty()) { + return Response.noContent().build(); + } else { + // In case there are errors, we send them as "bad request" + return Response.status(Status.BAD_REQUEST).entity(errors).build(); + } + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/SubMenuData.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/SubMenuData.java new file mode 100644 index 0000000000..3f79c87b32 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/SubMenuData.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +/** + * Data used to render a submenu item + */ +public class SubMenuData { + + private final String href; + private final String text; + + public static final SubMenuData SUBMENU_DOCUMENTATION = new SubMenuData("#documentation", "Documentation"); + public static final SubMenuData SUBMENU_XML = new SubMenuData("#xml", "XML"); + + + public SubMenuData(String href, String text) { + this.href = href; + this.text = text; + } + + public String getHref() { + return this.href; + } + + public String getText() { + return this.text; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/IPersistable.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/IPersistable.java new file mode 100644 index 0000000000..85f565c898 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/IPersistable.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources._support; + +import java.io.IOException; + +public interface IPersistable { + + /** + * @throws IOException if content could not be updated in the repository + * @throws IllegalStateException if an JAXBException occurred. This should + * never happen. + */ + public void persist() throws IOException; +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/CollectionsHelper.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/CollectionsHelper.java new file mode 100644 index 0000000000..f150855ce9 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/CollectionsHelper.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources._support.collections; + +import javax.ws.rs.core.Response; + +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources._support.IPersistable; + +public class CollectionsHelper { + + private CollectionsHelper() { + } + + /** + * + * @param + * @param resource the resource to be persisted + * @param idDetermination the object to use to determine the id of the + * entity + * @param entity the entity that was persisted. Used to determine the id + * @return the new id id of the resource + */ + public static Response persist(IPersistable resource, IIdDetermination idDetermination, X entity) { + Response res = BackendUtils.persist(resource); + if (res.getStatus() == 204) { + String id = idDetermination.getId(entity); + res = Response.ok(id).build(); + } + return res; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/EntityCollectionResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/EntityCollectionResource.java new file mode 100644 index 0000000000..64d0fbe824 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/EntityCollectionResource.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources._support.collections; + +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.datatypes.select2.Select2DataItem; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.restdoc.annotations.RestDoc; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.NotFoundException; +import com.sun.jersey.api.view.Viewable; + +/** + * Class managing a list of entities. It is intended to manage subresources, + * which are stored in a list. Either all entities have a unique key given by + * the TOSCA specification (subclass EntityWithIdCollectionResource) or a unique + * key is generated (subclass EntityWithoutIdCollectionResource) + * + * @param the resource modeling the entity + * @param the entity type of single items in the list + */ +public abstract class EntityCollectionResource, EntityT> implements IIdDetermination { + + private static final Logger logger = LoggerFactory.getLogger(EntityCollectionResource.class); + + protected final List list; + + protected final IPersistable res; + + protected final Class entityTClazz; + + protected final Class entityResourceTClazz; + + + /** + * @param clazz the class of EntityT. Required as it is not possible to call + * new EntityT (see http://stackoverflow.com/a/1090488/873282) + * @param list the list of entities contained in this resource. Has to be + * typed as not all TOSCA elements in the specification + * inherit from TExtensibleElements + * @param res the main resource the list is belonging to. Required for + * persistence. + */ + public EntityCollectionResource(Class entityResourceTClazz, Class entityTClazz, List list, IPersistable res) { + this.entityResourceTClazz = entityResourceTClazz; + this.entityTClazz = entityTClazz; + this.list = list; + this.res = res; + } + + /** + * Returns a list of ids of all entities nested here + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public Object getListOfAllEntityIds(@QueryParam("select2") String select2) { + if (select2 == null) { + return this.getListOfAllEntityIdsAsList(); + } else { + // return data ready for consumption by select2 + List res = new ArrayList(this.list.size()); + for (EntityT o : this.list) { + String id = this.getId(o); + Select2DataItem di = new Select2DataItem(id, id); + res.add(di); + } + return res; + } + } + + public List getListOfAllEntityIdsAsList() { + List res = new ArrayList(this.list.size()); + for (EntityT o : this.list) { + // We assume that different Object serializations *always* have different hashCodes + res.add(this.getId(o)); + } + return res; + } + + /** + * Required by reqandcapdefs.jsp + */ + public List getAllEntityResources() { + List listOfAllSubResources = this.getListOfAllEntityIdsAsList(); + List res = new ArrayList(listOfAllSubResources.size()); + for (String id : listOfAllSubResources) { + res.add(this.getEntityResourceFromDecodedId(id)); + } + return res; + } + + public EntityResourceT getEntityResourceFromDecodedId(String id) { + EntityT entity = null; + int idx = -1; + for (EntityT c : this.list) { + idx++; + String cId = this.getId(c); + if (cId.equals(id)) { + entity = c; + break; + } + } + if (entity == null) { + throw new NotFoundException(); + } else { + return this.getEntityResourceInstance(entity, idx); + } + } + + @Path("{id}/") + public EntityResourceT getEntityResource(@PathParam("id") String id) { + if (id == null) { + throw new IllegalArgumentException("id has to be given"); + } + id = Util.URLdecode(id); + return this.getEntityResourceFromDecodedId(id); + } + + /** + * @param entity the entity to create a resource for + * @param idx the index in the list + * @return the resource managing the given entity + */ + protected abstract EntityResourceT getEntityResourceInstance(EntityT entity, int idx); + + @GET + @Produces(MediaType.TEXT_HTML) + @RestDoc(methodDescription = "@return the HTML fragment (DIV-container) to be embedded in the 'Interface' part of nodetype.js ") + public Response getHTMLAsResponse() { + Viewable viewable = this.getHTML(); + return Response.ok().header(HttpHeaders.VARY, HttpHeaders.ACCEPT).entity(viewable).build(); + } + + /** + * called by getHTMLAsResponse + */ + public abstract Viewable getHTML(); + + /** + * Adds a new entity + * + * In case the element already exists, we return "CONFLICT" + */ + @POST + @Consumes({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response addNewElement(EntityT entity) { + if (entity == null) { + return Response.status(Status.BAD_REQUEST).entity("a valid XML/JSON element has to be posted").build(); + } + if (this.alreadyContains(entity)) { + // we do not replace the element, but replace it + return Response.status(Status.CONFLICT).build(); + } + this.list.add(entity); + return CollectionsHelper.persist(this.res, this, entity); + } + + @Override + public abstract String getId(EntityT entity); + + /** + * Checks for containment of e in the list. equals is not used + * as most EntityT do not offer a valid implementation + * + * @return true if list already contains e. + */ + public boolean alreadyContains(EntityT e) { + String id = this.getId(e); + for (EntityT el : this.list) { + if (this.getId(el).equals(id)) { + // break loop + // we found an equal list item + return true; + } + } + // all items checked: nothing equal contained + return false; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/EntityResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/EntityResource.java new file mode 100644 index 0000000000..bd08c9be00 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/EntityResource.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources._support.collections; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources._support.IPersistable; + +/** + * Class to hold a single entity residing in a list of entities + * + * @param the entity type contained in the list + */ +public abstract class EntityResource { + + // This is non-final as a "PUT" may update the object + // it might be unnecessary to update this object as the resource is created at each request + // We update the reference nevertheless to be safe if the resource is used in another context + protected EntityT o; + + protected final int idx; + + protected final List list; + + protected final IPersistable res; + + protected IIdDetermination idDetermination; + + + /** + * + * @param idDetermination the object offering determination of an id of + * EntityT. May be null. If null, then setIdDetermination(obj) + * has to be called to enable this class functioning properly + * @param o the object this resource is representing + * @param idx the index of the object in the list + * @param list the list, where the object is stored in + * @param res the resource the object/list belongs to + */ + public EntityResource(IIdDetermination idDetermination, EntityT o, int idx, List list, IPersistable res) { + this.idDetermination = idDetermination; + this.o = o; + this.idx = idx; + this.list = list; + this.res = res; + } + + /** + * Quick hack for AbstractReqOrCapDefResource which is itself an + * IIdDetermination + */ + protected final void setIdDetermination(IIdDetermination idDetermination) { + this.idDetermination = idDetermination; + } + + @GET + @Produces(MediaType.TEXT_XML) + @SuppressWarnings("unchecked") + public Response getXML() { + assert (this.o != null); + return Utils.getXML((Class) this.o.getClass(), this.o); + } + + /** + * Replaces the whole entity by the given entity + * + * As we use the hash code as index, the index changes when the resource is + * updated. This is not in line with REST. The alternative implementation is + * to use the index in the list as resource identification. That changes at + * each modification of the list itself (if elements are deleted / inserted + * before the current entry). When using the hash value, users may + * concurrently edit items and the list may also be updated + * + * @return the new id. + */ + @PUT + @Consumes(MediaType.TEXT_XML) + @Produces(MediaType.TEXT_PLAIN) + public Response setValue(EntityT o) { + this.list.set(this.idx, o); + this.o = o; + return CollectionsHelper.persist(this.res, this.idDetermination, o); + } + + @DELETE + public Response onDelete() { + try { + this.list.remove(this.idx); + } catch (IndexOutOfBoundsException e) { + return Response.status(Status.INTERNAL_SERVER_ERROR).entity("Could not delete entity, even if it should exist").build(); + } + return BackendUtils.persist(this.res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/IIdDetermination.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/IIdDetermination.java new file mode 100644 index 0000000000..e479e70dd3 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/IIdDetermination.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources._support.collections; + +public interface IIdDetermination { + + /** + * @return the id of the given entity + */ + public String getId(EntityT e); +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withid/EntityWithIdCollectionResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withid/EntityWithIdCollectionResource.java new file mode 100644 index 0000000000..f428752f6d --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withid/EntityWithIdCollectionResource.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources._support.collections.withid; + +import java.lang.reflect.Constructor; +import java.util.List; + +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.EntityCollectionResource; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class EntityWithIdCollectionResource, EntityT> extends EntityCollectionResource { + + private static final Logger logger = LoggerFactory.getLogger(EntityWithIdCollectionResource.class); + + + /** + * {@inheritDoc} + */ + public EntityWithIdCollectionResource(Class entityResourceTClazz, Class entityTClazz, List list, IPersistable res) { + super(entityResourceTClazz, entityTClazz, list, res); + } + + /** + * Each CollectionResource has to implement the id getting by itself as + * TOSCA XSD does not provide a general purpose id fetching mechanism + */ + @Override + public abstract String getId(EntityT entity); + + @Override + protected EntityResourceT getEntityResourceInstance(EntityT entity, int idx) { + Constructor constructor; + try { + constructor = this.entityResourceTClazz.getConstructor(IIdDetermination.class, this.entityTClazz, int.class, List.class, this.res.getClass()); + } catch (Exception e) { + try { + constructor = this.entityResourceTClazz.getConstructor(IIdDetermination.class, this.entityTClazz, int.class, List.class, IPersistable.class); + } catch (Exception e2) { + EntityWithIdCollectionResource.logger.debug("Could not get constructor", e); + EntityWithIdCollectionResource.logger.debug("res.getClass() was {}", this.res.getClass()); + throw new IllegalStateException(e2); + } + } + EntityResourceT newInstance; + try { + newInstance = constructor.newInstance(this, entity, idx, this.list, this.res); + } catch (Exception e) { + EntityWithIdCollectionResource.logger.debug("Could not instantiate class", e); + throw new IllegalStateException(e); + } + return newInstance; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withid/EntityWithIdResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withid/EntityWithIdResource.java new file mode 100644 index 0000000000..1ac6775ebe --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withid/EntityWithIdResource.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources._support.collections.withid; + +import java.util.List; + +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.EntityResource; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; + +public class EntityWithIdResource extends EntityResource { + + /** + * {@inheritDoc} + */ + public EntityWithIdResource(IIdDetermination idDetermination, EntityT o, int idx, List list, IPersistable res) { + super(idDetermination, o, idx, list, res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/EntityWithoutIdCollectionResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/EntityWithoutIdCollectionResource.java new file mode 100644 index 0000000000..8255f5d8d3 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/EntityWithoutIdCollectionResource.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources._support.collections.withoutid; + +import java.lang.reflect.Constructor; +import java.util.List; + +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.EntityCollectionResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.NotFoundException; + +/** + * Class managing a list of entities. It is intended to manage subresources, + * where the TOSCA specification did not specify a unique key. Currently, the + * hashCode of the XML String representation is used. If other representation + * should be used, the method {@code getEntityResource} has to be overriden. + * + * @param the resource modeling the entity + * @param the entity type of single items in the list + */ +public abstract class EntityWithoutIdCollectionResource, EntityT> extends EntityCollectionResource { + + private static final Logger logger = LoggerFactory.getLogger(EntityWithoutIdCollectionResource.class); + + + /** + * {@inheritDoc} + */ + public EntityWithoutIdCollectionResource(Class entityResourceTClazz, Class entityTClazz, List list, IPersistable res) { + super(entityResourceTClazz, entityTClazz, list, res); + } + + /** + * Method searching the list for an id with the hashcode instead of + * getId(EntityT) + */ + @Override + @Path("{id}/") + public EntityResourceT getEntityResource(@PathParam("id") String id) { + id = Util.URLdecode(id); + int idInt; + try { + idInt = Integer.parseInt(id); + } catch (java.lang.NumberFormatException e) { + throw new NotFoundException(id + " is not a valid id"); + } + EntityT entity = null; + int idx = -1; + for (EntityT c : this.list) { + idx++; + // speed optimization - instead of using getId() we directly use the hash code + int hash = Utils.getXMLAsString(c).hashCode(); + if (hash == idInt) { + entity = c; + break; + } + } + if (entity == null) { + throw new NotFoundException(); + } else { + return this.getEntityResourceInstance(entity, idx); + } + } + + @Override + public String getId(EntityT entity) { + return IdDeterminationWithHashCode.INSTANCE.getId(entity); + } + + /** + * {@inheritDoc} + */ + @Override + protected EntityResourceT getEntityResourceInstance(EntityT entity, int idx) { + Constructor constructor; + try { + constructor = this.entityResourceTClazz.getConstructor(this.entityTClazz, int.class, List.class, AbstractComponentInstanceResource.class); + } catch (Exception e) { + try { + constructor = this.entityResourceTClazz.getConstructor(this.entityTClazz, int.class, List.class, IPersistable.class); + } catch (NoSuchMethodException | SecurityException e1) { + EntityWithoutIdCollectionResource.logger.debug("Could not get constructor", e); + throw new IllegalStateException(e); + } + } + EntityResourceT newInstance; + try { + newInstance = constructor.newInstance(entity, idx, this.list, this.res); + } catch (Exception e) { + EntityWithoutIdCollectionResource.logger.debug("Could not instantiate class", e); + throw new IllegalStateException(e); + } + return newInstance; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/EntityWithoutIdResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/EntityWithoutIdResource.java new file mode 100644 index 0000000000..0cf2766daa --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/EntityWithoutIdResource.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources._support.collections.withoutid; + +import java.util.List; + +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.EntityResource; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; + +/** + * {@inheritDoc} + */ +public abstract class EntityWithoutIdResource extends EntityResource { + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + public EntityWithoutIdResource(EntityT o, int idx, List list, IPersistable res) { + super((IIdDetermination) IdDeterminationWithHashCode.INSTANCE, o, idx, list, res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/IdDeterminationWithHashCode.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/IdDeterminationWithHashCode.java new file mode 100644 index 0000000000..6b4e247446 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/IdDeterminationWithHashCode.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources._support.collections.withoutid; + +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; + +public class IdDeterminationWithHashCode implements IIdDetermination { + + public static final IdDeterminationWithHashCode INSTANCE = new IdDeterminationWithHashCode(); + + + @Override + public String getId(Object entity) { + // We assume that different Object serializations *always* have different hashCodes + int hash = Utils.getXMLAsString(entity).hashCode(); + return Integer.toString(hash); + } + + /** + * Static wrapper method for functions.tld + */ + public static String getIdStatically(Object entity) { + return IdDeterminationWithHashCode.INSTANCE.getId(entity); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/package-info.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/package-info.java new file mode 100644 index 0000000000..c62b344b6f --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/_support/collections/withoutid/package-info.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +/** + * This package contains abstract resources implementing common functionality to + * support collections of entities, where the data model does not provide a + * unique id + */ +package org.eclipse.winery.repository.resources._support.collections.withoutid; \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/AbstractAdminResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/AbstractAdminResource.java new file mode 100644 index 0000000000..846153e6da --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/AbstractAdminResource.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.admin; + +import javax.ws.rs.DELETE; +import javax.ws.rs.core.Response; + +import org.apache.commons.configuration.Configuration; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.datatypes.ids.admin.AdminId; + +/** + * Instance of one admin resource + */ +public abstract class AbstractAdminResource { + + protected final AdminId id; + protected Configuration configuration; + + + /** + * @param id the id of the element rendered by this resource + */ + public AbstractAdminResource(AdminId id) { + this.id = id; + this.configuration = Repository.INSTANCE.getConfiguration(id); + } + + @DELETE + public Response onDelete() { + return BackendUtils.delete(this.id); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/AdminTopResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/AdminTopResource.java new file mode 100644 index 0000000000..7e4a662642 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/AdminTopResource.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.admin; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.eclipse.winery.repository.resources.admin.types.ConstraintTypesManager; +import org.eclipse.winery.repository.resources.admin.types.PlanLanguagesManager; +import org.eclipse.winery.repository.resources.admin.types.PlanTypesManager; + +import com.sun.jersey.api.view.Viewable; + +public class AdminTopResource { + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML() { + return new Viewable("/jsp/admin/adminindex.jsp", this); + } + + @Path("namespaces/") + public NamespacesResource getNamespacesResource() { + return NamespacesResource.INSTANCE; + } + + @Path("repository/") + public RepositoryAdminResource getRepositoryAdminResource() { + return new RepositoryAdminResource(); + } + + @Path("planlanguages/") + public PlanLanguagesManager getPlanLanguagesResource() { + return PlanLanguagesManager.INSTANCE; + } + + @Path("plantypes/") + public PlanTypesManager getPlanTypesResource() { + return PlanTypesManager.INSTANCE; + } + + @Path("constrainttypes/") + public ConstraintTypesManager getConstraintTypesManager() { + return ConstraintTypesManager.INSTANCE; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/NamespacesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/NamespacesResource.java new file mode 100644 index 0000000000..cc86293911 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/NamespacesResource.java @@ -0,0 +1,253 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.admin; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.TreeSet; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.datatypes.ids.admin.NamespacesId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.sun.jersey.api.view.Viewable; + +/** + * Manages prefixes for the namespaces + */ +public class NamespacesResource extends AbstractAdminResource { + + private static final Logger logger = LoggerFactory.getLogger(NamespacesResource.class); + + public final static NamespacesResource INSTANCE = new NamespacesResource(); + + private Integer nsCount = 0; + + + private NamespacesResource() { + super(new NamespacesId()); + + // globally set prefixes + // if that behavior is not desired, the code has to be moved to "generatePrefix" which checks for existance, ... + this.configuration.setProperty("http://www.w3.org/2001/XMLSchema", "xsd"); + this.configuration.setProperty("http://www.w3.org/XML/1998/namespace", "xmlns"); + this.configuration.setProperty(org.eclipse.winery.common.constants.Namespaces.TOSCA_NAMESPACE, "tosca"); + this.configuration.setProperty(org.eclipse.winery.common.constants.Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "winery"); + } + + private Collection getAllPrefixes() { + Iterator keys = this.configuration.getKeys(); + HashSet res = new HashSet(); + while (keys.hasNext()) { + String key = keys.next(); + String prefix = this.configuration.getString(key); + res.add(prefix); + } + return res; + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Response getHTML() { + Viewable viewable = new Viewable("/jsp/admin/namespaces.jsp", this); + return Response.ok().entity(viewable).build(); + } + + /** + * Sets / overwrites prefix/namespace mapping + * + * In case the prefix is already bound to another namespace, BAD_REQUEST is + * returned. + */ + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public Response addNamespace(@FormParam("namespace") String namespace, @FormParam("nsPrefix") String prefix) { + if (StringUtils.isEmpty(namespace)) { + return Response.status(Status.BAD_REQUEST).entity("namespace must be given.").build(); + } + if (StringUtils.isEmpty(prefix)) { + return Response.status(Status.BAD_REQUEST).entity("prefix must be given.").build(); + } + namespace = Util.URLdecode(namespace); + prefix = Util.URLdecode(prefix); + Collection allPrefixes = this.getAllPrefixes(); + if (allPrefixes.contains(prefix)) { + if (NamespacesResource.getPrefix(namespace).equals(prefix)) { + return Response.notModified().build(); + } else { + // the requested prefix is already bound to a different namespace + return Response.status(Status.BAD_REQUEST).entity("prefix already bound to a different namespace.").build(); + } + } + this.configuration.setProperty(namespace, prefix); + return Response.noContent().build(); + } + + /** + * Deletes given namespace from the repository + * + * @param URI to delete. The namespace is URLencoded. + * @return + */ + @DELETE + @Path("{namespace}") + public Response onDelete(@PathParam("namespace") String URI) { + Response res; + URI = Util.URLdecode(URI); + if (this.configuration.containsKey(URI)) { + this.configuration.clearProperty(URI); + res = Response.noContent().build(); + } else { + res = Response.status(Status.NOT_FOUND).build(); + } + return res; + } + + /** + * SIDEFFECT: URI is added to list of known namespaces if it did not exist + * before + */ + public static String getPrefix(Namespace namespace) { + String ns = namespace.getDecoded(); + return NamespacesResource.getPrefix(ns); + } + + @Path("{namespace}") + @GET + @Produces(MediaType.TEXT_PLAIN) + public String getPrefixForEncodedNamespace(@PathParam("namespace") String URI) { + URI = Util.URLdecode(URI); + return NamespacesResource.getPrefix(URI); + } + + /** + * SIDEFFECT: URI is added to list of known namespaces if it did not exist + * before + */ + public static String getPrefix(String namespace) { + if (namespace == null) { + throw new IllegalArgumentException("Namespace must not be null"); + } + String prefix = NamespacesResource.INSTANCE.configuration.getString(namespace); + if (prefix == null) { + prefix = NamespacesResource.generatePrefix(namespace); + NamespacesResource.INSTANCE.configuration.setProperty(namespace, prefix); + } + return prefix; + } + + private static String generatePrefix(String namespace) { + String prefix = null; + Collection allPrefixes = NamespacesResource.INSTANCE.getAllPrefixes(); + + // TODO: generate prefix using URI (and not "arbitrary" prefix) + do { + prefix = String.format("ns%d", NamespacesResource.INSTANCE.nsCount); + NamespacesResource.INSTANCE.nsCount++; + } while (allPrefixes.contains(prefix)); + return prefix; + } + + /** + * Returns the list of all namespaces registered with his manager. It could + * be incomplete, if entries have been added manually to the repository + * + * @return all namespaces registered with this manager. + */ + private HashSet getRegisteredNamespaces() { + HashSet res = new HashSet(); + Iterator keys = this.configuration.getKeys(); + while (keys.hasNext()) { + String key = keys.next(); + Namespace ns = new Namespace(key, false); + res.add(ns); + } + return res; + } + + /** + * Returns the list of all namespaces registered with his manager and used + * at component instances. + */ + public static Collection getNamespaces() { + HashSet res = NamespacesResource.INSTANCE.getRegisteredNamespaces(); + res.addAll(Repository.INSTANCE.getUsedNamespaces()); + return res; + } + + /** + * This method is required because static methods cannot be accessed by EL + * + * @return see getNamespaces() + */ + public Collection getNamespacesForJSP() { + return NamespacesResource.getNamespaces(); + } + + /** + * Returns the list of all namespaces registered with his manager and used + * at component instances. + * + * @return a JSON list containing the non-encoded URIs of each known + * namespace + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public String getNamespacesAsJSONlist() { + Collection namespaces = NamespacesResource.getNamespaces(); + + // We now have all namespaces + // We need to convert from Namespace to String + + TreeSet stringNamespaces = new TreeSet(); + for (Namespace ns : namespaces) { + stringNamespaces.add(ns.getDecoded()); + } + + String res; + try { + res = Utils.mapper.writeValueAsString(stringNamespaces); + } catch (JsonProcessingException e) { + NamespacesResource.logger.error(e.getMessage(), e); + res = "[]"; + } + return res; + } + + /** + * Checks whether a prefix is registered for a namespace + * + * Used at CSARImporter + */ + public boolean getIsPrefixKnownForNamespace(String namespace) { + return this.configuration.containsKey(namespace); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/RepositoryAdminResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/RepositoryAdminResource.java new file mode 100644 index 0000000000..408704d723 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/RepositoryAdminResource.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.admin; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; + +import org.eclipse.winery.repository.Prefs; +import org.eclipse.winery.repository.backend.IRepositoryAdministration; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.backend.filebased.GitBasedRepository; +import org.restdoc.annotations.RestDoc; +import org.restdoc.annotations.RestDocParam; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; +import com.sun.jersey.core.header.FormDataContentDisposition; +import com.sun.jersey.multipart.FormDataParam; + +public class RepositoryAdminResource { + + private static final Logger logger = LoggerFactory.getLogger(RepositoryAdminResource.class); + + + // @formatter:off + @GET + @Produces(MediaType.TEXT_HTML) // we cannot add MimeTypes.MIMETYPE_ZIP as dumpRepository also produces that mimetype + @RestDoc(methodDescription = "Returns the repository admin page and implements administration utility") + public Response onGet( + @QueryParam(value = "dump") @RestDocParam(description = "If given, a dump of the repository is sent") String dump, + @QueryParam(value = "reset") @RestDocParam(description = "Resets the repository to the last “official” known state") String reset, + @QueryParam(value = "commit") @RestDocParam(description = "Commits the current state to the repository and pushes it upstream") String commit + ) { + // @formatter:on + if (dump != null) { + return this.dumpRepository(); + } else if (reset != null) { + try { + ((GitBasedRepository) Prefs.INSTANCE.getRepository()).cleanAndResetHard(); + } catch (Exception e) { + Response res; + res = Response.serverError().entity(e.getMessage()).build(); + return res; + } + return Response.noContent().build(); + } else if (commit != null) { + try { + ((GitBasedRepository) Prefs.INSTANCE.getRepository()).addCommitPush(); + } catch (Exception e) { + Response res; + res = Response.serverError().entity(e.getMessage()).build(); + return res; + } + return Response.noContent().build(); + } else { + Viewable viewable = new Viewable("/jsp/admin/repository.jsp", this); + return Response.ok().entity(viewable).build(); + } + } + + /** + * Imports the given ZIP + */ + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + public Response importRepositoryDump(@FormDataParam("file") InputStream uploadedInputStream, @FormDataParam("file") FormDataContentDisposition fileDetail) { + ((IRepositoryAdministration) Repository.INSTANCE).doImport(uploadedInputStream); + return Response.noContent().build(); + } + + @DELETE + public void deleteRepositoryData() { + ((IRepositoryAdministration) Repository.INSTANCE).doClear(); + } + + @GET + @Produces(org.eclipse.winery.common.constants.MimeTypes.MIMETYPE_ZIP) + public Response dumpRepository() { + StreamingOutput so = new StreamingOutput() { + + @Override + public void write(OutputStream output) throws IOException, WebApplicationException { + ((IRepositoryAdministration) Repository.INSTANCE).doDump(output); + } + }; + StringBuilder sb = new StringBuilder(); + sb.append("attachment;filename=\"repository.zip\""); + return Response.ok().header("Content-Disposition", sb.toString()).type(org.eclipse.winery.common.constants.MimeTypes.MIMETYPE_ZIP).entity(so).build(); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/AbstractTypesManager.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/AbstractTypesManager.java new file mode 100644 index 0000000000..bf3c0247f3 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/AbstractTypesManager.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.admin.types; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.UriInfo; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.datatypes.TypeWithShortName; +import org.eclipse.winery.repository.datatypes.ids.admin.TypesId; +import org.eclipse.winery.repository.datatypes.select2.Select2DataItem; +import org.eclipse.winery.repository.resources.admin.AbstractAdminResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; + +/** + * Handles longname/shortname by using properties + * + * FIXME: This class does NOT support dynamic reloading of the underlying + * Configuration instance + * + */ +public abstract class AbstractTypesManager extends AbstractAdminResource { + + @Context + private UriInfo uriInfo; + + protected static final Logger logger = LoggerFactory.getLogger(AbstractTypesManager.class); + + // hashes from a long type string to the type object holding complete type data + private final HashMap hashTypeStringToType; + + + public AbstractTypesManager(TypesId id) { + super(id); + // now, this.configuration is filled with stored data + + // copy over information from configuration to internal data structure + this.hashTypeStringToType = new HashMap(); + Iterator keys = this.configuration.getKeys(); + while (keys.hasNext()) { + String key = keys.next(); + String value = this.configuration.getString(key); + TypeWithShortName typeInfo = new TypeWithShortName(key, value); + this.hashTypeStringToType.put(key, typeInfo); + } + } + + protected void addData(String longName, String shortName) { + TypeWithShortName t = new TypeWithShortName(longName, shortName); + this.addData(t); + } + + /** + * Adds data to the internal data structure WITHOUT persisting it + * + * More or less a quick hack to enable adding default types without + * persisting them in the storage + * + * @param t the type to add + */ + private void addData(TypeWithShortName t) { + this.hashTypeStringToType.put(t.getType(), t); + } + + public synchronized void addTypeWithShortName(TypeWithShortName type) { + this.addData(type); + this.configuration.setProperty(type.getType(), type.getShortName()); + } + + /** + * Removes a type. Will not remove a type added by "addData" + */ + @DELETE + @Path("{type}") + public Response removeTypeWithResponse(@PathParam("type") String type) { + type = Util.URLdecode(type); + if (this.configuration.containsKey(type)) { + this.hashTypeStringToType.remove(type); + this.configuration.clearProperty(type); + return Response.noContent().build(); + } else if (this.hashTypeStringToType.containsKey(type)) { + // predefined types may not be deleted + // this branch is hit at types added via addData (e.g., predefined plantypes) + return Response.status(Status.FORBIDDEN).build(); + } else { + return Response.status(Status.NOT_FOUND).build(); + } + } + + /** + * Returns a sorted list of all available types + */ + public Collection getTypes() { + Collection res = new TreeSet(this.hashTypeStringToType.values()); + return res; + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public Object getTypesAsJSONArrayList(@QueryParam("select2") String select2) { + if (select2 == null) { + return this.getTypes(); + } else { + // select2 mode + SortedSet res = new TreeSet<>(); + for (TypeWithShortName t : this.getTypes()) { + Select2DataItem item = new Select2DataItem(t.getType(), t.getShortName()); + res.add(item); + } + return res; + } + } + + /** + * SIDEEFFECT: If there currently isn't any short type name, it is + * created + */ + public TypeWithShortName getTypeWithShortName(String typeString) { + TypeWithShortName t = this.hashTypeStringToType.get(typeString); + if (t == null) { + String shortName = this.getShortName(typeString); + t = new TypeWithShortName(typeString, shortName); + this.addTypeWithShortName(t); + } + return t; + } + + /** + * SIDEEFFECT: If there currently isn't any short type name, it is + * created + */ + public String getShortName(String typeString) { + TypeWithShortName type = this.hashTypeStringToType.get(typeString); + String res; + if (type == null) { + // happens if artifact type is not registered in artifacttypes.list + // (DATAFILENAME) + res = typeString; + } else { + res = type.getShortName(); + } + return res; + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML(@Context UriInfo uriInfo) { + this.uriInfo = uriInfo; + return new Viewable("/jsp/admin/types/types.jsp", this); + } + + @POST + public Response updateTypeMapping(@FormParam("shortname") String shortName, @FormParam("type") String type) { + if (StringUtils.isEmpty(shortName)) { + return Response.status(Status.BAD_REQUEST).entity("shortName has to be given").build(); + } + if (StringUtils.isEmpty(type)) { + return Response.status(Status.BAD_REQUEST).entity("type has to be given").build(); + } + shortName = Util.URLdecode(shortName); + type = Util.URLdecode(type); + TypeWithShortName tws = new TypeWithShortName(type, shortName); + this.addTypeWithShortName(tws); + return Response.noContent().build(); + } + + /** + * Required by types.jsp + */ + public String getURL() { + return this.uriInfo.getAbsolutePath().toString(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/ConstraintTypesManager.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/ConstraintTypesManager.java new file mode 100644 index 0000000000..d8a9c0eeb5 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/ConstraintTypesManager.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.admin.types; + +import org.eclipse.winery.repository.datatypes.ids.admin.ConstraintTypesId; + +public class ConstraintTypesManager extends AbstractTypesManager { + + public final static ConstraintTypesManager INSTANCE = new ConstraintTypesManager(); + + + private ConstraintTypesManager() { + super(new ConstraintTypesId()); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/PlanLanguagesManager.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/PlanLanguagesManager.java new file mode 100644 index 0000000000..cedafb776a --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/PlanLanguagesManager.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.admin.types; + +import org.eclipse.winery.repository.datatypes.ids.admin.PlanLanguagesId; + +public class PlanLanguagesManager extends AbstractTypesManager { + + public final static PlanLanguagesManager INSTANCE = new PlanLanguagesManager(); + + + private PlanLanguagesManager() { + super(new PlanLanguagesId()); + // add data without rendering in the plan languages file + this.addData(org.eclipse.winery.common.constants.Namespaces.URI_BPEL20_EXECUTABLE, "BPEL 2.0 (executable)"); + this.addData(org.eclipse.winery.common.constants.Namespaces.URI_BPMN20_MODEL, "BPMN 2.0"); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/PlanTypesManager.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/PlanTypesManager.java new file mode 100644 index 0000000000..de6e7ba0f0 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/admin/types/PlanTypesManager.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.admin.types; + +import org.eclipse.winery.repository.datatypes.ids.admin.PlanTypesId; + +public class PlanTypesManager extends AbstractTypesManager { + + public final static PlanTypesManager INSTANCE = new PlanTypesManager(); + + + private PlanTypesManager() { + super(new PlanTypesId()); + // add data without rendering in the plan types file + this.addData(org.eclipse.winery.repository.Constants.TOSCA_PLANTYPE_BUILD_PLAN, "Build Plan"); + this.addData(org.eclipse.winery.repository.Constants.TOSCA_PLANTYPE_TERMINATION_PLAN, "Termination Plan"); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/DeploymentArtifactResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/DeploymentArtifactResource.java new file mode 100644 index 0000000000..cadf47337c --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/DeploymentArtifactResource.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.artifacts; + +import java.util.List; + +import org.eclipse.winery.model.tosca.TDeploymentArtifact; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.definitions.ArtifactTypeId; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.INodeTemplateResourceOrNodeTypeImplementationResource; + +public class DeploymentArtifactResource extends GenericArtifactResource { + + private final TDeploymentArtifact a; + + + /** + * Converts the given artifactId to an DeploymentArtifact. + * + * SIDE EFFECT Adds it to the DeploymentArtifacts list if it does + * not yet exist. + */ + private static TDeploymentArtifact getDeploymentArtifact(String artifactId, List deploymentArtifacts) { + for (TDeploymentArtifact ia : deploymentArtifacts) { + if (ia.getName().equals(artifactId)) { + return ia; + } + } + // DA does not exist in list + TDeploymentArtifact ia = new TDeploymentArtifact(); + ia.setName(artifactId); + deploymentArtifacts.add(ia); + return ia; + } + + public DeploymentArtifactResource(String artifactId, List deploymentArtifacts, INodeTemplateResourceOrNodeTypeImplementationResource res) { + this(DeploymentArtifactResource.getDeploymentArtifact(artifactId, deploymentArtifacts), deploymentArtifacts, res); + } + + public DeploymentArtifactResource(TDeploymentArtifact a, int idx, List deploymentArtifacts, INodeTemplateResourceOrNodeTypeImplementationResource res) { + super(a, idx, deploymentArtifacts, res); + this.a = a; + } + + public DeploymentArtifactResource(TDeploymentArtifact deploymentArtifact, List deploymentArtifacts, INodeTemplateResourceOrNodeTypeImplementationResource res) { + this(deploymentArtifact, deploymentArtifacts.indexOf(deploymentArtifact), deploymentArtifacts, res); + } + + public TDeploymentArtifact getDeploymentArtifact() { + return this.a; + } + + @Override + public void setArtifactType(ArtifactTypeId artifactTypeId) { + this.getDeploymentArtifact().setArtifactType(artifactTypeId.getQName()); + this.persist(); + } + + @Override + public void setArtifactTemplate(ArtifactTemplateId artifactTemplateId) { + this.getDeploymentArtifact().setArtifactRef(artifactTemplateId.getQName()); + this.persist(); + } + + private void persist() { + BackendUtils.persist(this.res); + } + + @Override + public TDeploymentArtifact getA() { + return this.a; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/DeploymentArtifactsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/DeploymentArtifactsResource.java new file mode 100644 index 0000000000..203927e4ab --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/DeploymentArtifactsResource.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.artifacts; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +import org.eclipse.winery.model.tosca.TDeploymentArtifact; +import org.eclipse.winery.model.tosca.TDeploymentArtifacts; +import org.eclipse.winery.model.tosca.TNodeTemplate; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.resources.INodeTemplateResourceOrNodeTypeImplementationResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DeploymentArtifactsResource extends GenericArtifactsResource { + + private static final Logger logger = LoggerFactory.getLogger(DeploymentArtifactsResource.class); + + private List deploymentArtifacts; + + + public DeploymentArtifactsResource(List deploymentArtifact, INodeTemplateResourceOrNodeTypeImplementationResource res) { + super(DeploymentArtifactResource.class, TDeploymentArtifact.class, deploymentArtifact, res); + this.deploymentArtifacts = deploymentArtifact; + } + + /** + * Determines the list of DAs belonging to the given node template. + * + * If no DAs are existing, an empty list is created in the model for the + * node template + */ + private static List getDeploymentArtifacts(TNodeTemplate nodeTemplate) { + TDeploymentArtifacts deploymentArtifacts = nodeTemplate.getDeploymentArtifacts(); + final List res; + if (deploymentArtifacts == null) { + deploymentArtifacts = new TDeploymentArtifacts(); + nodeTemplate.setDeploymentArtifacts(deploymentArtifacts); + } + res = deploymentArtifacts.getDeploymentArtifact(); + return res; + } + + public DeploymentArtifactsResource(TNodeTemplate nodeTemplate, INodeTemplateResourceOrNodeTypeImplementationResource res) { + this(DeploymentArtifactsResource.getDeploymentArtifacts(nodeTemplate), res); + } + + /** + * @param artifactId - encoded deployment artifact Id + */ + @Override + @Path("{artifactId}/") + public DeploymentArtifactResource getEntityResource(@PathParam("artifactId") String artifactId) { + artifactId = Util.URLdecode(artifactId); + return this.getArtifactResourceWithDecodedId(artifactId); + } + + @Override + protected DeploymentArtifactResource getArtifactResourceWithDecodedId(String artifactId) { + return new DeploymentArtifactResource(artifactId, this.deploymentArtifacts, (INodeTemplateResourceOrNodeTypeImplementationResource) this.res); + } + + @Override + public Collection getAllArtifactResources() { + Collection res = new ArrayList(this.deploymentArtifacts.size()); + for (TDeploymentArtifact da : this.deploymentArtifacts) { + DeploymentArtifactResource r = new DeploymentArtifactResource(da, this.deploymentArtifacts, (INodeTemplateResourceOrNodeTypeImplementationResource) this.res); + res.add(r); + } + return res; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/GenericArtifactResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/GenericArtifactResource.java new file mode 100644 index 0000000000..cec2ec99e2 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/GenericArtifactResource.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.artifacts; + +import java.util.List; + +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.definitions.ArtifactTypeId; +import org.eclipse.winery.repository.resources.INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdResource; + +/** + * Currently no common things for deployment artifacts and implementation + * artifacts as the data model also has no common ancestor (besides + * TExensibleElement) + */ +public abstract class GenericArtifactResource extends EntityWithoutIdResource { + + public GenericArtifactResource(ArtifactT o, int idx, List list, INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource res) { + super(o, idx, list, GenericArtifactsResource.getAbstractComponentInstanceResource(res)); + } + + public abstract void setArtifactType(ArtifactTypeId artifactTypeId); + + public abstract void setArtifactTemplate(ArtifactTemplateId artifactTemplateId); + + /** + * required by artifacts.jsp + */ + public abstract ArtifactT getA(); + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/GenericArtifactsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/GenericArtifactsResource.java new file mode 100644 index 0000000000..cf6e1b8b57 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/GenericArtifactsResource.java @@ -0,0 +1,579 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.artifacts; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.UriInfo; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.definitions.ArtifactTypeId; +import org.eclipse.winery.common.ids.definitions.NodeTypeId; +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.generators.ia.Generator; +import org.eclipse.winery.model.tosca.TEntityTemplate.Properties; +import org.eclipse.winery.model.tosca.TInterface; +import org.eclipse.winery.model.tosca.TNodeType; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.backend.ResourceCreationResult; +import org.eclipse.winery.repository.backend.filebased.FileUtils; +import org.eclipse.winery.repository.datatypes.ids.elements.ArtifactTemplateDirectoryId; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources.AbstractComponentsResource; +import org.eclipse.winery.repository.resources.IHasTypeReference; +import org.eclipse.winery.repository.resources.INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdCollectionResource; +import org.eclipse.winery.repository.resources.entitytemplates.PropertiesResource; +import org.eclipse.winery.repository.resources.entitytemplates.artifacttemplates.ArtifactTemplateResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.EntityTypeImplementationResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.nodetypeimplementations.NodeTypeImplementationResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.relationshiptypeimplementations.RelationshipTypeImplementationResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; +import org.eclipse.winery.repository.resources.servicetemplates.topologytemplates.NodeTemplateResource; +import org.restdoc.annotations.RestDoc; +import org.restdoc.annotations.RestDocParam; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Text; +import org.xml.sax.InputSource; + +import com.sun.jersey.api.view.Viewable; + +/** + * Resource handling both deployment and implementation artifacts + * + */ +public abstract class GenericArtifactsResource, ArtifactT> extends EntityWithoutIdCollectionResource { + + private static final Logger logger = LoggerFactory.getLogger(GenericArtifactsResource.class); + + protected final INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource res; + + + public GenericArtifactsResource(Class entityResourceTClazz, Class entityTClazz, List list, INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource res) { + super(entityResourceTClazz, entityTClazz, list, GenericArtifactsResource.getAbstractComponentInstanceResource(res)); + this.res = res; + } + + protected abstract ArtifactResource getArtifactResourceWithDecodedId(String artifactId); + + // @formatter:off + + /** + * @return TImplementationArtifact | TDeploymentArtifact (XML) | URL of generated IA zip (in case of autoGenerateIA) + */ + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_XML) + @RestDoc(methodDescription = "Creates a new implementation/deployment artifact. " + + "If an implementation artifact with the same name already exists, it is overridden.") + public Response onPost( + @FormParam("artifactName") + @RestDocParam(description = "This is the name of the implementation/deployment artifact. " + + "Is alsoused as prefix of the name of the corresponding artifact template if no specific template is provided. " + + "In contrast to CS01, we require a artifactName also for the implementationArtifact to be able to properly referencing it.") + String artifactNameStr, + + @FormParam("artifactTemplate") + @RestDocParam(description = "QName of the artifact Template - used by Winery Backend instead of artifactTemplateName + artifactTemplateNS") + String artifactTemplate, + + @FormParam("artifactTemplateName") + @RestDocParam(description = "if provided and autoCreateArtifactTemplate, a template of this id localname and artifactTemplateNS generated. " + + "Winery always sends this string if auto creation is desired.") + String artifactTemplateName, + + @FormParam("artifactTemplateNS") + String artifactTemplateNS, + + @FormParam("autoCreateArtifactTemplate") + @RestDocParam(description = "if empty, no, or false, no artifact template is created. " + + "An artifact type has to be given in that case. " + + "Furthermore, an artifact template name + artifact template namespace has to be provided. " + + "Otherwise, the artifactNameStr is used as name for the artifact and a new artifact template is created having {@code Template} as name") + String autoCreateArtifactTemplate, + + @FormParam("artifactType") + @RestDocParam(description = "QName of the type, format: {namespace}localname. " + + "Optional if artifactTemplateName + artifactTempalteNS is provided") + String artifactTypeStr, + + @FormParam("artifactSpecificContent") + @RestDocParam(description = "XML snippet that should be put inside the artifact XML in the TOSCA serialization. " + + "This feature will be removed soon. " + + "TODO: This only works if there is a single child element expected and not several elements. " + + "Future versions of the Winery will support arbitrary content there.") + String artifactSpecificContent, + + @FormParam("interfaceName") + String interfaceNameStr, + + @FormParam("operationName") + String operationNameStr, + + @FormParam("autoGenerateIA") + @RestDocParam(description = "If not empty, the IA generator will be called") + String autoGenerateIA, + + @FormParam("javapackage") + @RestDocParam(description = "The Java package to use for IA generation") + String javapackage, + + @Context UriInfo uriInfo + ){ + // we assume that the parent ComponentInstance container exists + + // @formatter:on + + if (StringUtils.isEmpty(artifactNameStr)) { + return Response.status(Status.BAD_REQUEST).entity("Empty artifactName").build(); + } + if (StringUtils.isEmpty(artifactTypeStr)) { + if (StringUtils.isEmpty(artifactTemplateName) || StringUtils.isEmpty(artifactTemplateNS)) { + if (StringUtils.isEmpty(artifactTemplate)) { + return Response.status(Status.BAD_REQUEST).entity("No artifact type given and no template given. Cannot guess artifact type").build(); + } + } + } + + if (!StringUtils.isEmpty(autoGenerateIA)) { + if (StringUtils.isEmpty(javapackage)) { + return Response.status(Status.BAD_REQUEST).entity("no java package name supplied for IA auto generation.").build(); + } + if (StringUtils.isEmpty(interfaceNameStr)) { + return Response.status(Status.BAD_REQUEST).entity("no interface name supplied for IA auto generation.").build(); + } + } + + // convert second calling form to first calling form + if (!StringUtils.isEmpty(artifactTemplate)) { + QName qname = QName.valueOf(artifactTemplate); + artifactTemplateName = qname.getLocalPart(); + artifactTemplateNS = qname.getNamespaceURI(); + } + + Document doc = null; + + // check artifact specific content for validity + // if invalid, abort and do not create anything + if (!StringUtils.isEmpty(artifactSpecificContent)) { + try { + DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + InputSource is = new InputSource(); + StringReader sr = new StringReader(artifactSpecificContent); + is.setCharacterStream(sr); + doc = db.parse(is); + } catch (Exception e) { + // FIXME: currently we allow a single element only. However, the content should be internally wrapped by an (arbitrary) XML element as the content will be nested in the artifact element, too + GenericArtifactsResource.logger.debug("Invalid content", e); + return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + // determine artifactTemplate and artifactType + + ArtifactTypeId artifactTypeId; + ArtifactTemplateId artifactTemplateId = null; + ArtifactTemplateResource artifactTemplateResource = null; + + boolean doAutoCreateArtifactTemplate = !(StringUtils.isEmpty(autoCreateArtifactTemplate) || autoCreateArtifactTemplate.equalsIgnoreCase("no") || autoCreateArtifactTemplate.equalsIgnoreCase("false")); + if (!doAutoCreateArtifactTemplate) { + // no auto creation + if (!StringUtils.isEmpty(artifactTemplateName) && !StringUtils.isEmpty(artifactTemplateNS)) { + QName artifactTemplateQName = new QName(artifactTemplateNS, artifactTemplateName); + artifactTemplateId = BackendUtils.getTOSCAcomponentId(ArtifactTemplateId.class, artifactTemplateQName); + } + if (StringUtils.isEmpty(artifactTypeStr)) { + // derive the type from the artifact template + if (artifactTemplateId == null) { + return Response.status(Status.NOT_ACCEPTABLE).entity("No artifactTemplate and no artifactType provided. Deriving the artifactType is not possible.").build(); + } + artifactTemplateResource = new ArtifactTemplateResource(artifactTemplateId); + artifactTypeId = BackendUtils.getTOSCAcomponentId(ArtifactTypeId.class, artifactTemplateResource.getType()); + } else { + // artifactTypeStr is directly given, use that + artifactTypeId = BackendUtils.getTOSCAcomponentId(ArtifactTypeId.class, artifactTypeStr); + } + } else { + // do the artifact template auto creation magic + + if (StringUtils.isEmpty(artifactTypeStr)) { + return Response.status(Status.BAD_REQUEST).entity("Artifact template auto creation requested, but no artifact type supplied.").build(); + } + + // we assume that the type points to a valid artifact type + artifactTypeId = BackendUtils.getTOSCAcomponentId(ArtifactTypeId.class, artifactTypeStr); + + if (StringUtils.isEmpty(artifactTemplateName) || StringUtils.isEmpty(artifactTemplateNS)) { + // no explicit name provided + // we use the artifactNameStr as prefix for the + // artifact template name + + // we create a new artifact template in the namespace of the parent + // element + Namespace namespace = this.res.getNamespace(); + + artifactTemplateId = new ArtifactTemplateId(namespace, new XMLId(artifactNameStr + "artifactTemplate", false)); + } else { + QName artifactTemplateQName = new QName(artifactTemplateNS, artifactTemplateName); + artifactTemplateId = new ArtifactTemplateId(artifactTemplateQName); + } + ResourceCreationResult creationResult = BackendUtils.create(artifactTemplateId); + if (!creationResult.isSuccess()) { + // something went wrong. skip + return creationResult.getResponse(); + } + + // associate the type to the created artifact template + artifactTemplateResource = new ArtifactTemplateResource(artifactTemplateId); + // set the type. The resource is automatically persisted inside + artifactTemplateResource.setType(artifactTypeStr); + } + + // variable artifactTypeId is set + // variable artifactTemplateId is not null if artifactTemplate has been generated + + // we have to generate the DA/IA resource now + // Doing it here instead of doing it at the subclasses is dirty on the + // one hand, but quicker to implement on the other hand + + // Create the artifact itself + + ArtifactResource artifactResource = this.getArtifactResourceWithDecodedId(artifactNameStr); + + // Winery internal id is the name of the artifact: + // store the name + if (this instanceof ImplementationArtifactsResource) { + ((ImplementationArtifactResource) artifactResource).getImplementationArtifact().setName(artifactNameStr); + } else { + ((DeploymentArtifactResource) artifactResource).getDeploymentArtifact().setName(artifactNameStr); + } + + if (this instanceof ImplementationArtifactsResource) { + // store interface name + if (!StringUtils.isEmpty(interfaceNameStr)) { + ((ImplementationArtifactResource) artifactResource).getImplementationArtifact().setInterfaceName(interfaceNameStr); + } + // store operation name + if (!StringUtils.isEmpty(operationNameStr)) { + ((ImplementationArtifactResource) artifactResource).getImplementationArtifact().setOperationName(operationNameStr); + } + } + + // store artifact type, artifact template, and artifact specific content information + + // store artifact type + assert (artifactTypeId != null); + artifactResource.setArtifactType(artifactTypeId); + + // store artifact template + if (artifactTemplateId != null) { + artifactResource.setArtifactTemplate(artifactTemplateId); + } + + if (doc != null) { + // the content has been checked for validity at the beginning of the method. + // If this point in the code is reached, the XML has been parsed into doc + + List any; + if (this instanceof ImplementationArtifactsResource) { + any = ((ImplementationArtifactResource) artifactResource).getImplementationArtifact().getAny(); + } else { + any = ((DeploymentArtifactResource) artifactResource).getDeploymentArtifact().getAny(); + } + // just copy over the dom node. Hopefully, that works... + any.add(doc.getDocumentElement()); + } + + if (StringUtils.isEmpty(autoGenerateIA)) { + // no IA generation + // we include a JSON array for the data table + + Object implOrDeplArtifact; + if (this instanceof ImplementationArtifactsResource) { + implOrDeplArtifact = ((ImplementationArtifactResource) artifactResource).getImplementationArtifact(); + } else { + implOrDeplArtifact = ((DeploymentArtifactResource) artifactResource).getDeploymentArtifact(); + } + String implOrDeplArtifactXML = Utils.getXMLAsString(implOrDeplArtifact); + + return Response.created(Utils.createURI(Util.URLencode(artifactNameStr))).entity(implOrDeplArtifactXML).build(); + } else { + // after everything was created, we fire up the artifact generation + return this.generateImplementationArtifact(interfaceNameStr, javapackage, uriInfo, artifactTemplateId, artifactTemplateResource); + } + } + + /** + * Generates a unique and valid name to be used for the generated maven + * project name, java project name, class name, port type name. + */ + private String generateName(NodeTypeId nodeTypeId, String interfaceName) { + String name = Util.namespaceToJavaPackage(nodeTypeId.getNamespace().getDecoded()); + name += Util.FORBIDDEN_CHARACTER_REPLACEMENT; + + // Winery already ensures that this is a valid NCName + // getName() returns the id of the nodeType: A nodeType carries the "id" attribute only (and no name attribute) + name += nodeTypeId.getXmlId().getDecoded(); + + // Two separators to distinguish node type and interface part + name += Util.FORBIDDEN_CHARACTER_REPLACEMENT; + name += Util.FORBIDDEN_CHARACTER_REPLACEMENT; + name += Util.namespaceToJavaPackage(interfaceName); + + // In addition we must replace '.', because Java class names must not + // contain dots, but for Winery they are fine. + return name.replace(".", Util.FORBIDDEN_CHARACTER_REPLACEMENT); + } + + /** + * Generates the implementation artifact using the implementation artifact + * generator. Also sets the proeprties according to the requirements of + * OpenTOSCA. + * + * @param interfaceNameStr + * @param javapackage + * @param uriInfo + * @param artifactTemplateId + * @param artifactTemplateResource the resource associated with the + * artifactTempalteId. If null, the object is created in this + * method + * + * @return {@inheritDoc} + */ + private Response generateImplementationArtifact(String interfaceNameStr, String javapackage, UriInfo uriInfo, ArtifactTemplateId artifactTemplateId, ArtifactTemplateResource artifactTemplateResource) { + TInterface iface; + + assert (this instanceof ImplementationArtifactsResource); + IHasTypeReference typeRes = (EntityTypeImplementationResource) this.res; + QName type = typeRes.getType(); + TOSCAComponentId typeId; + TNodeType nodeType = null; + if (typeRes instanceof NodeTypeImplementationResource) { + // TODO: refactor: This is more a model/repo utilities thing than something which should happen here... + + typeId = new NodeTypeId(type); + NodeTypeResource ntRes = (NodeTypeResource) AbstractComponentsResource.getComponentInstaceResource(typeId); + + // required for IA Generation + nodeType = ntRes.getNodeType(); + + List interfaces = nodeType.getInterfaces().getInterface(); + Iterator it = interfaces.iterator(); + do { + iface = it.next(); + if (iface.getName().equals(interfaceNameStr)) { + break; + } + } while (it.hasNext()); + // iface now contains the right interface + } else { + assert (typeRes instanceof RelationshipTypeImplementationResource); + return Response.serverError().entity("IA creation for relation ship type implementations not yet possible").build(); + } + + Path workingDir; + try { + workingDir = Files.createTempDirectory("winery"); + } catch (IOException e2) { + GenericArtifactsResource.logger.debug("Could not create temporary directory", e2); + return Response.serverError().entity("Could not create temporary directory").build(); + } + + URI artifactTemplateFilesUri = uriInfo.getBaseUri().resolve(Utils.getAbsoluteURL(artifactTemplateId)).resolve("files/"); + URL artifactTemplateFilesUrl; + try { + artifactTemplateFilesUrl = artifactTemplateFilesUri.toURL(); + } catch (MalformedURLException e2) { + GenericArtifactsResource.logger.debug("Could not convert URI to URL", e2); + return Response.serverError().entity("Could not convert URI to URL").build(); + } + + String name = this.generateName((NodeTypeId) typeId, interfaceNameStr); + Generator gen = new Generator(iface, javapackage, artifactTemplateFilesUrl, name, workingDir.toFile()); + File zipFile = gen.generateProject(); + if (zipFile == null) { + return Response.serverError().entity("IA generator failed").build(); + } + + // store it + // TODO: refactor: this is more a RepositoryUtils thing than a special thing here; see also importFile at CSARImporter + + ArtifactTemplateDirectoryId fileDir = new ArtifactTemplateDirectoryId(artifactTemplateId); + RepositoryFileReference fref = new RepositoryFileReference(fileDir, zipFile.getName().toString()); + try (InputStream is = Files.newInputStream(zipFile.toPath()); + BufferedInputStream bis = new BufferedInputStream(is)) { + String mediaType = Utils.getMimeType(bis, zipFile.getName()); + // TODO: do the catch thing as in CSARImporter + + Repository.INSTANCE.putContentToFile(fref, bis, MediaType.valueOf(mediaType)); + } catch (IOException e1) { + throw new IllegalStateException("Could not import generated files", e1); + } + + // cleanup dir + try { + FileUtils.forceDelete(workingDir); + } catch (IOException e) { + GenericArtifactsResource.logger.debug("Could not delete working directory", e); + } + + // store the properties in the artifact template + if (artifactTemplateResource == null) { + artifactTemplateResource = (ArtifactTemplateResource) AbstractComponentsResource.getComponentInstaceResource(artifactTemplateId); + } + this.storeProperties(artifactTemplateResource, typeId, name); + + URI url = uriInfo.getBaseUri().resolve(Utils.getAbsoluteURL(fref)); + return Response.created(url).build(); + } + + + private final String NS_OPENTOSCA_WAR_TYPE = "http://www.uni-stuttgart.de/opentosca"; + + + private void storeProperties(ArtifactTemplateResource artifactTemplateResource, TOSCAComponentId typeId, String name) { + // We generate the properties by hand instead of using JAX-B as using JAX-B causes issues at org.eclipse.winery.common.ModelUtilities.getPropertiesKV(TEntityTemplate): + // getAny() does not always return "w3c.dom.element" anymore + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + try { + builder = dbf.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + GenericArtifactsResource.logger.error(e.getMessage(), e); + return; + } + Document doc = builder.newDocument(); + Element root = doc.createElementNS(this.NS_OPENTOSCA_WAR_TYPE, "WSProperties"); + doc.appendChild(root); + + Element element = doc.createElementNS(this.NS_OPENTOSCA_WAR_TYPE, "ServiceEndpoint"); + Text text = doc.createTextNode("/services/" + name + "Port"); + element.appendChild(text); + root.appendChild(element); + + element = doc.createElementNS(this.NS_OPENTOSCA_WAR_TYPE, "PortType"); + text = doc.createTextNode("{" + typeId.getNamespace().getDecoded() + "}" + name); + element.appendChild(text); + root.appendChild(element); + + element = doc.createElementNS(this.NS_OPENTOSCA_WAR_TYPE, "InvocationType"); + text = doc.createTextNode("SOAP/HTTP"); + element.appendChild(text); + root.appendChild(element); + + Properties properties = new Properties(); + properties.setAny(root); + PropertiesResource propertiesResource = artifactTemplateResource.getPropertiesResource(); + propertiesResource.setProperties(properties); + } + + @Override + public Viewable getHTML() { + return new Viewable("/jsp/artifacts/artifacts.jsp", this); + } + + /** + * Required for artifacts.jsp + * + * @return list of known artifact types. + */ + public List getAllArtifactTypes() { + SortedSet allArtifactTypes = Repository.INSTANCE.getAllTOSCAComponentIds(ArtifactTypeId.class); + List res = new ArrayList(allArtifactTypes.size()); + for (ArtifactTypeId id : allArtifactTypes) { + res.add(id.getQName()); + } + return res; + } + + /** + * Required for artifacts.jsp + * + * @return list of all contained artifacts. + */ + public abstract Collection getAllArtifactResources(); + + /** + * Required by artifact.jsp to decide whether to display + * "Deployment Artifact" or "Implementation Artifact" + */ + public boolean getIsDeploymentArtifacts() { + boolean res = (this instanceof DeploymentArtifactsResource); + return res; + } + + /** + * required by artifacts.jsp + */ + public String getNamespace() { + return this.res.getNamespace().getDecoded(); + } + + /** + * For saving resources, an AbstractComponentInstanceResource is required. + * DAs may be attached to a node template, which is not an + * AbstractComponentInstanceResource, but its grandparent resource + * ServiceTemplate is + * + * @param res the resource to determine the the + * AbstractComponentInstanceResource for + * @return the AbstractComponentInstanceResource where the given res is + * contained in + */ + public static AbstractComponentInstanceResource getAbstractComponentInstanceResource(INodeTemplateResourceOrNodeTypeImplementationResourceOrRelationshipTypeImplementationResource res) { + final AbstractComponentInstanceResource r; + if (res instanceof NodeTemplateResource) { + r = ((NodeTemplateResource) res).getServiceTemplateResource(); + } else { + // quick hack: the resource has to be an abstract component instance + r = (AbstractComponentInstanceResource) res; + } + return r; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/ImplementationArtifactResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/ImplementationArtifactResource.java new file mode 100644 index 0000000000..f68f523e72 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/ImplementationArtifactResource.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.artifacts; + +import java.util.List; + +import org.eclipse.winery.model.tosca.TImplementationArtifacts.ImplementationArtifact; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.definitions.ArtifactTypeId; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.INodeTypeImplementationResourceOrRelationshipTypeImplementationResource; + +public class ImplementationArtifactResource extends GenericArtifactResource { + + private ImplementationArtifact a; + + + /** + * Converts the given artifactId to an ImplementArtifact. + * + * SIDE EFFECT Adds it to the implementationArtifacts list if it + * does not yet exist. + */ + private static ImplementationArtifact getImplementationArtifact(String artifactId, List implementationArtifacts) { + if (artifactId == null) { + throw new IllegalArgumentException("artifactId must not be null"); + } + if (implementationArtifacts == null) { + throw new IllegalArgumentException("implementationArtifacts must not be null"); + } + for (ImplementationArtifact ia : implementationArtifacts) { + // ia.getName() might be null as TOSCA COS01 does not forsee a name on the implementation artifact + // Therefore, we begin the test with "artifactId" + if (artifactId.equals(ia.getName())) { + return ia; + } + } + // IA does not exist in list + ImplementationArtifact ia = new ImplementationArtifact(); + ia.setName(artifactId); + implementationArtifacts.add(ia); + return ia; + } + + public ImplementationArtifactResource(String artifactId, List implementationArtifacts, INodeTypeImplementationResourceOrRelationshipTypeImplementationResource res) { + this(ImplementationArtifactResource.getImplementationArtifact(artifactId, implementationArtifacts), implementationArtifacts, res); + } + + public ImplementationArtifactResource(ImplementationArtifact a, int idx, List implementationArtifacts, INodeTypeImplementationResourceOrRelationshipTypeImplementationResource res) { + super(a, idx, implementationArtifacts, res); + this.a = a; + } + + public ImplementationArtifactResource(ImplementationArtifact a, List implementationArtifacts, INodeTypeImplementationResourceOrRelationshipTypeImplementationResource res) { + this(a, implementationArtifacts.indexOf(a), implementationArtifacts, res); + } + + public ImplementationArtifact getImplementationArtifact() { + return this.a; + } + + @Override + public void setArtifactType(ArtifactTypeId artifactTypeId) { + this.getImplementationArtifact().setArtifactType(artifactTypeId.getQName()); + BackendUtils.persist(this.res); + } + + @Override + public void setArtifactTemplate(ArtifactTemplateId artifactTemplateId) { + this.getImplementationArtifact().setArtifactRef(artifactTemplateId.getQName()); + BackendUtils.persist(this.res); + } + + @Override + public ImplementationArtifact getA() { + return this.a; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/ImplementationArtifactsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/ImplementationArtifactsResource.java new file mode 100644 index 0000000000..491cdf9f0d --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/artifacts/ImplementationArtifactsResource.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.artifacts; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.xml.namespace.QName; + +import org.eclipse.winery.model.tosca.TImplementationArtifacts.ImplementationArtifact; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.resources.INodeTypeImplementationResourceOrRelationshipTypeImplementationResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.nodetypeimplementations.NodeTypeImplementationResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.relationshiptypeimplementations.RelationshipTypeImplementationResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypesResource; +import org.eclipse.winery.repository.resources.entitytypes.relationshiptypes.RelationshipTypeResource; +import org.eclipse.winery.repository.resources.entitytypes.relationshiptypes.RelationshipTypesResource; +import org.eclipse.winery.repository.resources.interfaces.InterfaceResource; + +/** + * ImplementationArtifact instead of TImplementationArtifact has to be used + * because of difference in the XSD at tImplementationArtifacts vs. + * tDeploymentArtifacts + */ +public class ImplementationArtifactsResource extends GenericArtifactsResource { + + private List implementationArtifacts; + + + public ImplementationArtifactsResource(List implementationArtifact, INodeTypeImplementationResourceOrRelationshipTypeImplementationResource res) { + super(ImplementationArtifactResource.class, ImplementationArtifact.class, implementationArtifact, res); + this.implementationArtifacts = implementationArtifact; + } + + /** + * @return a cast to TNodeTypeImplementationResource of the parent of this + * resource. + */ + protected NodeTypeImplementationResource getNTI() { + return (NodeTypeImplementationResource) this.res; + } + + /** + * @return a cast to TNodeTypeImplementationResource of the parent of this + * resource. + */ + protected RelationshipTypeImplementationResource getRTI() { + return (RelationshipTypeImplementationResource) this.res; + } + + /** + * @param artifactId - encoded implementation artifact Id + */ + @Override + @Path("{artifactId}/") + public ImplementationArtifactResource getEntityResource(@PathParam("artifactId") String artifactId) { + artifactId = Util.URLdecode(artifactId); + return this.getArtifactResourceWithDecodedId(artifactId); + } + + @Override + protected ImplementationArtifactResource getArtifactResourceWithDecodedId(String artifactId) { + return new ImplementationArtifactResource(artifactId, this.implementationArtifacts, (INodeTypeImplementationResourceOrRelationshipTypeImplementationResource) this.res); + } + + @Override + public Collection getAllArtifactResources() { + Collection res = new ArrayList(this.implementationArtifacts.size()); + for (ImplementationArtifact da : this.implementationArtifacts) { + ImplementationArtifactResource r = new ImplementationArtifactResource(da, this.implementationArtifacts, (INodeTypeImplementationResourceOrRelationshipTypeImplementationResource) this.res); + res.add(r); + } + return res; + } + + /** required by artifacts.jsp **/ + public List getInterfacesOfAssociatedType() { + boolean isNodeTypeImplementation = this.res instanceof NodeTypeImplementationResource; + QName type; + List interfaces = new ArrayList(); + if (isNodeTypeImplementation) { + type = this.getNTI().getType(); + NodeTypeResource typeResource = (NodeTypeResource) new NodeTypesResource().getComponentInstaceResource(type); + interfaces.addAll(typeResource.getInterfaces().getAllEntityResources()); + } else { + type = this.getRTI().getType(); + RelationshipTypeResource typeResource = (RelationshipTypeResource) new RelationshipTypesResource().getComponentInstaceResource(type); + interfaces.addAll(typeResource.getSourceInterfaces().getAllEntityResources()); + interfaces.addAll(typeResource.getTargetInterfaces().getAllEntityResources()); + } + return interfaces; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/documentation/DocumentationResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/documentation/DocumentationResource.java new file mode 100644 index 0000000000..6783948d3a --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/documentation/DocumentationResource.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.documentation; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.PUT; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.eclipse.winery.model.tosca.TDocumentation; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.CollectionsHelper; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdResource; + +public class DocumentationResource extends EntityWithoutIdResource { + + public DocumentationResource(TDocumentation o, int idx, List list, IPersistable res) { + super(o, idx, list, res); + } + + @PUT + @Consumes(MediaType.TEXT_HTML) + @Produces(MediaType.TEXT_PLAIN) + public Response setValue(String documentation) { + this.o.getContent().clear(); + this.o.getContent().add(documentation); + this.list.set(this.idx, this.o); + return CollectionsHelper.persist(this.res, this.idDetermination, this.o); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/documentation/DocumentationsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/documentation/DocumentationsResource.java new file mode 100644 index 0000000000..1466a57334 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/documentation/DocumentationsResource.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.documentation; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.model.tosca.TDocumentation; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.CollectionsHelper; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdCollectionResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; + +public class DocumentationsResource extends EntityWithoutIdCollectionResource { + + private static final Logger logger = LoggerFactory.getLogger(DocumentationResource.class); + + + public DocumentationsResource(IPersistable res, List documentations) { + super(DocumentationResource.class, TDocumentation.class, documentations, res); + } + + @Override + public Viewable getHTML() { + return new Viewable("/jsp/documentation.jsp", this.list); + } + + /** + * Adds a new documentation + */ + @POST + @Consumes(MediaType.TEXT_HTML) + public Response addNewElement(String documentation) { + if (documentation == null) { + return Response.status(Status.BAD_REQUEST).entity("No content provided").build(); + } + TDocumentation doc = new TDocumentation(); + doc.getContent().add(documentation); + // TODO: check for duplicates as in instance states + this.list.add(doc); + return CollectionsHelper.persist(this.res, this, doc); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/IEntityTemplateResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/IEntityTemplateResource.java new file mode 100644 index 0000000000..e5025b111b --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/IEntityTemplateResource.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytemplates; + +import javax.ws.rs.DELETE; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; + +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources.IHasTypeReference; + +/** + * Interface ensuring that no methods are forgotten when implementing an + * {@link AbstractComponentInstanceResource}, which is also a template + */ +public interface IEntityTemplateResource extends IHasTypeReference { + + @Path("properties/") + public PropertiesResource getPropertiesResource(); + + @DELETE + public Response onDelete(); + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/PropertiesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/PropertiesResource.java new file mode 100644 index 0000000000..43410951a9 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/PropertiesResource.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytemplates; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; + +import com.sun.jersey.api.view.Viewable; + +public class PropertiesResource { + + private AbstractComponentInstanceResource res; + private TEntityTemplate template; + + + /** + * @param template the template to store the definitions at + * @param res the resource to save after modifications + */ + public PropertiesResource(TEntityTemplate template, AbstractComponentInstanceResource res) { + this.template = template; + this.res = res; + } + + /** + * Currently, properties can only be updated as a whole XML fragment + * + * Getting/setting a fragment of properties is not possible yet + */ + @PUT + @Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.APPLICATION_JSON}) + public Response setProperties(TEntityTemplate.Properties properties) { + this.getTemplate().setProperties(properties); + return BackendUtils.persist(this.res); + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML() { + return new Viewable("/jsp/entitytemplates/properties.jsp", this); + } + + /** data for the JSP **/ + + public TEntityTemplate getTemplate() { + return this.template; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/TEntityTemplateResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/TEntityTemplateResource.java new file mode 100644 index 0000000000..b684f998e5 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/TEntityTemplateResource.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytemplates; + +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources.IHasTypeReference; + +public class TEntityTemplateResource implements IEntityTemplateResource, IHasTypeReference { + + protected final E template; + protected final AbstractComponentInstanceResource res; + private final List list; + private final int idx; + + + /** + * This constructor is used for both entity templates nested in an component + * instance as well as for entity templates being component instances + * itself. + * + * As Java does not support multi-inheritance, we implemented a quick hack + * to re-use this class as inner implementation at templates extending + * AbstractComponentInstanceResourceDefinitionsBacked + * + * @param template the template this resource is modeling + * @param list (optional in the case of component instances) the list the + * template is contained in + * @param idx (optional in the case of component instances) the index in the + * list of the template. Required for fast deletion + * @param res the resource the template (indirectly) belongs to + */ + public TEntityTemplateResource(E template, List list, int idx, AbstractComponentInstanceResource res) { + assert (template != null); + this.template = template; + + // list and idx may + this.list = list; + this.idx = idx; + + assert (res != null); + this.res = res; + } + + public String getId() { + return this.template.getId(); + } + + public void setId(String id) { + // TODO: There is no check for uniqueness of the given id + this.template.setId(id); + } + + /** + * {@inheritDoc} + */ + @Override + public QName getType() { + return this.template.getType(); + } + + @Path("type") + @GET + public String getTypeAsQNameString() { + return this.getType().toString(); + } + + /** + * {@inheritDoc} + */ + @Override + public Response setType(QName type) { + this.template.setType(type); + return BackendUtils.persist(this.res); + } + + /** + * {@inheritDoc} + */ + @Override + public Response setType(String typeStr) { + return this.setType(QName.valueOf(typeStr)); + } + + /** + * {@inheritDoc} + */ + @Override + public PropertiesResource getPropertiesResource() { + return new PropertiesResource(this.template, this.res); + } + + /** + * {@inheritDoc} + */ + @Override + public Response onDelete() { + this.list.remove(this.idx); + return BackendUtils.persist(this.res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/TEntityTemplatesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/TEntityTemplatesResource.java new file mode 100644 index 0000000000..fda60c4f01 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/TEntityTemplatesResource.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytemplates; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.List; + +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources.servicetemplates.topologytemplates.RelationshipTemplateResource; + +import com.sun.jersey.api.NotFoundException; + +/** + * This resource models the list of TEntityTemplates + */ +public class TEntityTemplatesResource { + + private final List templateList; + protected final AbstractComponentInstanceResource res; + private final Class> templateResourceClazz; + private final Class clazz; + + + /** + * + * @param templateList the list to represent + * @param clazz the class of a single element of a list + * @param templateResourceClazz the resource class, which represents a + * single element + * @param res the resource where the list is nested in + */ + public TEntityTemplatesResource(List templateList, Class clazz, Class> templateResourceClazz, AbstractComponentInstanceResource res) { + this.templateList = templateList; + this.clazz = clazz; + this.templateResourceClazz = templateResourceClazz; + this.res = res; + } + + @Path("{id}/") + public TEntityTemplateResource getTEntityTemplateResource(@PathParam("id") String id) { + id = Util.URLdecode(id); + T template = null; + for (T t : this.templateList) { + if (t.getId().equals(id)) { + template = t; + break; + } + } + if (template == null) { + throw new NotFoundException(); + } + Constructor> constructor; + try { + constructor = this.templateResourceClazz.getConstructor(this.clazz, List.class, int.class, AbstractComponentInstanceResource.class); + } catch (Exception e) { + throw new IllegalStateException("Could not get constructor for TElemenetInstanceResource", e); + } + TEntityTemplateResource subRes; + try { + subRes = constructor.newInstance(null, this.res); + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + throw new IllegalStateException("Could not instantiate TElemenetInstanceResource", e); + } + return subRes; + } + + /** + * (no more?) required by topologytemplateedit.jsp + */ + public Collection getAll() { + throw new IllegalStateException("This is outdated, isn't it?"); + // Collection res = new HashSet(); + // @SuppressWarnings("unchecked") + // SortedSet nestedIds = (SortedSet) (SortedSet) Repository.INSTANCE.getNestedIds(this.id, RelationshipTemplateId.class); + // for (RelationshipTemplateId id : nestedIds) { + // RelationshipTemplateResource r = new RelationshipTemplateResource(id); + // res.add(r); + // } + // return res; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/ArtifactTemplateResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/ArtifactTemplateResource.java new file mode 100644 index 0000000000..feb5699c66 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/ArtifactTemplateResource.java @@ -0,0 +1,307 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytemplates.artifacttemplates; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.SortedSet; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.definitions.ArtifactTypeId; +import org.eclipse.winery.common.ids.definitions.NodeTypeImplementationId; +import org.eclipse.winery.common.ids.definitions.RelationshipTypeImplementationId; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.model.tosca.TArtifactReference; +import org.eclipse.winery.model.tosca.TArtifactTemplate; +import org.eclipse.winery.model.tosca.TArtifactTemplate.ArtifactReferences; +import org.eclipse.winery.model.tosca.TDeploymentArtifact; +import org.eclipse.winery.model.tosca.TDeploymentArtifacts; +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TImplementationArtifact; +import org.eclipse.winery.model.tosca.TImplementationArtifacts; +import org.eclipse.winery.model.tosca.TNodeTemplate; +import org.eclipse.winery.model.tosca.TTopologyTemplate; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.datatypes.ids.elements.ArtifactTemplateDirectoryId; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceWithReferencesResource; +import org.eclipse.winery.repository.resources.AbstractComponentsResource; +import org.eclipse.winery.repository.resources.IHasName; +import org.eclipse.winery.repository.resources.entitytemplates.IEntityTemplateResource; +import org.eclipse.winery.repository.resources.entitytemplates.PropertiesResource; +import org.eclipse.winery.repository.resources.entitytemplates.TEntityTemplateResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.nodetypeimplementations.NodeTypeImplementationResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.relationshiptypeimplementations.RelationshipTypeImplementationResource; +import org.eclipse.winery.repository.resources.entitytypes.artifacttypes.ArtifactTypeResource; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; + +/** + * Models an Artifact Template with its artifact references + * + * The associated files (through tArtifactReference) are stored directly within + * this resource. The element is generated during export + * only + * + * This class inherits from AbstractComponentInstanceResourceDefinitionsBacked + * and not from TEntityTemplateResource, because + * ArtifactTemplates are directly available under TDefinitions and we need the + * generic resource handling + */ + +public class ArtifactTemplateResource extends AbstractComponentInstanceWithReferencesResource implements IEntityTemplateResource, IHasName { + + private final TEntityTemplateResource entityTemplateResource; + + + public ArtifactTemplateResource(ArtifactTemplateId id) { + super(id); + this.entityTemplateResource = new TEntityTemplateResource(this.getTArctifactTemplate(), null, 0, this); + } + + /** + * @return null if no artifact type resource is defined + */ + public ArtifactTypeResource getAritfactTypeResource() { + ArtifactTypeId atId = new ArtifactTypeId(this.getTArctifactTemplate().getType()); + return new ArtifactTypeResource(atId); + } + + private TArtifactTemplate getTArctifactTemplate() { + return (TArtifactTemplate) this.element; + } + + @Override + public String getName() { + String name = this.getTArctifactTemplate().getName(); + if (name == null) { + return this.getTArctifactTemplate().getId(); + } else { + return name; + } + } + + @Override + public Response setName(String name) { + this.getTArctifactTemplate().setName(name); + return BackendUtils.persist(this); + } + + @Override + protected TExtensibleElements createNewElement() { + return new TArtifactTemplate(); + } + + @Override + protected void copyIdToFields() { + this.getTArctifactTemplate().setId(this.getId().getXmlId().getDecoded()); + // Namespace cannot be set as the namespace is contained in TDefinitions only + } + + /** + * {@inheritDoc} + */ + @Override + public void synchronizeReferences() { + TArtifactTemplate template = this.getTArctifactTemplate(); + + ArtifactTemplateDirectoryId fileDir = new ArtifactTemplateDirectoryId((ArtifactTemplateId) this.id); + SortedSet files = Repository.INSTANCE.getContainedFiles(fileDir); + if (files.isEmpty()) { + // clear artifact references + template.setArtifactReferences(null); + } else { + ArtifactReferences artifactReferences = new ArtifactReferences(); + template.setArtifactReferences(artifactReferences); + List artRefList = artifactReferences.getArtifactReference(); + for (RepositoryFileReference ref : files) { + // determine path + // path relative from the root of the CSAR is ok (COS01, line 2663) + String path = Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(ref)); + + // put path into data structure + // we do not use Inlude/Exclude as we directly reference a concrete file + TArtifactReference artRef = new TArtifactReference(); + artRef.setReference(path); + artRefList.add(artRef); + } + } + } + + @Path("files/") + public FilesResource getFilesResource() { + ArtifactTemplateDirectoryId fileDir = new ArtifactTemplateDirectoryId((ArtifactTemplateId) this.id); + return new FilesResource(fileDir); + } + + /*********************************************************************** + * "inheritance" from TEntityTemplateResource * + * + * Offering all methods of TEntityTemplateResource and + * forwarding it to our private instance of it + */ + + @Override + public QName getType() { + return this.entityTemplateResource.getType(); + } + + @Override + public Response setType(QName type) { + this.entityTemplateResource.setType(type); + return BackendUtils.persist(this); + } + + @Override + public Response setType(String typeStr) { + this.entityTemplateResource.setType(typeStr); + return BackendUtils.persist(this); + } + + @Override + public PropertiesResource getPropertiesResource() { + return new PropertiesResource(this.getTArctifactTemplate(), this); + } + + int getReferenceCount() { + // We do not use a database, therefore, we have to go through all possibilities pointing to the artifact template + // DAs and IAs point to an artifact template + // DAs are contained in Node Type Implementations and Node Templates + // IAs are contained in Node Type Implementations and Relationship Type Implementations + + int count = 0; + + Collection allDAs = new HashSet<>(); + Collection allIAs = new HashSet<>(); + + // handle Node Type Implementation, which contains DAs and IAs + SortedSet nodeTypeImplementations = Repository.INSTANCE.getAllTOSCAComponentIds(NodeTypeImplementationId.class); + for (NodeTypeImplementationId ntiId : nodeTypeImplementations) { + NodeTypeImplementationResource ntiRes = (NodeTypeImplementationResource) AbstractComponentsResource.getComponentInstaceResource(ntiId); + TDeploymentArtifacts deploymentArtifacts = ntiRes.getNTI().getDeploymentArtifacts(); + if (deploymentArtifacts != null) { + allDAs.addAll(deploymentArtifacts.getDeploymentArtifact()); + } + TImplementationArtifacts implementationArtifacts = ntiRes.getNTI().getImplementationArtifacts(); + if (implementationArtifacts != null) { + allIAs.addAll(implementationArtifacts.getImplementationArtifact()); + } + } + + // check all Relationshiptype Impelentations for IAs + SortedSet relationshipTypeImplementations = Repository.INSTANCE.getAllTOSCAComponentIds(RelationshipTypeImplementationId.class); + for (RelationshipTypeImplementationId rtiId : relationshipTypeImplementations) { + RelationshipTypeImplementationResource rtiRes = (RelationshipTypeImplementationResource) AbstractComponentsResource.getComponentInstaceResource(rtiId); + TImplementationArtifacts implementationArtifacts = rtiRes.getRTI().getImplementationArtifacts(); + if (implementationArtifacts != null) { + allIAs.addAll(implementationArtifacts.getImplementationArtifact()); + } + } + + // check all node templates for DAs + SortedSet serviceTemplates = Repository.INSTANCE.getAllTOSCAComponentIds(ServiceTemplateId.class); + for (ServiceTemplateId sid : serviceTemplates) { + ServiceTemplateResource serviceTemplateRes = (ServiceTemplateResource) AbstractComponentsResource.getComponentInstaceResource(sid); + TTopologyTemplate topologyTemplate = serviceTemplateRes.getServiceTemplate().getTopologyTemplate(); + if (topologyTemplate != null) { + List nodeTemplateOrRelationshipTemplate = topologyTemplate.getNodeTemplateOrRelationshipTemplate(); + for (TEntityTemplate template : nodeTemplateOrRelationshipTemplate) { + if (template instanceof TNodeTemplate) { + TNodeTemplate nodeTemplate = (TNodeTemplate) template; + TDeploymentArtifacts deploymentArtifacts = nodeTemplate.getDeploymentArtifacts(); + if (deploymentArtifacts != null) { + allDAs.addAll(deploymentArtifacts.getDeploymentArtifact()); + } + } + } + } + } + + // now we have all DAs and IAs + + QName ourQName = this.getQName(); + + // check DAs for artifact templates + for (TDeploymentArtifact da : allDAs) { + QName artifactRef = da.getArtifactRef(); + if (ourQName.equals(artifactRef)) { + count++; + } + } + + // check IAs for artifact templates + for (TImplementationArtifact ia : allIAs) { + QName artifactRef = ia.getArtifactRef(); + if (ourQName.equals(artifactRef)) { + count++; + } + } + + return count; + } + + /** + * Query parameter {@code type}:
+ * Retunrs the type of the artifact template + * + * Query parameter {@code referenceCount}:
+ * Determines the number of elements known by the repository which point to + * this resource. This method probably can be moved up the type hierarchy. + * Currently, it is only required here by the topology modeler. + * + * @return the type of the artifact template OR the number of references + * pointing to this resource + */ + @GET + @Produces(MediaType.TEXT_PLAIN) + public Response getRefereneCount(@QueryParam("referenceCount") String referenceCount, @QueryParam("type") String type) { + if (referenceCount != null) { + String res = Integer.toString(this.getReferenceCount()); + return Response.ok().entity(res).build(); + } else if (type != null) { + String res = this.getType().toString(); + return Response.ok().entity(res).build(); + } else { + // we enforce the query parameter to be extensible to other queries + return Response.status(Status.BAD_REQUEST).entity("You have to pass the query parameter referenceCount or type").build(); + } + + } + + /* not yet implemented */ + /* + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getReferenes(@QueryParam("references") String references) { + if (references== null) { + // we enforce the query parameter to be extensible to other queries + return Response.status(Status.BAD_REQUEST).entity("You have to pass the query parameter references").build(); + } + + String res = Integer.toString(this.getReferenceCount()); + return Response.ok().entity(res).build(); + } + */ + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/ArtifactTemplatesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/ArtifactTemplatesResource.java new file mode 100644 index 0000000000..63b86282ec --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/ArtifactTemplatesResource.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytemplates.artifacttemplates; + +import org.eclipse.winery.repository.resources.AbstractComponentsWithTypeReferenceResource; + +/** + * This class does NOT inherit from TEntityTemplatesResource + * as these templates are directly nested in a TDefinitionsElement + */ +public class ArtifactTemplatesResource extends AbstractComponentsWithTypeReferenceResource { + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/FilesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/FilesResource.java new file mode 100644 index 0000000000..9b1f364a40 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/FilesResource.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytemplates.artifacttemplates; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.SortedSet; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.UriInfo; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.Constants; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.datatypes.FileMeta; +import org.eclipse.winery.repository.datatypes.ids.elements.ArtifactTemplateDirectoryId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; +import com.sun.jersey.core.header.FormDataContentDisposition; +import com.sun.jersey.multipart.FormDataBodyPart; +import com.sun.jersey.multipart.FormDataParam; + +public class FilesResource { + + private static final Logger logger = LoggerFactory.getLogger(FilesResource.class); + private final ArtifactTemplateDirectoryId fileDir; + + + public FilesResource(ArtifactTemplateDirectoryId fileDir) { + this.fileDir = fileDir; + } + + private String getData4jqueryFileUpload(List metas) { + String data4jqueryFileUpload = Utils.Object2JSON(metas); + data4jqueryFileUpload = "{\"files\":" + data4jqueryFileUpload + "}"; + return data4jqueryFileUpload; + } + + /** + * Handles the upload of a single file. Adds the given file to the + * current artifact template. + * + * If the file already exists, is it overriden + * + * @return JSON with data required by JQuery-File-Upload (see + * https://github.com/blueimp/jQuery-File-Upload/wiki/Setup) + */ + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.MULTIPART_FORM_DATA) + public Response onPost(@FormDataParam("files[]") InputStream uploadedInputStream, @FormDataParam("files[]") FormDataContentDisposition fileDetail, @FormDataParam("files[]") FormDataBodyPart body, @Context UriInfo uriInfo) { + // existence check not required as instantiation of the resource ensures that the object only exists if the resource exists + FilesResource.logger.debug("Beginning with file upload"); + + String fileName = fileDetail.getFileName(); + if (StringUtils.isEmpty(fileName)) { + return Response.status(Status.BAD_REQUEST).build(); + } + RepositoryFileReference ref = this.fileName2fileRef(fileName, false); + + // TODO: instead of fixing the media type, we could overwrite the browser's mediatype by using some user configuration + BufferedInputStream bis = new BufferedInputStream(uploadedInputStream); + MediaType mediaType = Utils.getFixedMimeType(bis, fileName, body.getMediaType()); + + Response response = BackendUtils.putContentToFile(ref, bis, mediaType); + if (response.getStatus() == Status.INTERNAL_SERVER_ERROR.getStatusCode()) { + return response; + } + + // create FileMeta object + String URL = Utils.getAbsoluteURL(this.fileDir) + Util.URLencode(fileName); + String thumbnailURL = uriInfo.getBaseUriBuilder().path(Constants.PATH_MIMETYPEIMAGES).path(FilenameUtils.getExtension(fileName) + Constants.SUFFIX_MIMETYPEIMAGES).build().toString(); + long size; + try { + size = Repository.INSTANCE.getSize(ref); + } catch (IOException e) { + FilesResource.logger.error(e.getMessage(), e); + return Response.serverError().entity(e.getMessage()).build(); + } + FileMeta fileMeta = new FileMeta(fileName, size, URL, thumbnailURL); + + List metas = new ArrayList(); + metas.add(fileMeta); + return Response.created(Utils.createURI(URL)).entity(this.getData4jqueryFileUpload(metas)).build(); + } + + /** + * Returns a list of file meta object + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public String getJSON() { + return this.getData4jqueryFileUpload(this.getAllFileMetas()); + } + + private List getAllFileMetas() { + List res = new ArrayList(); + SortedSet fileRefs = Repository.INSTANCE.getContainedFiles(this.fileDir); + for (RepositoryFileReference ref : fileRefs) { + res.add(new FileMeta(ref)); + } + return res; + } + + private RepositoryFileReference fileName2fileRef(String fileName, boolean encoded) { + if (encoded) { + fileName = Util.URLdecode(fileName); + } + RepositoryFileReference ref = new RepositoryFileReference(this.fileDir, fileName); + return ref; + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML() { + return new Viewable("/jsp/entitytemplates/artifacttemplates/files.jsp"); + } + + @GET + @Path("/{fileName}") + public Response getFile(@PathParam("fileName") String fileName, @HeaderParam("If-Modified-Since") String modified) { + RepositoryFileReference ref = this.fileName2fileRef(fileName, true); + return BackendUtils.returnRepoPath(ref, modified); + } + + @DELETE + @Path("/{fileName}") + public Response deleteFile(@PathParam("fileName") String fileName) { + RepositoryFileReference ref = this.fileName2fileRef(fileName, true); + return BackendUtils.delete(ref); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/package-info.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/package-info.java new file mode 100644 index 0000000000..437537892e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/package-info.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +/** + * The sub packages of this package contains all resources, which are derived + * from tEntityTemplate + * + * EntityTemplates get their namespaces from the surrounding + * Definitions-element.
+ * Nevertheless, they are stored using the same filesystem structure as + * EntityTypes + * + * {@link org.eclipse.winery.repository.resources.servicetemplates.topologytemplates.RelationshipTemplateResource} + * and + * {@link org.eclipse.winery.repository.resources.servicetemplates.topologytemplates.NodeTemplateResource} + * are stored in the topology package + */ +package org.eclipse.winery.repository.resources.entitytemplates; + diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/policytemplates/PolicyTemplateResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/policytemplates/PolicyTemplateResource.java new file mode 100644 index 0000000000..e69a2824df --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/policytemplates/PolicyTemplateResource.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytemplates.policytemplates; + +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.definitions.PolicyTemplateId; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TPolicyTemplate; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources.IHasName; +import org.eclipse.winery.repository.resources.entitytemplates.IEntityTemplateResource; +import org.eclipse.winery.repository.resources.entitytemplates.PropertiesResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class PolicyTemplateResource extends AbstractComponentInstanceResource implements IEntityTemplateResource, IHasName { + + private static final Logger logger = LoggerFactory.getLogger(PolicyTemplateResource.class); + + + /** + * Constructor has to be public because of test cases + */ + public PolicyTemplateResource(PolicyTemplateId id) { + super(id); + } + + /** + * Convenience method to avoid casting at the caller's side. + */ + public TPolicyTemplate getPolicyTemplate() { + return (TPolicyTemplate) this.getElement(); + } + + @Override + protected TExtensibleElements createNewElement() { + return new TPolicyTemplate(); + } + + @Override + public QName getType() { + return this.getPolicyTemplate().getType(); + } + + @Override + public Response setType(QName type) { + this.getPolicyTemplate().setType(type); + return BackendUtils.persist(this); + } + + @Override + public Response setType(String typeStr) { + this.getPolicyTemplate().setType(QName.valueOf(typeStr)); + return BackendUtils.persist(this); + } + + @Override + public PropertiesResource getPropertiesResource() { + return new PropertiesResource(this.getPolicyTemplate(), this); + } + + @Override + protected void copyIdToFields() { + this.getPolicyTemplate().setId(this.getId().getXmlId().getDecoded()); + } + + @Override + public String getName() { + String name = this.getPolicyTemplate().getName(); + if (name == null) { + return this.getPolicyTemplate().getId(); + } else { + return name; + } + } + + @Override + public Response setName(String name) { + this.getPolicyTemplate().setName(name); + return BackendUtils.persist(this); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/policytemplates/PolicyTemplatesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/policytemplates/PolicyTemplatesResource.java new file mode 100644 index 0000000000..922877caa4 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytemplates/policytemplates/PolicyTemplatesResource.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytemplates.policytemplates; + +import org.eclipse.winery.repository.resources.AbstractComponentsWithTypeReferenceResource; + +/** + * Manages all policy types in all available namespaces
+ * The actual implementation is done in the + * AbstractComponentsWithTypeReferenceResource + */ +public class PolicyTemplatesResource extends AbstractComponentsWithTypeReferenceResource { + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/EntityTypeImplementationResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/EntityTypeImplementationResource.java new file mode 100644 index 0000000000..8b48e74306 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/EntityTypeImplementationResource.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypeimplementations; + +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal; +import org.eclipse.winery.repository.resources.IHasTypeReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class EntityTypeImplementationResource extends AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal implements IHasTypeReference { + + private static final Logger logger = LoggerFactory.getLogger(EntityTypeImplementationResource.class); + + + protected EntityTypeImplementationResource(TOSCAComponentId id) { + super(id); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/nodetypeimplementations/NodeTypeImplementationResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/nodetypeimplementations/NodeTypeImplementationResource.java new file mode 100644 index 0000000000..95b95d2d55 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/nodetypeimplementations/NodeTypeImplementationResource.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypeimplementations.nodetypeimplementations; + +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.definitions.NodeTypeImplementationId; +import org.eclipse.winery.model.tosca.TDeploymentArtifacts; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TImplementationArtifacts; +import org.eclipse.winery.model.tosca.TNodeTypeImplementation; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.INodeTemplateResourceOrNodeTypeImplementationResource; +import org.eclipse.winery.repository.resources.INodeTypeImplementationResourceOrRelationshipTypeImplementationResource; +import org.eclipse.winery.repository.resources.artifacts.DeploymentArtifactsResource; +import org.eclipse.winery.repository.resources.artifacts.ImplementationArtifactsResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.EntityTypeImplementationResource; + +public class NodeTypeImplementationResource extends EntityTypeImplementationResource implements INodeTemplateResourceOrNodeTypeImplementationResource, INodeTypeImplementationResourceOrRelationshipTypeImplementationResource { + + public NodeTypeImplementationResource(NodeTypeImplementationId id) { + super(id); + } + + /** + * public because of exporter + */ + public TNodeTypeImplementation getNTI() { + return (TNodeTypeImplementation) this.getElement(); + } + + /** + * Even if both node type implementations and relationship type + * implementations have implementation artifacts, there is no common + * supertype. To avoid endless casts, we just implement the method here + * + * @return + */ + @Path("implementationartifacts/") + public ImplementationArtifactsResource getImplementationArtifacts() { + TImplementationArtifacts implementationArtifacts; + implementationArtifacts = this.getNTI().getImplementationArtifacts(); + if (implementationArtifacts == null) { + implementationArtifacts = new TImplementationArtifacts(); + this.getNTI().setImplementationArtifacts(implementationArtifacts); + } + return new ImplementationArtifactsResource(implementationArtifacts.getImplementationArtifact(), this); + } + + /** + * Only NodeTypes have deployment artifacts, not RelationshipType. + * Therefore, this method is declared in + * {@link NodeTypeImplementationResource} and not in + * {@link EntityTypeImplementationResource} + */ + @Path("deploymentartifacts/") + public DeploymentArtifactsResource getDeploymentArtifacts() { + TDeploymentArtifacts deploymentArtifacts; + deploymentArtifacts = this.getNTI().getDeploymentArtifacts(); + if (deploymentArtifacts == null) { + deploymentArtifacts = new TDeploymentArtifacts(); + this.getNTI().setDeploymentArtifacts(deploymentArtifacts); + } + return new DeploymentArtifactsResource(deploymentArtifacts.getDeploymentArtifact(), this); + } + + @Override + protected TExtensibleElements createNewElement() { + return new TNodeTypeImplementation(); + } + + @Override + protected void copyIdToFields() { + this.getNTI().setTargetNamespace(this.getId().getNamespace().getDecoded()); + this.getNTI().setName(this.getId().getXmlId().getDecoded()); + } + + @Override + public QName getType() { + return this.getNTI().getNodeType(); + } + + @Override + public Response setType(QName type) { + this.getNTI().setNodeType(type); + return BackendUtils.persist(this); + } + + @Override + public Response setType(String typeStr) { + QName type = QName.valueOf(typeStr); + return this.setType(type); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/nodetypeimplementations/NodeTypeImplementationsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/nodetypeimplementations/NodeTypeImplementationsResource.java new file mode 100644 index 0000000000..ecdc801819 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/nodetypeimplementations/NodeTypeImplementationsResource.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypeimplementations.nodetypeimplementations; + +import org.eclipse.winery.repository.resources.AbstractComponentsWithTypeReferenceResource; + +public class NodeTypeImplementationsResource extends AbstractComponentsWithTypeReferenceResource { +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/package-info.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/package-info.java new file mode 100644 index 0000000000..af1c346bc4 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/package-info.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +/** + * The sub packages of this package contains all resources, which are + * implementations of a type.
+ * The specification does NOT introduce tEntityTypeImplementation, but we + * implement as if that had been happened. + */ +package org.eclipse.winery.repository.resources.entitytypeimplementations; + diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/relationshiptypeimplementations/RelationshipTypeImplementationResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/relationshiptypeimplementations/RelationshipTypeImplementationResource.java new file mode 100644 index 0000000000..521758a259 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/relationshiptypeimplementations/RelationshipTypeImplementationResource.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypeimplementations.relationshiptypeimplementations; + +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.definitions.RelationshipTypeImplementationId; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TImplementationArtifacts; +import org.eclipse.winery.model.tosca.TRelationshipTypeImplementation; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.INodeTypeImplementationResourceOrRelationshipTypeImplementationResource; +import org.eclipse.winery.repository.resources.artifacts.ImplementationArtifactsResource; +import org.eclipse.winery.repository.resources.entitytypeimplementations.EntityTypeImplementationResource; + +public class RelationshipTypeImplementationResource extends EntityTypeImplementationResource implements INodeTypeImplementationResourceOrRelationshipTypeImplementationResource { + + public RelationshipTypeImplementationResource(RelationshipTypeImplementationId id) { + super(id); + } + + public TRelationshipTypeImplementation getRTI() { + return (TRelationshipTypeImplementation) this.getElement(); + } + + /** + * Even if both node type implementations and relationship type + * implementations have implementation artifacts, there is no common + * supertype. To avoid endless casts, we just implement the method here + */ + @Path("implementationartifacts/") + public ImplementationArtifactsResource getImplementationArtifacts() { + TImplementationArtifacts implementationArtifacts; + implementationArtifacts = this.getRTI().getImplementationArtifacts(); + if (implementationArtifacts == null) { + implementationArtifacts = new TImplementationArtifacts(); + this.getRTI().setImplementationArtifacts(implementationArtifacts); + } + return new ImplementationArtifactsResource(implementationArtifacts.getImplementationArtifact(), this); + } + + @Override + protected TExtensibleElements createNewElement() { + return new TRelationshipTypeImplementation(); + } + + @Override + protected void copyIdToFields() { + this.getRTI().setTargetNamespace(this.getId().getNamespace().getDecoded()); + this.getRTI().setName(this.getId().getXmlId().getDecoded()); + } + + @Override + public QName getType() { + return this.getRTI().getRelationshipType(); + } + + @Override + public Response setType(QName type) { + this.getRTI().setRelationshipType(type); + return BackendUtils.persist(this); + } + + @Override + public Response setType(String typeStr) { + QName qname = QName.valueOf(typeStr); + return this.setType(qname); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/relationshiptypeimplementations/RelationshipTypeImplementationsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/relationshiptypeimplementations/RelationshipTypeImplementationsResource.java new file mode 100644 index 0000000000..f15c1e532c --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypeimplementations/relationshiptypeimplementations/RelationshipTypeImplementationsResource.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypeimplementations.relationshiptypeimplementations; + +import org.eclipse.winery.repository.resources.AbstractComponentsWithTypeReferenceResource; + +public class RelationshipTypeImplementationsResource extends AbstractComponentsWithTypeReferenceResource { + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/ImplementationsOfOneType.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/ImplementationsOfOneType.java new file mode 100644 index 0000000000..0a93a68fc8 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/ImplementationsOfOneType.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes; + +import java.util.Collection; + +import javax.ws.rs.GET; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.definitions.TopologyGraphElementEntityTypeId; +import org.eclipse.winery.repository.resources.admin.NamespacesResource; + +import com.sun.jersey.api.view.Viewable; + +/** + * specifies the methods required by implementations.jsp + */ +public abstract class ImplementationsOfOneType { + + private final TopologyGraphElementEntityTypeId typeId; + + + public ImplementationsOfOneType(TopologyGraphElementEntityTypeId typeId) { + this.typeId = typeId; + } + + public TopologyGraphElementEntityTypeId getTypeId() { + return this.typeId; + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Response getHTML() { + Viewable viewable = new Viewable("/jsp/entitytypes/implementations.jsp", this); + return Response.ok().entity(viewable).build(); + } + + public Collection getNamespaceAutocompletionList() { + return NamespacesResource.getNamespaces(); + } + + /** + * @return a list of type implementations implementing the associated node + * type + */ + public abstract String getImplementationsTableData(); + + /** + * The string used as URL part + */ + public abstract String getType(); + + /** + * The string displayed to the user + */ + public abstract String getTypeStr(); + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/InstanceStatesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/InstanceStatesResource.java new file mode 100644 index 0000000000..4eaea1c228 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/InstanceStatesResource.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.model.tosca.TTopologyElementInstanceStates; +import org.eclipse.winery.model.tosca.TTopologyElementInstanceStates.InstanceState; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.backend.BackendUtils; + +import com.sun.jersey.api.view.Viewable; + +/** + * Resource for instance states
+ * Used by relationship types and node types + */ +public class InstanceStatesResource { + + private TopologyGraphElementEntityTypeResource typeResource; + private TTopologyElementInstanceStates instanceStates; + + + /** + * + * @param instanceStates the instanceStates to manage + * @param typeResource the type resource, where the instance states are + * managed. This reference is required to fire "persist()" in + * case of updates + */ + public InstanceStatesResource(TTopologyElementInstanceStates instanceStates, TopologyGraphElementEntityTypeResource typeResource) { + this.instanceStates = instanceStates; + this.typeResource = typeResource; + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML() { + return new Viewable("/jsp/entitytypes/instancestates.jsp", this); + } + + public List getInstanceStates() { + List instanceStates = this.instanceStates.getInstanceState(); + ArrayList states = new ArrayList(instanceStates.size()); + for (InstanceState instanceState : instanceStates) { + states.add(instanceState.getState()); + } + return states; + } + + @DELETE + @Path("{instanceState}") + public Response deleteInstanceState(@PathParam("instanceState") String instanceStateToRemove) { + if (StringUtils.isEmpty(instanceStateToRemove)) { + return Response.status(Status.BAD_REQUEST).entity("null instance to remove").build(); + } + instanceStateToRemove = Util.URLdecode(instanceStateToRemove); + + // InstanceState does not override "equals()", therefore we have to manually remove it + + List instanceStates = this.instanceStates.getInstanceState(); + Iterator iterator = instanceStates.iterator(); + boolean found = false; + while (iterator.hasNext() && !found) { + if (iterator.next().getState().equals(instanceStateToRemove)) { + found = true; + } + } + + if (!found) { + return Response.status(Status.NOT_FOUND).build(); + } + + iterator.remove(); + + return BackendUtils.persist(this.typeResource); + } + + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public Response addInstanceState(@FormParam("state") String state) { + if (StringUtils.isEmpty(state)) { + return Response.notAcceptable(null).build(); + } + + // InstanceState does not override "equals()", therefore we have to manually check for existance + + List instanceStates = this.instanceStates.getInstanceState(); + Iterator iterator = instanceStates.iterator(); + boolean found = false; + while (iterator.hasNext() && !found) { + if (iterator.next().getState().equals(state)) { + found = true; + } + } + + if (found) { + // no error, just return + return Response.noContent().build(); + } + + InstanceState instanceState = new InstanceState(); + instanceState.setState(state); + instanceStates.add(instanceState); + + return BackendUtils.persist(this.typeResource); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/TopologyGraphElementEntityTypeResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/TopologyGraphElementEntityTypeResource.java new file mode 100644 index 0000000000..6cebfe844d --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/TopologyGraphElementEntityTypeResource.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes; + +import org.eclipse.winery.common.ids.definitions.TOSCAComponentId; +import org.eclipse.winery.repository.resources.EntityTypeResource; + +public abstract class TopologyGraphElementEntityTypeResource extends EntityTypeResource { + + protected TopologyGraphElementEntityTypeResource(TOSCAComponentId id) { + super(id); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/artifacttypes/ArtifactTypeResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/artifacttypes/ArtifactTypeResource.java new file mode 100644 index 0000000000..232d4f99fa --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/artifacttypes/ArtifactTypeResource.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.artifacttypes; + +import java.util.SortedSet; + +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.constants.Namespaces; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.common.ids.definitions.ArtifactTypeId; +import org.eclipse.winery.model.tosca.TArtifactType; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.datatypes.select2.Select2OptGroup; +import org.eclipse.winery.repository.resources.EntityTypeResource; + +public class ArtifactTypeResource extends EntityTypeResource { + + public ArtifactTypeResource(ArtifactTypeId id) { + super(id); + } + + + private final QName qnameFileExtension = new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "fileExtension"); + + + /** + * @return the file extension associated with this artifact type. May be + * null + */ + @GET + @Path("/fileextension") + public String getAssociatedFileExtension() { + return this.getDefinitions().getOtherAttributes().get(this.qnameFileExtension); + } + + @PUT + @Path("/fileextension") + public Response setAssociatedFileExtension(String fileExtension) { + this.getDefinitions().getOtherAttributes().put(this.qnameFileExtension, fileExtension); + return BackendUtils.persist(this); + } + + @Override + protected TExtensibleElements createNewElement() { + return new TArtifactType(); + } + + @Override + public SortedSet getListOfAllInstances() { + return this.getListOfAllInstances(ArtifactTemplateId.class); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/artifacttypes/ArtifactTypesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/artifacttypes/ArtifactTypesResource.java new file mode 100644 index 0000000000..1718ab739d --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/artifacttypes/ArtifactTypesResource.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.artifacttypes; + +import java.util.SortedSet; + +import javax.ws.rs.GET; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.common.ids.definitions.ArtifactTypeId; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources.AbstractComponentsResource; + +public class ArtifactTypesResource extends AbstractComponentsResource { + + // This cannot be used as the INSTANCE is per startup of the whole + // application + // We could do some checking for the number of ArtifactTypeResources or + // timestamp, + // + // private final HashMap fileExtensionMapping + // = new ArtifactTypesResource().getFileExtensionMapping(); + + /** + * @return a mapping from file extension to artifact type resources + */ + // public HashMap getFileExtensionMapping() { + // HashMap res = new HashMap(); + // for (ArtifactTypeResource at : this.getArtifactTypeResources()) { + // if (at.getAssociatedFileExtension() != null) { + // res.put(at.getAssociatedFileExtension(), at); + // } + // } + // return res; + // } + + @GET + // should be "QName", but that MIME type is not available. XLink is too + // complicated for our setup + @Produces(MediaType.TEXT_PLAIN) + public Response getArtifactTypeQNameForExtension(@QueryParam("extension") String extension) { + if (extension == null) { + return Response.status(Status.NOT_ACCEPTABLE).build(); + } + ArtifactTypeResource artifactType = this.getArtifactTypeForExtension(extension); + Response res; + if (artifactType == null) { + res = Response.status(Status.NOT_FOUND).build(); + } else { + res = Response.ok().entity(artifactType.getId().getQName().toString()).build(); + } + return res; + } + + /** + * Returns the first matching ArtifactTypeResource for the given file + * extension. Returns null if no such ArtifactType can be found + * + * The case of the extension is ignored. + * + * This is more a DAO method + */ + public ArtifactTypeResource getArtifactTypeForExtension(String extension) { + SortedSet allArtifactTypeIds = Repository.INSTANCE.getAllTOSCAComponentIds(ArtifactTypeId.class); + ArtifactTypeResource res = null; + for (ArtifactTypeId id : allArtifactTypeIds) { + ArtifactTypeResource r = new ArtifactTypeResource(id); + if (extension.equalsIgnoreCase(r.getAssociatedFileExtension())) { + res = r; + break; + } + } + return res; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/CapabilityTypeResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/CapabilityTypeResource.java new file mode 100644 index 0000000000..924efd48f7 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/CapabilityTypeResource.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.capabilitytypes; + +import org.eclipse.winery.model.tosca.TCapabilityType; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.common.ids.definitions.CapabilityTypeId; +import org.eclipse.winery.repository.resources.EntityTypeResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class CapabilityTypeResource extends EntityTypeResource { + + private static final Logger logger = LoggerFactory.getLogger(CapabilityTypeResource.class); + + + /** + * Constructor has to be public because of test cases + */ + public CapabilityTypeResource(CapabilityTypeId id) { + super(id); + } + + /** + * Convenience method to avoid casting at the caller's side. + * + * @return the CapabilityType object this resource is representing + */ + public TCapabilityType getCapabilityType() { + return (TCapabilityType) this.getElement(); + } + + @Override + protected TExtensibleElements createNewElement() { + return new TCapabilityType(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/CapabilityTypesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/CapabilityTypesResource.java new file mode 100644 index 0000000000..27500e1324 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/CapabilityTypesResource.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.capabilitytypes; + +import org.eclipse.winery.repository.resources.AbstractComponentsResource; + +/** + * Manages all capability types in all available namespaces
+ * The actual implementation is done in the AbstractComponentsResource + */ +public class CapabilityTypesResource extends AbstractComponentsResource { + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/ImplementationsOfOneNodeTypeResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/ImplementationsOfOneNodeTypeResource.java new file mode 100644 index 0000000000..09d8492b8b --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/ImplementationsOfOneNodeTypeResource.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.nodetypes; + +import java.io.StringWriter; +import java.util.Collection; + +import org.eclipse.winery.common.ids.definitions.NodeTypeId; +import org.eclipse.winery.common.ids.definitions.NodeTypeImplementationId; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.entitytypes.ImplementationsOfOneType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; + +public class ImplementationsOfOneNodeTypeResource extends ImplementationsOfOneType { + + private static final Logger logger = LoggerFactory.getLogger(ImplementationsOfOneNodeTypeResource.class); + + + /** + * The constructor is different from the usual constructors as this resource + * does NOT store own data, but retrieves its data solely from the + * associated node type + * + * @param nodeTypeId the node type id, where this list of implementations + * belongs to + */ + public ImplementationsOfOneNodeTypeResource(NodeTypeId nodeTypeId) { + super(nodeTypeId); + } + + /** + * required by implementations.jsp + * + * @return for each node type implementation implementing the associated + * node type + */ + @Override + public String getImplementationsTableData() { + String res; + JsonFactory jsonFactory = new JsonFactory(); + StringWriter tableDataSW = new StringWriter(); + try { + JsonGenerator jGenerator = jsonFactory.createGenerator(tableDataSW); + jGenerator.writeStartArray(); + + Collection allNodeTypeImplementations = BackendUtils.getAllElementsRelatedWithATypeAttribute(NodeTypeImplementationId.class, this.getTypeId().getQName()); + for (NodeTypeImplementationId ntiID : allNodeTypeImplementations) { + jGenerator.writeStartArray(); + jGenerator.writeString(ntiID.getNamespace().getDecoded()); + jGenerator.writeString(ntiID.getXmlId().getDecoded()); + jGenerator.writeEndArray(); + } + jGenerator.writeEndArray(); + jGenerator.close(); + tableDataSW.close(); + res = tableDataSW.toString(); + } catch (Exception e) { + ImplementationsOfOneNodeTypeResource.logger.error(e.getMessage(), e); + res = "[]"; + } + return res; + } + + @Override + public String getType() { + return "nodetype"; + } + + @Override + public String getTypeStr() { + return "Node Type"; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/NodeTypeResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/NodeTypeResource.java new file mode 100644 index 0000000000..6c573a559c --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/NodeTypeResource.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.nodetypes; + +import javax.ws.rs.Path; + +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TNodeType; +import org.eclipse.winery.model.tosca.TNodeType.CapabilityDefinitions; +import org.eclipse.winery.model.tosca.TNodeType.Interfaces; +import org.eclipse.winery.model.tosca.TNodeType.RequirementDefinitions; +import org.eclipse.winery.model.tosca.TTopologyElementInstanceStates; +import org.eclipse.winery.common.ids.definitions.NodeTypeId; +import org.eclipse.winery.repository.resources.entitytypes.InstanceStatesResource; +import org.eclipse.winery.repository.resources.entitytypes.TopologyGraphElementEntityTypeResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.reqandcapdefs.CapabilityDefinitionsResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.reqandcapdefs.RequirementDefinitionsResource; +import org.eclipse.winery.repository.resources.interfaces.InterfacesResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NodeTypeResource extends TopologyGraphElementEntityTypeResource { + + private static final Logger logger = LoggerFactory.getLogger(NodeTypeResource.class); + + + public NodeTypeResource(NodeTypeId id) { + super(id); + } + + /** + * Convenience method to avoid casting at the caller's side. + */ + public TNodeType getNodeType() { + return (TNodeType) this.getElement(); + } + + /** sub-resources **/ + + @Path("implementations/") + public ImplementationsOfOneNodeTypeResource getImplementations() { + return new ImplementationsOfOneNodeTypeResource((NodeTypeId) this.id); + } + + @Path("instancestates/") + public InstanceStatesResource getInstanceStatesResource() { + TTopologyElementInstanceStates instanceStates = this.getNodeType().getInstanceStates(); + if (instanceStates == null) { + // if an explicit (empty) list does not exist, create it + instanceStates = new TTopologyElementInstanceStates(); + this.getNodeType().setInstanceStates(instanceStates); + } + return new InstanceStatesResource(instanceStates, this); + } + + @Path("interfaces/") + public InterfacesResource getInterfaces() { + Interfaces interfaces = this.getNodeType().getInterfaces(); + if (interfaces == null) { + interfaces = new Interfaces(); + this.getNodeType().setInterfaces(interfaces); + } + return new InterfacesResource(null, interfaces.getInterface(), this); + } + + @Path("requirementdefinitions/") + public RequirementDefinitionsResource getRequirementDefinitions() { + RequirementDefinitions definitions = this.getNodeType().getRequirementDefinitions(); + if (definitions == null) { + definitions = new RequirementDefinitions(); + this.getNodeType().setRequirementDefinitions(definitions); + } + return new RequirementDefinitionsResource(this, definitions.getRequirementDefinition()); + } + + @Path("capabilitydefinitions/") + public CapabilityDefinitionsResource getCapabilityDefinitions() { + CapabilityDefinitions definitions = this.getNodeType().getCapabilityDefinitions(); + if (definitions == null) { + definitions = new CapabilityDefinitions(); + this.getNodeType().setCapabilityDefinitions(definitions); + } + return new CapabilityDefinitionsResource(this, definitions.getCapabilityDefinition()); + } + + @Path("visualappearance/") + public VisualAppearanceResource getVisualAppearanceResource() { + return new VisualAppearanceResource(this, this.getElement().getOtherAttributes(), (NodeTypeId) this.id); + } + + @Override + protected TExtensibleElements createNewElement() { + return new TNodeType(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/NodeTypesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/NodeTypesResource.java new file mode 100644 index 0000000000..e9ed4fd8c8 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/NodeTypesResource.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.nodetypes; + +import org.eclipse.winery.repository.resources.AbstractComponentsResource; + +/** + * Manages all nodetypes in all available namespaces
+ * The actual implementation is done in the AbstractComponentsResource + */ +public class NodeTypesResource extends AbstractComponentsResource { + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/VisualAppearanceResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/VisualAppearanceResource.java new file mode 100644 index 0000000000..d897efedd6 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/VisualAppearanceResource.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.nodetypes; + +import java.io.InputStream; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.constants.QNames; +import org.eclipse.winery.common.ids.definitions.NodeTypeId; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.constants.Filename; +import org.eclipse.winery.repository.datatypes.ids.elements.VisualAppearanceId; +import org.eclipse.winery.repository.resources.GenericVisualAppearanceResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; +import com.sun.jersey.multipart.FormDataBodyPart; +import com.sun.jersey.multipart.FormDataParam; + +public class VisualAppearanceResource extends GenericVisualAppearanceResource { + + private static final Logger logger = LoggerFactory.getLogger(VisualAppearanceResource.class); + + + public VisualAppearanceResource(NodeTypeResource res, Map map, NodeTypeId parentId) { + super(res, map, new VisualAppearanceId(parentId)); + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Response getHTML() { + Viewable viewable = new Viewable("/jsp/entitytypes/nodetypes/visualappearance.jsp", this); + return Response.ok().entity(viewable).build(); + } + + @GET + @Path("50x50") + public Response get50x50Image(@HeaderParam("If-Modified-Since") String modified) { + return this.getImage(Filename.FILENAME_BIG_ICON, modified); + } + + @PUT + @Path("50x50") + @Consumes(MediaType.MULTIPART_FORM_DATA) + public Response post50x50Image(@FormDataParam("file") InputStream uploadedInputStream, @FormDataParam("file") FormDataBodyPart body) { + return this.putImage(Filename.FILENAME_BIG_ICON, uploadedInputStream, body.getMediaType()); + } + + @GET + @Path("bordercolor") + public String getBorderColor() { + return BackendUtils.getColorAndSetDefaultIfNotExisting(this.getId().getParent().getXmlId().getDecoded(), QNames.QNAME_BORDER_COLOR, this.otherAttributes, this.res); + } + + @PUT + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Path("bordercolor") + public Response putBorderColor(@FormParam("color") String color) { + this.otherAttributes.put(QNames.QNAME_BORDER_COLOR, color); + return BackendUtils.persist(this.res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/AbstractReqOrCapDefResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/AbstractReqOrCapDefResource.java new file mode 100644 index 0000000000..b7eea9258a --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/AbstractReqOrCapDefResource.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.nodetypes.reqandcapdefs; + +import java.lang.reflect.Method; +import java.util.List; + +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.eclipse.winery.model.tosca.TCapabilityDefinition; +import org.eclipse.winery.model.tosca.TConstraint; +import org.eclipse.winery.model.tosca.TRequirementDefinition; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.ConstraintsResource; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Bundles common properties of TRequirementDefinition and TCapabilityDefinition + * + * We agreed in the project not to modify org.eclipse.winery.model.tosca. + * Therefore, this resource models the common properties of a + * TRequirementDefinition and a TCapabilityDefinition + */ +public abstract class AbstractReqOrCapDefResource extends EntityWithIdResource implements IIdDetermination { + + private static final Logger logger = LoggerFactory.getLogger(AbstractReqOrCapDefResource.class); + + protected NodeTypeResource parent; + + // the capability or the requirement + private Object reqOrCapDef; + + private List constraints; + + + /** + * @param constraints additional parameter (in comparison to the constructor + * of EntityWithIdResource) as we require that sublist for the + * constrinats sub resource + */ + public AbstractReqOrCapDefResource(IIdDetermination idDetermination, ReqOrCapDef reqOrCapDef, int idx, List list, NodeTypeResource res, List constraints) { + super(idDetermination, reqOrCapDef, idx, list, res); + assert ((reqOrCapDef instanceof TRequirementDefinition) || (reqOrCapDef instanceof TCapabilityDefinition)); + this.parent = res; + this.reqOrCapDef = reqOrCapDef; + this.constraints = constraints; + } + + @GET + @Path("name") + public String getName() { + return (String) this.invokeGetter("getName"); + } + + static String getName(Object reqOrCapDef) { + return (String) AbstractReqOrCapDefResource.invokeGetter(reqOrCapDef, "getName"); + } + + @GET + @Path("lowerbound") + public int getLowerBound() { + return (int) this.invokeGetter("getLowerBound"); + } + + @GET + @Path("upperbound") + public String getUpperBound() { + return (String) this.invokeGetter("getUpperBound"); + } + + @PUT + @Path("name") + public Response setName(@FormParam(value = "name") String name) { + // TODO: type check - see also min/max Instance of a node template + this.invokeSetter("setName", name); + return BackendUtils.persist(this.parent); + } + + @PUT + @Path("lowerbound") + public Response setLowerBound(@FormParam(value = "lowerbound") String value) { + // TODO: type check + this.invokeSetter("setLowerBound", value); + return BackendUtils.persist(this.parent); + } + + @PUT + @Path("upperbound") + public Response setUpperBound(@FormParam(value = "upperbound") String value) { + // TODO: type check + this.invokeSetter("setUpperBound", value); + return BackendUtils.persist(this.parent); + } + + @Path("constraints/") + public ConstraintsResource getConstraintsResource() { + return new ConstraintsResource(this.constraints, this.parent); + } + + private static Object invokeGetter(Object reqOrCapDef, String getterName) { + Method method; + Object res; + try { + method = reqOrCapDef.getClass().getMethod(getterName); + res = method.invoke(reqOrCapDef); + } catch (Exception e) { + AbstractReqOrCapDefResource.logger.error("Could not invoke getter {}", getterName, e); + throw new IllegalStateException(e); + } + return res; + } + + private Object invokeGetter(String getterName) { + return AbstractReqOrCapDefResource.invokeGetter(this.reqOrCapDef, getterName); + } + + /** + * Quick hack method for RequirementOrCapabilityDefinitionsResource + */ + static void invokeSetter(Object reqOrCapDef, String setterName, Object value) { + Method method; + try { + method = reqOrCapDef.getClass().getMethod(setterName, value.getClass()); + method.invoke(reqOrCapDef, value); + } catch (Exception e) { + AbstractReqOrCapDefResource.logger.error("Could not invoke setter {}", setterName, e); + throw new IllegalStateException(e); + } + } + + private void invokeSetter(String setterName, Object value) { + AbstractReqOrCapDefResource.invokeSetter(this.reqOrCapDef, setterName, value); + } + + @GET + @Path("type") + @Produces(MediaType.TEXT_PLAIN) + public String getTypeAsString() { + return this.getType().toString(); + } + + /** + * required by the JSP. + * + * Therefore, we have two getters for the type: QName for the JSP and String + * for REST clients + */ + public abstract QName getType(); + + /** + * Required by reqandcapdefs.jsp + */ + public Object getDef() { + return this.reqOrCapDef; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/CapabilityDefinitionResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/CapabilityDefinitionResource.java new file mode 100644 index 0000000000..0fd3bd3d30 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/CapabilityDefinitionResource.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.nodetypes.reqandcapdefs; + +import java.util.List; + +import javax.ws.rs.FormParam; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.eclipse.winery.model.tosca.TCapabilityDefinition; +import org.eclipse.winery.model.tosca.TCapabilityDefinition.Constraints; +import org.eclipse.winery.model.tosca.TConstraint; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; + +/** + * Implementation similar to RequirementDefinitionResource, but with + * TCapabilityDefinition instead of TRequirementDefinition + */ +public final class CapabilityDefinitionResource extends AbstractReqOrCapDefResource { + + private TCapabilityDefinition capDef; + + + /** + * Constructor has to follow the pattern of EnetityTResource as the + * constructor is invoked by reflection in EntityWithIdcollectionResource + * + * @param res the resource this req def is nested in. Has to be of Type + * "NodeTypeResource". Due to the implementation of + * org.eclipse.winery .repository.resources._support.collections. + * withid.EntityWithIdCollectionResource + * .getEntityResourceInstance(EntityT, int), we have to use + * "AbstractComponentInstanceResource" as type + */ + public CapabilityDefinitionResource(IIdDetermination idDetermination, TCapabilityDefinition capDef, int idx, List list, AbstractComponentInstanceResource res) { + super(idDetermination, capDef, idx, list, (NodeTypeResource) res, CapabilityDefinitionResource.getConstraints(capDef)); + this.capDef = capDef; + } + + /** + * Quick hack to avoid internal server error + */ + public CapabilityDefinitionResource(IIdDetermination idDetermination, TCapabilityDefinition capDef, int idx, List list, IPersistable res) { + this(idDetermination, capDef, idx, list, (AbstractComponentInstanceResource) res); + } + + /** + * Fetch the list of constraints from the given definition. If the list does + * not exist, the list is created an stored in the given capDef + */ + public static List getConstraints(TCapabilityDefinition capDef) { + Constraints constraints = capDef.getConstraints(); + if (constraints == null) { + constraints = new Constraints(); + capDef.setConstraints(constraints); + } + return constraints.getConstraint(); + } + + public QName getType() { + return this.capDef.getCapabilityType(); + } + + @PUT + @Path("type") + public Response setType(@FormParam(value = "type") String value) { + QName qname = QName.valueOf(value); + this.capDef.setCapabilityType(qname); + return BackendUtils.persist(this.parent); + } + + @Override + public String getId(TCapabilityDefinition e) { + return e.getName(); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/CapabilityDefinitionsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/CapabilityDefinitionsResource.java new file mode 100644 index 0000000000..d93edb436e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/CapabilityDefinitionsResource.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.nodetypes.reqandcapdefs; + +import java.util.Collection; +import java.util.List; +import java.util.SortedSet; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.definitions.CapabilityTypeId; +import org.eclipse.winery.model.tosca.TCapabilityDefinition; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; + +public class CapabilityDefinitionsResource extends RequirementOrCapabilityDefinitionsResource { + + private static final Logger logger = LoggerFactory.getLogger(CapabilityDefinitionsResource.class); + + + public CapabilityDefinitionsResource(NodeTypeResource res, List defs) { + super(CapabilityDefinitionResource.class, TCapabilityDefinition.class, defs, res); + } + + @Override + public Viewable getHTML() { + return new Viewable("/jsp/entitytypes/nodetypes/reqandcapdefs/capdefs.jsp", this); + } + + @Override + public Collection getAllTypes() { + SortedSet allTOSCAComponentIds = Repository.INSTANCE.getAllTOSCAComponentIds(CapabilityTypeId.class); + return BackendUtils.convertTOSCAComponentIdCollectionToQNameCollection(allTOSCAComponentIds); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementDefinitionResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementDefinitionResource.java new file mode 100644 index 0000000000..aeee000a29 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementDefinitionResource.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.nodetypes.reqandcapdefs; + +import java.util.List; + +import javax.ws.rs.FormParam; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.eclipse.winery.model.tosca.TConstraint; +import org.eclipse.winery.model.tosca.TRequirementDefinition; +import org.eclipse.winery.model.tosca.TRequirementDefinition.Constraints; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; + +public final class RequirementDefinitionResource extends AbstractReqOrCapDefResource { + + private TRequirementDefinition reqDef; + + + /** + * Constructor has to follow the pattern of EnetityTResource as the + * constructor is invoked by reflection in EntityWithIdcollectionResource + * + * @param res the resource this req def is nested in. Has to be of Type + * "NodeTypeResource". Due to the implementation of + * org.eclipse.winery .repository.resources._support.collections. + * withid.EntityWithIdCollectionResource + * .getEntityResourceInstance(EntityT, int), we have to use + * "AbstractComponentInstanceResource" as type + */ + public RequirementDefinitionResource(IIdDetermination idDetermination, TRequirementDefinition reqDef, int idx, List list, AbstractComponentInstanceResource res) { + super(idDetermination, reqDef, idx, list, (NodeTypeResource) res, RequirementDefinitionResource.getConstraints(reqDef)); + this.reqDef = reqDef; + } + + /** + * Quick fix to avoid internal server error when opening + * RequirementDefinitions Tab + */ + public RequirementDefinitionResource(IIdDetermination idDetermination, TRequirementDefinition reqDef, int idx, List list, IPersistable res) { + this(idDetermination, reqDef, idx, list, (AbstractComponentInstanceResource) res); + } + + /** + * Fetch the list of constraints from the given definition. If the list does + * not exist, the list is created an stored in the given def + */ + public static List getConstraints(TRequirementDefinition def) { + Constraints constraints = def.getConstraints(); + if (constraints == null) { + constraints = new Constraints(); + def.setConstraints(constraints); + } + return constraints.getConstraint(); + } + + public QName getType() { + return this.reqDef.getRequirementType(); + } + + @PUT + @Path("type") + public Response setType(@FormParam(value = "type") String value) { + QName qname = QName.valueOf(value); + this.reqDef.setRequirementType(qname); + return BackendUtils.persist(this.parent); + } + + @Override + public String getId(TRequirementDefinition e) { + return e.getName(); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementDefinitionsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementDefinitionsResource.java new file mode 100644 index 0000000000..62db59634c --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementDefinitionsResource.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.nodetypes.reqandcapdefs; + +import java.util.Collection; +import java.util.List; +import java.util.SortedSet; + +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.ids.definitions.RequirementTypeId; +import org.eclipse.winery.model.tosca.TRequirementDefinition; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; + +import com.sun.jersey.api.view.Viewable; + +public class RequirementDefinitionsResource extends RequirementOrCapabilityDefinitionsResource { + + public RequirementDefinitionsResource(NodeTypeResource res, List defs) { + super(RequirementDefinitionResource.class, TRequirementDefinition.class, defs, res); + } + + @Override + public Viewable getHTML() { + return new Viewable("/jsp/entitytypes/nodetypes/reqandcapdefs/reqdefs.jsp", this); + } + + @Override + public Collection getAllTypes() { + SortedSet allTOSCAComponentIds = Repository.INSTANCE.getAllTOSCAComponentIds(RequirementTypeId.class); + return BackendUtils.convertTOSCAComponentIdCollectionToQNameCollection(allTOSCAComponentIds); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementOrCapabilityDefinitionsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementOrCapabilityDefinitionsResource.java new file mode 100644 index 0000000000..0c6936ee47 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/RequirementOrCapabilityDefinitionsResource.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.nodetypes.reqandcapdefs; + +import java.util.Collection; +import java.util.List; + +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.xml.namespace.QName; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.model.tosca.TCapabilityDefinition; +import org.eclipse.winery.model.tosca.TRequirementDefinition; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdCollectionResource; +import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource; + +import com.sun.jersey.api.view.Viewable; + +/** + * This superclass has only a few methods as we cannot easily abstract from the + * subclasses: We would need Java reflection to invoke "getName" (to get the + * subresource). The hope is that this copy'n'paste programming will not + * introduce bugs when changing childs + * + * We try to abstract from the problems by using generics and reflections + * + * @param TRequirementDefinition or TCapabilityDefinition + * @param the resource managing ReqDefOrCapDef + */ +public abstract class RequirementOrCapabilityDefinitionsResource, ReqDefOrCapDef> extends EntityWithIdCollectionResource { + + protected final NodeTypeResource res; + + + public RequirementOrCapabilityDefinitionsResource(Class entityResourceTClazz, Class entityTClazz, List list, NodeTypeResource res) { + super(entityResourceTClazz, entityTClazz, list, res); + this.res = res; + } + + @Override + public abstract Viewable getHTML(); + + /** + * @return collection of all available types + */ + public abstract Collection getAllTypes(); + + @POST + // As there is no supertype of TCapabilityType and TRequirementType containing the common attributes, we have to rely on unchecked casts + @SuppressWarnings("unchecked") + public Response onPost(@FormParam("name") String name, @FormParam("type") String type, @FormParam("lowerbound") String lowerBound, @FormParam("upperbound") String upperbound) { + if (StringUtils.isEmpty(name)) { + return Response.status(Status.BAD_REQUEST).entity("Name has to be provided").build(); + } + if (StringUtils.isEmpty(type)) { + return Response.status(Status.BAD_REQUEST).entity("Type has to be provided").build(); + } + + int lbound = 1; + if (!StringUtils.isEmpty(lowerBound)) { + try { + lbound = Integer.parseInt(lowerBound); + } catch (NumberFormatException e) { + return Response.status(Status.BAD_REQUEST).entity("Bad format of lowerbound: " + e.getMessage()).build(); + } + } + + String ubound = "1"; + if (!StringUtils.isEmpty(upperbound)) { + ubound = upperbound; + } + + // we also support replacement of existing requirements + // therefore, we loop through the existing requirements + int idx = -1; + boolean found = false; + for (ReqDefOrCapDef d : this.list) { + idx++; + if (this.getId(d).equals(name)) { + found = true; + break; + } + } + + QName typeQName = QName.valueOf(type); + // Create object and put type in it + ReqDefOrCapDef def; + if (this instanceof CapabilityDefinitionsResource) { + def = (ReqDefOrCapDef) new TCapabilityDefinition(); + ((TCapabilityDefinition) def).setCapabilityType(typeQName); + } else { + assert (this instanceof RequirementDefinitionsResource); + def = (ReqDefOrCapDef) new TRequirementDefinition(); + ((TRequirementDefinition) def).setRequirementType(typeQName); + } + + // copy all other data into object + AbstractReqOrCapDefResource.invokeSetter(def, "setName", name); + AbstractReqOrCapDefResource.invokeSetter(def, "setLowerBound", lbound); + AbstractReqOrCapDefResource.invokeSetter(def, "setUpperBound", ubound); + + if (found) { + // replace element + this.list.set(idx, def); + } else { + // add new element + this.list.add(def); + } + + Response r = BackendUtils.persist(this.res); + return r; + } + + @Override + public String getId(ReqDefOrCapDef reqDefOrCapDef) { + return AbstractReqOrCapDefResource.getName(reqDefOrCapDef); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/package-info.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/package-info.java new file mode 100644 index 0000000000..6fbbc5a60e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/package-info.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +/** + * The sub packages of this package contains all resources, which are derived + * from tEntityType + */ +package org.eclipse.winery.repository.resources.entitytypes; + diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/AppliesToResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/AppliesToResource.java new file mode 100644 index 0000000000..0e4b560523 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/AppliesToResource.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.policytypes; + +import javax.ws.rs.GET; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.eclipse.winery.model.tosca.TPolicyType; + +import com.sun.jersey.api.view.Viewable; + +public class AppliesToResource { + + private PolicyTypeResource policyTypeResource; + + + public AppliesToResource(PolicyTypeResource policyTypeResource) { + this.policyTypeResource = policyTypeResource; + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML() { + return new Viewable("/jsp/entitytypes/policytypes/appliesto.jsp", this); + } + + public TPolicyType getPolicyType() { + return this.policyTypeResource.getPolicyType(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/LanguageResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/LanguageResource.java new file mode 100644 index 0000000000..036cc732a3 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/LanguageResource.java @@ -0,0 +1,28 @@ +package org.eclipse.winery.repository.resources.entitytypes.policytypes; + +import javax.ws.rs.GET; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import com.sun.jersey.api.view.Viewable; + +public class LanguageResource { + + private PolicyTypeResource policyTypeResource; + + + public LanguageResource(PolicyTypeResource policyTypeResource) { + this.policyTypeResource = policyTypeResource; + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML() { + return new Viewable("/jsp/entitytypes/policytypes/language.jsp", this); + } + + public String getLanguage() { + return this.policyTypeResource.getPolicyType().getPolicyLanguage(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/PolicyTypeResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/PolicyTypeResource.java new file mode 100644 index 0000000000..62c728ac83 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/PolicyTypeResource.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.policytypes; + +import java.util.SortedSet; + +import javax.ws.rs.Path; + +import org.eclipse.winery.common.ids.definitions.PolicyTemplateId; +import org.eclipse.winery.common.ids.definitions.PolicyTypeId; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TPolicyType; +import org.eclipse.winery.repository.datatypes.select2.Select2OptGroup; +import org.eclipse.winery.repository.resources.EntityTypeResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class PolicyTypeResource extends EntityTypeResource { + + private static final Logger logger = LoggerFactory.getLogger(PolicyTypeResource.class); + + + /** + * Constructor has to be public because of test cases + */ + public PolicyTypeResource(PolicyTypeId id) { + super(id); + } + + /** + * Convenience method to avoid casting at the caller's side. + */ + public TPolicyType getPolicyType() { + return (TPolicyType) this.getElement(); + } + + @Override + protected TExtensibleElements createNewElement() { + return new TPolicyType(); + } + + @Path("appliesto/") + public AppliesToResource getAppliesTo() { + return new AppliesToResource(this); + } + + @Path("language/") + public LanguageResource getLanguage() { + return new LanguageResource(this); + } + + @Override + public SortedSet getListOfAllInstances() { + return this.getListOfAllInstances(PolicyTemplateId.class); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/PolicyTypesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/PolicyTypesResource.java new file mode 100644 index 0000000000..28a1ee79ad --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/policytypes/PolicyTypesResource.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.policytypes; + +import org.eclipse.winery.repository.resources.AbstractComponentsResource; + +/** + * Manages all policy types in all available namespaces
+ * The actual implementation is done in the AbstractComponentsResource + */ +public class PolicyTypesResource extends AbstractComponentsResource { + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/JSPData.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/JSPData.java new file mode 100644 index 0000000000..a5338ed006 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/JSPData.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.properties; + +import java.util.List; + +import org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKV; +import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition; +import org.eclipse.winery.model.tosca.TEntityType; + +/** + * Collects data used by the JSP + */ +public class JSPData { + + // FIXME: this is a quick hack and provides a fixed list of available + // property types only. This list has to be made dynamically updatable (and offer plugins to edit) + // currently only http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#built-in-datatypes are supported + private static final String[] availablePropertyTypes = {"xsd:string", "xsd:boolean", "xsd:decimal", "xsd:float", "xsd:anyURI", "xsd:QName"}; + + private final PropertiesDefinitionResource propertiesDefinitionResource; + private final WinerysPropertiesDefinition wpd; + + + public JSPData(PropertiesDefinitionResource propertiesDefinitionResource, WinerysPropertiesDefinition wpd) { + this.propertiesDefinitionResource = propertiesDefinitionResource; + this.wpd = wpd; + } + + public List getPropertyDefinitionKVList() { + // as this method is used by the JSP, we have to initialize the list and not provide a fake list + // in other words: we are in the mode, where the user has chosen the winery property handling + assert (this.getIsWineryKeyValueProperties()); + if (this.wpd.getPropertyDefinitionKVList() == null) { + return java.util.Collections.emptyList(); + } else { + return this.wpd.getPropertyDefinitionKVList(); + } + } + + public Boolean getIsWineryKeyValueProperties() { + return (this.wpd != null); + // the jsp renders list data only if the list is existing + // we could (somehow) also always keep the old list, but we opted for keeping the choice between the four options also in the XML (and not storing stale data) + // in the case, the WPD is derived from XSD, the list is rendered nevertheless + } + + public boolean getIsWineryKeyValuePropertiesDerivedFromXSD() { + return ((this.wpd != null) && (this.wpd.getIsDerivedFromXSD() != null)); + } + + public String[] getAvailablePropertyTypes() { + return JSPData.availablePropertyTypes; + } + + public TEntityType getEntityType() { + return this.propertiesDefinitionResource.getEntityType(); + } + + public String getElementName() { + if (this.wpd == null) { + return null; + } else { + return this.wpd.getElementName(); + } + } + + public String getNamespace() { + if (this.wpd == null) { + return null; + } else { + return this.wpd.getNamespace(); + } + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/PropertiesDefinitionResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/PropertiesDefinitionResource.java new file mode 100644 index 0000000000..6a6379135d --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/PropertiesDefinitionResource.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.properties; + +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.xml.namespace.QName; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.common.constants.MimeTypes; +import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition; +import org.eclipse.winery.model.tosca.TEntityType; +import org.eclipse.winery.model.tosca.TEntityType.PropertiesDefinition; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.EntityTypeResource; +import org.eclipse.winery.repository.resources.entitytypes.properties.winery.WinerysPropertiesDefinitionResource; +import org.restdoc.annotations.RestDoc; +import org.restdoc.annotations.RestDocParam; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; + +/** + * Models + *
    + *
  1. TOSCA conforming properties definition (XML element / XML schema / none)
  2. + *
  3. Winery's KV properties (in the subresource "winery")
  4. + *
+ * + * This class does not have "KV" in its name, because it models + * {@link TEntityType.PropertiesDefinition} + */ +public class PropertiesDefinitionResource { + + private static final Logger logger = LoggerFactory.getLogger(PropertiesDefinitionResource.class); + + // We hold a copy of super.res as we work on the type EntityTypeResource instead of AbstractComponentInstanceResource + private final EntityTypeResource parentRes; + + // we assume that this class is created at each request + // therefore, we can have "wpd" final + private final WinerysPropertiesDefinition wpd; + + + public PropertiesDefinitionResource(EntityTypeResource res) { + this.parentRes = res; + this.wpd = ModelUtilities.getWinerysPropertiesDefinition(res.getEntityType()); + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML() { + return new Viewable("/jsp/entitytypes/properties/propertiesDefinition.jsp", new JSPData(this, this.wpd)); + } + + public TEntityType getEntityType() { + return this.parentRes.getEntityType(); + } + + @Path("winery/") + public WinerysPropertiesDefinitionResource getWinerysPropertiesDefinitionResource() { + // this.wpd is null if there is no winery definition exisitin. The subresource handles that case, too + return new WinerysPropertiesDefinitionResource(this.parentRes, this.wpd); + } + + @DELETE + public Response clearPropertiesDefinition() { + this.getEntityType().setPropertiesDefinition(null); + ModelUtilities.removeWinerysPropertiesDefinition(this.getEntityType()); + return BackendUtils.persist(this.parentRes); + } + + public boolean getIsWineryKeyValueProperties() { + return (this.wpd != null); + } + + @GET + @Produces(MimeTypes.MIMETYPE_XSD) + public Response getXSD() { + if (this.getIsWineryKeyValueProperties()) { + return Response.ok().entity(ModelUtilities.getWinerysPropertiesDefinitionXSDAsDocument(this.wpd)).build(); + } else { + // not yet implemented + // We would have to check the imports in the repo for the defined property + // This also has to be similarly done at the export to determine the right imports + return Response.status(Status.NOT_FOUND).build(); + } + } + + @GET + @RestDoc(methodDescription = "We provide the XSD at . and at ./xsd/ to enable simple quering in the browser without the hazzle of setting the correct mime type.") + @Path("xsd/") + @Produces(MimeTypes.MIMETYPE_XSD) + public Response getXSDAtSubResource() { + return this.getXSD(); + } + + // @formatter:off + @POST + @RestDoc(methodDescription="Updates/creates a property based on XSD element or XML schema.") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + public Response onPost( + @FormParam("name") @RestDocParam(description="Either xsdelement or xsdtype. 'name' comes from x-editable, which uses that as field name") String name, + @FormParam("value") @RestDocParam(description="The qname") String value) { + // @formatter:on + if (StringUtils.isEmpty(name)) { + return Response.status(Status.BAD_REQUEST).entity("You have to provide a key/type or a name/value pair").build(); + } + if (StringUtils.isEmpty(value)) { + return Response.status(Status.BAD_REQUEST).entity("If a name is provided, a value has also to be provided").build(); + } + + // first of all, remove Winery's Properties definition (if it exists) + ModelUtilities.removeWinerysPropertiesDefinition(this.getEntityType()); + + QName qname = QName.valueOf(value); + + // replace old properties definition by new one + PropertiesDefinition def = new PropertiesDefinition(); + if (name.equals("xsdtype")) { + def.setType(qname); + } else if (name.equals("xsdelement")) { + def.setElement(qname); + } else { + return Response.status(Status.BAD_REQUEST).entity("Invalid name. Choose xsdelement or xsdtype").build(); + } + this.getEntityType().setPropertiesDefinition(def); + List errors = new ArrayList<>(); + BackendUtils.deriveWPD(this.getEntityType(), errors); + // currently the errors are just logged + for (String error : errors) { + PropertiesDefinitionResource.logger.debug(error); + } + return BackendUtils.persist(this.parentRes); + + } + +} \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/PropertyDefinitionKVListResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/PropertyDefinitionKVListResource.java new file mode 100644 index 0000000000..f967042b6e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/PropertyDefinitionKVListResource.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.properties.winery; + +import org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKV; +import org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKVList; +import org.eclipse.winery.repository.resources.EntityTypeResource; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdCollectionResource; + +import com.sun.jersey.api.view.Viewable; + +/** + * Supports Winery's k/v properties introducing sub resources + * "PropertyDefinition", which defines one property + */ +public class PropertyDefinitionKVListResource extends EntityWithIdCollectionResource { + + public PropertyDefinitionKVListResource(EntityTypeResource res, PropertyDefinitionKVList list) { + super(PropertyDefinitionKVResource.class, PropertyDefinitionKV.class, list, res); + } + + @Override + public String getId(PropertyDefinitionKV entity) { + return entity.getKey(); + } + + @Override + public Viewable getHTML() { + throw new IllegalStateException("Not yet implemented."); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/PropertyDefinitionKVResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/PropertyDefinitionKVResource.java new file mode 100644 index 0000000000..00a8d24491 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/PropertyDefinitionKVResource.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.properties.winery; + +import java.util.List; + +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; + +import org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKV; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdResource; +import org.restdoc.annotations.RestDoc; + +/** + * Models a definition of one property + * + * This is NOT in line with CSPRD01, which forces one element of one type + */ +public class PropertyDefinitionKVResource extends EntityWithIdResource { + + public PropertyDefinitionKVResource(IIdDetermination idDetermination, PropertyDefinitionKV o, int idx, List list, AbstractComponentInstanceResource res) { + super(idDetermination, o, idx, list, res); + } + + public PropertyDefinitionKVResource(IIdDetermination idDetermination, PropertyDefinitionKV o, int idx, List list, IPersistable res) { + super(idDetermination, o, idx, list, res); + } + + @GET + @RestDoc(methodDescription = "@return type is the 'id' of the type ('shortType'), not the full type name") + @Path("type") + public String getType() { + return this.o.getType(); + } + + @PUT + @RestDoc(methodDescription = "@return type is the 'id' of the type ('shortType'), not the full type name") + @Path("type") + public Response setType(@FormParam("type") String type) { + this.o.setType(type); + return BackendUtils.persist(this.res); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/WinerysPropertiesDefinitionResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/WinerysPropertiesDefinitionResource.java new file mode 100644 index 0000000000..0d219e3577 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/properties/winery/WinerysPropertiesDefinitionResource.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.properties.winery; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.eclipse.winery.model.tosca.TEntityType; +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKVList; +import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.EntityTypeResource; +import org.restdoc.annotations.RestDoc; + +import com.sun.jersey.api.NotFoundException; + +public class WinerysPropertiesDefinitionResource { + + private final EntityTypeResource res; + private final WinerysPropertiesDefinition wpd; + + + /** + * @param res the resource where winery's k/v properties are defined + * @param wpd winery's properties definition object, MAY be null + */ + public WinerysPropertiesDefinitionResource(EntityTypeResource res, WinerysPropertiesDefinition wpd) { + this.res = res; + this.wpd = wpd; + } + + @POST + @RestDoc(methodDescription = "switches the mode to winery properties instead of element/type properties") + public Response onPost() { + TEntityType et = this.res.getEntityType(); + + // clear current properties definition + et.setPropertiesDefinition(null); + + // create empty winery properties definition and persist it + WinerysPropertiesDefinition wpd = new WinerysPropertiesDefinition(); + ModelUtilities.replaceWinerysPropertiesDefinition(et, wpd); + return BackendUtils.persist(this.res); + } + + @Path("namespace") + @GET + @Produces(MediaType.TEXT_PLAIN) + public String getNamespace() { + if (this.wpd == null) { + throw new NotFoundException(); + } + return this.wpd.getNamespace(); + } + + @Path("namespace") + @PUT + @Consumes(MediaType.TEXT_PLAIN) + public Response setNamespace(String namespace) { + if (this.wpd == null) { + throw new NotFoundException(); + } + this.wpd.setNamespace(namespace); + return BackendUtils.persist(this.res); + } + + @Path("elementname") + @GET + @Produces(MediaType.TEXT_PLAIN) + public String getElementName() { + if (this.wpd == null) { + throw new NotFoundException(); + } + return this.wpd.getElementName(); + } + + @Path("elementname") + @PUT + @Consumes(MediaType.TEXT_PLAIN) + public Response setLocalname(String elementName) { + if (this.wpd == null) { + throw new NotFoundException(); + } + this.wpd.setElementName(elementName); + return BackendUtils.persist(this.res); + } + + @Path("elementname") + @PUT + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public Response setLocalnameViaWebUI(@FormParam(value = "name") String elementName) { + if (this.wpd == null) { + throw new NotFoundException(); + } + this.wpd.setElementName(elementName); + return BackendUtils.persist(this.res); + } + + /** + * Here, also the addition of k/v properties is handled. + */ + @Path("list/") + public PropertyDefinitionKVListResource getListResource() { + if (this.wpd == null) { + throw new NotFoundException(); + } + PropertyDefinitionKVList list = this.wpd.getPropertyDefinitionKVList(); + if (list == null) { + list = new PropertyDefinitionKVList(); + this.wpd.setPropertyDefinitionKVList(list); + } + return new PropertyDefinitionKVListResource(this.res, list); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/ImplementationsOfOneRelationshipTypeResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/ImplementationsOfOneRelationshipTypeResource.java new file mode 100644 index 0000000000..a3e926bf57 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/ImplementationsOfOneRelationshipTypeResource.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.relationshiptypes; + +import java.io.StringWriter; +import java.util.Collection; + +import org.eclipse.winery.common.ids.definitions.RelationshipTypeId; +import org.eclipse.winery.common.ids.definitions.RelationshipTypeImplementationId; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.entitytypes.ImplementationsOfOneType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; + +public class ImplementationsOfOneRelationshipTypeResource extends ImplementationsOfOneType { + + public ImplementationsOfOneRelationshipTypeResource(RelationshipTypeId typeId) { + super(typeId); + } + + + private static final Logger logger = LoggerFactory.getLogger(ImplementationsOfOneRelationshipTypeResource.class); + + + /** + * required by implementations.jsp + * + * Method similar top the one of ImplementationsOfOneNodeTypeResource + * + * @return for each node type implementation implementing the associated + * node type + */ + @Override + public String getImplementationsTableData() { + String res; + JsonFactory jsonFactory = new JsonFactory(); + StringWriter tableDataSW = new StringWriter(); + try { + JsonGenerator jGenerator = jsonFactory.createGenerator(tableDataSW); + jGenerator.writeStartArray(); + + Collection allNTIids = BackendUtils.getAllElementsRelatedWithATypeAttribute(RelationshipTypeImplementationId.class, this.getTypeId().getQName()); + for (RelationshipTypeImplementationId ntiID : allNTIids) { + jGenerator.writeStartArray(); + jGenerator.writeString(ntiID.getNamespace().getDecoded()); + jGenerator.writeString(ntiID.getXmlId().getDecoded()); + jGenerator.writeEndArray(); + } + jGenerator.writeEndArray(); + jGenerator.close(); + tableDataSW.close(); + res = tableDataSW.toString(); + } catch (Exception e) { + ImplementationsOfOneRelationshipTypeResource.logger.error(e.getMessage(), e); + res = "[]"; + } + return res; + } + + @Override + public String getType() { + return "relationshiptype"; + } + + @Override + public String getTypeStr() { + return "Relationship Type"; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/RelationshipTypeResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/RelationshipTypeResource.java new file mode 100644 index 0000000000..c874bd5018 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/RelationshipTypeResource.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.relationshiptypes; + +import java.util.Collection; +import java.util.SortedSet; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TRelationshipType; +import org.eclipse.winery.model.tosca.TRelationshipType.SourceInterfaces; +import org.eclipse.winery.model.tosca.TRelationshipType.TargetInterfaces; +import org.eclipse.winery.model.tosca.TRelationshipType.ValidSource; +import org.eclipse.winery.model.tosca.TRelationshipType.ValidTarget; +import org.eclipse.winery.model.tosca.TTopologyElementInstanceStates; +import org.eclipse.winery.common.ids.definitions.NodeTypeId; +import org.eclipse.winery.common.ids.definitions.RelationshipTypeId; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources.entitytypes.InstanceStatesResource; +import org.eclipse.winery.repository.resources.entitytypes.TopologyGraphElementEntityTypeResource; +import org.eclipse.winery.repository.resources.interfaces.InterfacesResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; + +public class RelationshipTypeResource extends TopologyGraphElementEntityTypeResource { + + private static final Logger logger = LoggerFactory.getLogger(RelationshipTypeResource.class); + + + public RelationshipTypeResource(RelationshipTypeId id) { + super(id); + } + + @Path("implementations/") + public ImplementationsOfOneRelationshipTypeResource getImplementations() { + return new ImplementationsOfOneRelationshipTypeResource((RelationshipTypeId) this.id); + } + + @Path("visualappearance/") + public VisualAppearanceResource getVisualAppearanceResource() { + return new VisualAppearanceResource(this, this.getElement().getOtherAttributes(), (RelationshipTypeId) this.id); + } + + @Path("instancestates/") + public InstanceStatesResource getInstanceStatesResource() { + TTopologyElementInstanceStates instanceStates = this.getRelationshipType().getInstanceStates(); + if (instanceStates == null) { + // if an explicit (empty) list does not exist, create it + instanceStates = new TTopologyElementInstanceStates(); + this.getRelationshipType().setInstanceStates(instanceStates); + } + return new InstanceStatesResource(this.getRelationshipType().getInstanceStates(), this); + } + + @Path("sourceinterfaces/") + public InterfacesResource getSourceInterfaces() { + SourceInterfaces interfaces = this.getRelationshipType().getSourceInterfaces(); + if (interfaces == null) { + interfaces = new SourceInterfaces(); + this.getRelationshipType().setSourceInterfaces(interfaces); + } + return new InterfacesResource("source", interfaces.getInterface(), this); + } + + @Path("targetinterfaces/") + public InterfacesResource getTargetInterfaces() { + TargetInterfaces interfaces = this.getRelationshipType().getTargetInterfaces(); + if (interfaces == null) { + interfaces = new TargetInterfaces(); + this.getRelationshipType().setTargetInterfaces(interfaces); + } + return new InterfacesResource("target", interfaces.getInterface(), this); + } + + @Path("validendings/") + @GET + @Produces(MediaType.TEXT_HTML) + public Response getHTML() { + Viewable viewable = new Viewable("/jsp/entitytypes/relationshiptypes/validendings.jsp", this); + return Response.ok().entity(viewable).build(); + } + + @Path("validsource") + @GET + public String getValidSource() { + ValidSource validSource; + if (((validSource = this.getRelationshipType().getValidSource()) == null) || (validSource.getTypeRef() == null)) { + return null; + } + return this.getRelationshipType().getValidSource().getTypeRef().toString(); + } + + @Path("validsource") + @PUT + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public Response setValidSource(String typeRef) { + ValidSource vs = new ValidSource(); + QName qname = QName.valueOf(typeRef); + vs.setTypeRef(qname); + this.getRelationshipType().setValidSource(vs); + return BackendUtils.persist(this); + } + + @Path("validtarget") + @GET + public String getValidTarget() { + ValidTarget validTarget; + if (((validTarget = this.getRelationshipType().getValidTarget()) == null) || (validTarget.getTypeRef() == null)) { + return null; + } + return this.getRelationshipType().getValidTarget().getTypeRef().toString(); + } + + @Path("validtarget") + @PUT + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public Response setValidTarget(String typeRef) { + ValidTarget vt = new ValidTarget(); + QName qname = QName.valueOf(typeRef); + vt.setTypeRef(qname); + this.getRelationshipType().setValidTarget(vt); + return BackendUtils.persist(this); + } + + /** + * Required for validendings.jsp + */ + public Collection getPossibleValidEndings() { + SortedSet allNodeTypeIds = Repository.INSTANCE.getAllTOSCAComponentIds(NodeTypeId.class); + return allNodeTypeIds; + } + + /** + * Convenience method to avoid casting at the caller's side. + */ + public TRelationshipType getRelationshipType() { + return (TRelationshipType) this.getElement(); + } + + @Override + protected TExtensibleElements createNewElement() { + return new TRelationshipType(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/RelationshipTypesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/RelationshipTypesResource.java new file mode 100644 index 0000000000..a0422f7676 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/RelationshipTypesResource.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.relationshiptypes; + +import org.eclipse.winery.repository.resources.AbstractComponentsResource; + +public class RelationshipTypesResource extends AbstractComponentsResource { +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/VisualAppearanceResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/VisualAppearanceResource.java new file mode 100644 index 0000000000..c17c19bac2 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/relationshiptypes/VisualAppearanceResource.java @@ -0,0 +1,291 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + * Jerome Tagliaferri - support for setting the color + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.relationshiptypes; + +import java.io.StringWriter; +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.xml.namespace.QName; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.constants.Defaults; +import org.eclipse.winery.common.constants.Namespaces; +import org.eclipse.winery.common.constants.QNames; +import org.eclipse.winery.common.ids.definitions.RelationshipTypeId; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.datatypes.ids.elements.VisualAppearanceId; +import org.eclipse.winery.repository.resources.GenericVisualAppearanceResource; +import org.restdoc.annotations.RestDoc; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; +import com.sun.jersey.api.view.Viewable; + +public class VisualAppearanceResource extends GenericVisualAppearanceResource { + + private static final Logger logger = LoggerFactory.getLogger(VisualAppearanceResource.class); + + private static final QName QNAME_ARROWHEAD_SOURCE = new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "sourceArrowHead"); + private static final QName QNAME_ARROWHEAD_TARGET = new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "targetArrowHead"); + private static final QName QNAME_DASH = new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "dash"); + private static final QName QNAME_LINEWIDTH = new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "linewidth"); + private static final QName QNAME_HOVER_COLOR = new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "hovercolor"); + + + public VisualAppearanceResource(RelationshipTypeResource res, Map map, RelationshipTypeId parentId) { + super(res, map, new VisualAppearanceId(parentId)); + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Response getHTML() { + Viewable viewable = new Viewable("/jsp/entitytypes/relationshiptypes/visualappearance.jsp", this); + return Response.ok().entity(viewable).build(); + } + + @GET + @RestDoc(methodDescription = "@return JSON object to be used at jsPlumb.registerConnectionType('NAME', )") + @Produces(MediaType.APPLICATION_JSON) + public Response getConnectionTypeForJsPlumbData() { + JsonFactory jsonFactory = new JsonFactory(); + StringWriter sw = new StringWriter(); + try { + JsonGenerator jg = jsonFactory.createGenerator(sw); + jg.writeStartObject(); + + jg.writeFieldName("connector"); + jg.writeString("Flowchart"); + + jg.writeFieldName("paintStyle"); + jg.writeStartObject(); + jg.writeFieldName("lineWidth"); + jg.writeNumber(this.getLineWidth()); + jg.writeFieldName("strokeStyle"); + jg.writeObject(this.getColor()); + String dash = this.getDash(); + if (!StringUtils.isEmpty(dash)) { + String dashStyle = null; + switch (dash) { + case "dotted": + dashStyle = "1 5"; + break; + case "dotted2": + dashStyle = "3 4"; + break; + case "plain": + // default works + // otherwise, "1 0" can be used + break; + } + if (dashStyle != null) { + jg.writeStringField("dashstyle", dashStyle); + } + } + jg.writeEndObject(); + + jg.writeFieldName("hoverPaintStyle"); + jg.writeStartObject(); + jg.writeFieldName("strokeStyle"); + jg.writeObject(this.getHoverColor()); + jg.writeEndObject(); + + // BEGIN: Overlays + + jg.writeFieldName("overlays"); + jg.writeStartArray(); + + // source arrow head + String head = this.getSourceArrowHead(); + if (!head.equals("none")) { + jg.writeStartArray(); + jg.writeString(head); + + jg.writeStartObject(); + + jg.writeFieldName("location"); + jg.writeNumber(0); + + // arrow should point towards the node and not away from it + jg.writeFieldName("direction"); + jg.writeNumber(-1); + + jg.writeFieldName("width"); + jg.writeNumber(20); + + jg.writeFieldName("length"); + jg.writeNumber(12); + + jg.writeEndObject(); + jg.writeEndArray(); + } + + // target arrow head + head = this.getTargetArrowHead(); + if (!head.equals("none")) { + jg.writeStartArray(); + jg.writeString(head); + jg.writeStartObject(); + jg.writeFieldName("location"); + jg.writeNumber(1); + jg.writeFieldName("width"); + jg.writeNumber(20); + jg.writeFieldName("length"); + jg.writeNumber(12); + jg.writeEndObject(); + jg.writeEndArray(); + } + + // Type in brackets on the arrow + jg.writeStartArray(); + jg.writeString("Label"); + jg.writeStartObject(); + jg.writeStringField("id", "label"); + jg.writeStringField("label", "(" + ((RelationshipTypeResource) this.res).getName() + ")"); + jg.writeStringField("cssClass", "relationshipTypeLabel"); + jg.writeFieldName("location"); + jg.writeNumber(0.5); + jg.writeEndObject(); + jg.writeEndArray(); + + jg.writeEndArray(); + + // END: Overlays + + jg.writeEndObject(); + + jg.close(); + } catch (Exception e) { + VisualAppearanceResource.logger.error(e.getMessage(), e); + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build(); + } + String res = sw.toString(); + return Response.ok(res).build(); + } + + private String getOtherAttributeWithDefault(QName qname, String def) { + String res = this.otherAttributes.get(qname); + if (StringUtils.isEmpty(res)) { + return def; + } else { + return res; + } + } + + /* * * source arrow head * * */ + + public String getSourceArrowHead() { + return this.getOtherAttributeWithDefault(VisualAppearanceResource.QNAME_ARROWHEAD_SOURCE, Defaults.DEFAULT_RT_ARROWHEAD_SOURCE); + } + + @PUT + @Consumes(MediaType.TEXT_PLAIN) + @Path("sourcearrowhead") + public Response onPutSourceHead(String config) { + if (StringUtils.isEmpty(config)) { + return Response.status(Status.BAD_REQUEST).entity("config must not be empty").build(); + } + this.otherAttributes.put(VisualAppearanceResource.QNAME_ARROWHEAD_SOURCE, config); + return BackendUtils.persist(this.res); + } + + /* * * target arrow head * * */ + + public String getTargetArrowHead() { + return this.getOtherAttributeWithDefault(VisualAppearanceResource.QNAME_ARROWHEAD_TARGET, Defaults.DEFAULT_RT_ARROWHEAD_TARGET); + } + + @PUT + @Consumes(MediaType.TEXT_PLAIN) + @Path("targetarrowhead") + public Response onPutTargetHead(String config) { + if (StringUtils.isEmpty(config)) { + return Response.status(Status.BAD_REQUEST).entity("config must not be empty").build(); + } + this.otherAttributes.put(VisualAppearanceResource.QNAME_ARROWHEAD_TARGET, config); + return BackendUtils.persist(this.res); + } + + /* * * + * + * stroke dash array / represents the line + * + * Attention: if a linewidth != 1 is chosen, the dash has to be multiplied somehow by the line width + * See: http://jsplumbtoolkit.com/doc/paint-styles: + * "The dashstyle attribute is specified as an array of strokes and spaces, where each value is some multiple of the width of the Connector" + * + * * * */ + + public String getDash() { + return this.getOtherAttributeWithDefault(VisualAppearanceResource.QNAME_DASH, Defaults.DEFAULT_RT_DASH); + } + + @PUT + @Consumes(MediaType.TEXT_PLAIN) + @Path("dash") + public Response onPutDash(String config) { + if (StringUtils.isEmpty(config)) { + return Response.status(Status.BAD_REQUEST).entity("config must not be empty").build(); + } + this.otherAttributes.put(VisualAppearanceResource.QNAME_DASH, config); + return BackendUtils.persist(this.res); + } + + /* * * stroke/line width * * */ + + public String getLineWidth() { + return this.getOtherAttributeWithDefault(VisualAppearanceResource.QNAME_LINEWIDTH, Defaults.DEFAULT_RT_LINEWIDTH); + } + + /* * * color * * */ + + /** + * read by topologytemplateeditor.jsp via ${it.color} + */ + public String getColor() { + return BackendUtils.getColorAndSetDefaultIfNotExisting(this.getId().getParent().getXmlId().getDecoded(), QNames.QNAME_COLOR, this.otherAttributes, this.res); + } + + @PUT + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Path("color") + public Response onPutColor(@FormParam("color") String color) { + this.otherAttributes.put(QNames.QNAME_COLOR, color); + return BackendUtils.persist(this.res); + } + + /** + * read by topologytemplateeditor.jsp via ${it.hoverColor} + */ + public String getHoverColor() { + return this.getOtherAttributeWithDefault(VisualAppearanceResource.QNAME_HOVER_COLOR, Defaults.DEFAULT_RT_HOVER_COLOR); + } + + @PUT + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Path("hovercolor") + public Response onPutHoverColor(@FormParam("color") String color) { + this.otherAttributes.put(VisualAppearanceResource.QNAME_HOVER_COLOR, color); + return BackendUtils.persist(this.res); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequiredCapabilityTypeResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequiredCapabilityTypeResource.java new file mode 100644 index 0000000000..c0768352d9 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequiredCapabilityTypeResource.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.requirementtypes; + +import java.util.Collection; +import java.util.SortedSet; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.xml.namespace.QName; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.ids.definitions.CapabilityTypeId; +import org.eclipse.winery.model.tosca.TRequirementType; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; + +import com.sun.jersey.api.NotFoundException; +import com.sun.jersey.api.view.Viewable; + +public class RequiredCapabilityTypeResource { + + private RequirementTypeResource requirementTypeResource; + + + public RequiredCapabilityTypeResource(RequirementTypeResource requirementTypeResource) { + this.requirementTypeResource = requirementTypeResource; + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML() { + return new Viewable("/jsp/entitytypes/requirementtypes/requiredcapabilitytype.jsp", this); + } + + public TRequirementType getRequirementType() { + return this.requirementTypeResource.getRequirementType(); + } + + @PUT + @Consumes(MediaType.TEXT_PLAIN) + public Response putRequiredCapabilityType(String type) { + if (StringUtils.isEmpty(type)) { + return Response.status(Status.BAD_REQUEST).entity("type must not be empty").build(); + } + QName qname = QName.valueOf(type); + CapabilityTypeId id = new CapabilityTypeId(qname); + if (Repository.INSTANCE.exists(id)) { + // everything allright. Store new reference + this.getRequirementType().setRequiredCapabilityType(qname); + return BackendUtils.persist(this.requirementTypeResource); + } else { + throw new NotFoundException("Given QName could not be resolved to an existing capability type"); + } + } + + @DELETE + public Response deleteRequiredCapabilityType() { + this.getRequirementType().setRequiredCapabilityType(null); + return BackendUtils.persist(this.requirementTypeResource); + } + + /** required for jsp **/ + public Collection getAllCapabilityTypes() { + SortedSet allTOSCAComponentIds = Repository.INSTANCE.getAllTOSCAComponentIds(CapabilityTypeId.class); + return BackendUtils.convertTOSCAComponentIdCollectionToQNameCollection(allTOSCAComponentIds); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequirementTypeResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequirementTypeResource.java new file mode 100644 index 0000000000..0f143fb958 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequirementTypeResource.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.requirementtypes; + +import javax.ws.rs.Path; + +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TRequirementType; +import org.eclipse.winery.common.ids.definitions.RequirementTypeId; +import org.eclipse.winery.repository.resources.EntityTypeResource; + +public class RequirementTypeResource extends EntityTypeResource { + + public RequirementTypeResource(RequirementTypeId id) { + super(id); + } + + /** + * Convenience method to avoid casting at the caller's side. + */ + public TRequirementType getRequirementType() { + return (TRequirementType) this.getElement(); + } + + @Override + protected TExtensibleElements createNewElement() { + return new TRequirementType(); + } + + @Path("requiredcapabilitytype/") + public RequiredCapabilityTypeResource getRequiredCapabilityTypeResource() { + return new RequiredCapabilityTypeResource(this); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequirementTypesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequirementTypesResource.java new file mode 100644 index 0000000000..708aed15ec --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/entitytypes/requirementtypes/RequirementTypesResource.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.requirementtypes; + +import org.eclipse.winery.repository.resources.AbstractComponentsResource; + +/** + * Manages all capability types in all available namespaces
+ * The actual implementation is done in the AbstractComponentsResource + */ +public class RequirementTypesResource extends AbstractComponentsResource { + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/ImportsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/ImportsResource.java new file mode 100644 index 0000000000..82ff02e6d7 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/ImportsResource.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.imports; + +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.resources.AbstractComponentsResource; +import org.eclipse.winery.repository.resources.imports.genericimports.GenericImportsResource; +import org.eclipse.winery.repository.resources.imports.xsdimports.XSDImportsResource; + +/** + * The specification does not nest the sequence of import elements in an imports + * container. We introduce such a container to be consistent with the other + * resource naming + */ +public class ImportsResource { + + @Path("{id}/") + public AbstractComponentsResource getXSDsResource(@PathParam("id") String id) { + // once: decoding for browser locations + id = Util.URLdecode(id); + // once again: real URI + id = Util.URLdecode(id); + if (id.equals("http://www.w3.org/2001/XMLSchema")) { + // Models http://www.w3.org/2001/XMLSchema. We do not use xsd instead of the + // encoded namespace, because this induces special cases at many places + return new XSDImportsResource(); + } else { + return new GenericImportsResource(id); + } + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/genericimports/GenericImportResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/genericimports/GenericImportResource.java new file mode 100644 index 0000000000..ddcb4621e0 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/genericimports/GenericImportResource.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.imports.genericimports; + +import java.util.SortedSet; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.ids.definitions.imports.GenericImportId; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TImport; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; + +public class GenericImportResource extends AbstractComponentInstanceResource { + + // The import belonging to this resource + protected final TImport theImport; + + + public GenericImportResource(GenericImportId id) { + super(id); + + boolean needsPersistence = false; + + if (this.getDefinitions().getServiceTemplateOrNodeTypeOrNodeTypeImplementation().isEmpty()) { + // super class loaded an existing definitions + + // we have to manually assign our import right + this.theImport = this.getDefinitions().getImport().get(0); + + // element is not assigned as there are no service templates/... + // we assign the value to be sure that no NPEs occur + this.element = this.theImport; + } else { + // super class created a new import + + // store it locally + this.theImport = (TImport) this.element; + + // undo the side effect of adding it at the wrong place at TDefinitions + this.getDefinitions().getServiceTemplateOrNodeTypeOrNodeTypeImplementation().clear(); + + // add import at the right place + this.getDefinitions().getImport().add(this.theImport); + + // Super class has persisted the definitions + // We have to persist the new variant + needsPersistence = true; + } + + if (this.theImport.getLocation() == null) { + // invalid import -- try to synchronize with storage + + SortedSet containedFiles = Repository.INSTANCE.getContainedFiles(id); + // there is also a .definitions contained + // we are only interested in the non-.definitions + for (RepositoryFileReference ref : containedFiles) { + if (!ref.getFileName().endsWith(".definitions")) { + // associated file found + // set the filename of the import to the found xsd + // TODO: no more validity checks are done currently. In the case of XSD: targetNamespace matches, not more than one xsd + this.theImport.setLocation(ref.getFileName()); + needsPersistence = true; + break; + } + } + } + + if (needsPersistence) { + BackendUtils.persist(this); + } + } + + @Override + protected TExtensibleElements createNewElement() { + throw new IllegalStateException("This should not never happen."); + } + + @Override + protected void copyIdToFields() { + // this.theImport cannot be used as this method is called by the super constructor + ((TImport) this.element).setNamespace(this.id.getNamespace().getDecoded()); + } + + @GET + @Path("{filename}") + public Response getFile(@PathParam("filename") String fileName) { + fileName = Util.URLdecode(fileName); + String location; + if ((location = this.getLocation()) == null) { + return Response.status(Status.NOT_FOUND).build(); + } + if (!location.equals(fileName)) { + return Response.status(Status.NOT_FOUND).build(); + } + RepositoryFileReference ref = new RepositoryFileReference(this.id, location); + return BackendUtils.returnRepoPath(ref, null); + + } + + public String getLocation() { + return this.theImport.getLocation(); + } + + /** + * @return a name suitable for componentnaming.jspf + */ + public String getName() { + if (this.getLocation() == null) { + return this.id.getXmlId().getDecoded(); + } else { + return this.getLocation(); + } + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/genericimports/GenericImportsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/genericimports/GenericImportsResource.java new file mode 100644 index 0000000000..dd74e1bc39 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/genericimports/GenericImportsResource.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.imports.genericimports; + +import org.eclipse.winery.common.ids.definitions.imports.GenericImportId; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceResource; +import org.eclipse.winery.repository.resources.AbstractComponentsResource; + +/** + * Manages a certain kind of imports without special treatments + */ +public class GenericImportsResource extends AbstractComponentsResource { + + private String type; + + + /** + * @param id the (decoded) id, e.g., http://schemas.xmlsoap.org/wsdl/ + */ + public GenericImportsResource(String id) { + this.type = id; + } + + @Override + public AbstractComponentInstanceResource getComponentInstaceResource(String namespace, String id, boolean encoded) { + GenericImportId iId = new GenericImportId(namespace, id, encoded, this.type); + return new GenericImportResource(iId); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/xsdimports/XSDImportResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/xsdimports/XSDImportResource.java new file mode 100644 index 0000000000..44d351cfa2 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/xsdimports/XSDImportResource.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.imports.xsdimports; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.xml.XMLConstants; + +import org.apache.xerces.xs.XSConstants; +import org.apache.xerces.xs.XSModel; +import org.apache.xerces.xs.XSNamedMap; +import org.apache.xerces.xs.XSObject; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.ids.definitions.imports.XSDImportId; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TImport; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources.imports.genericimports.GenericImportResource; +import org.restdoc.annotations.RestDoc; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; + +/** + * Even if we are not a component instance, we use that infrastructure to manage + * imports. Some hacks will be necessary. However, these are less effort than + * doing a clean design + */ +public class XSDImportResource extends GenericImportResource { + + private static final Logger logger = LoggerFactory.getLogger(XSDImportResource.class); + + + public XSDImportResource(XSDImportId id) { + super(id); + } + + @Override + protected TExtensibleElements createNewElement() { + TImport imp = new TImport(); + imp.setImportType(XMLConstants.W3C_XML_SCHEMA_NS_URI); + return imp; + } + + /** + * public required by XSDImportsResource + * + * @return null if XSD file does not exist + */ + public RepositoryFileReference getXSDFileReference() { + String loc = this.getLocation(); + if (loc == null) { + return null; + } + final RepositoryFileReference ref = new RepositoryFileReference(this.id, loc); + return ref; + } + + /** + * @return null if no file is associated + */ + private XSModel getXSModel() { + final RepositoryFileReference ref = this.getXSDFileReference(); + return BackendUtils.getXSModel(ref); + } + + // we need "unchecked", because of the parsing of the cache + @SuppressWarnings("unchecked") + public Collection getAllDefinedLocalNames(short type) { + RepositoryFileReference ref = this.getXSDFileReference(); + if (ref == null) { + return Collections.emptySet(); + } + Date lastUpdate = Repository.INSTANCE.getLastUpdate(ref); + + String cacheFileName = "definedLocalNames " + Integer.toString(type) + ".cache"; + RepositoryFileReference cacheRef = new RepositoryFileReference(this.id, cacheFileName); + boolean cacheNeedsUpdate = true; + if (Repository.INSTANCE.exists(cacheRef)) { + Date lastUpdateCache = Repository.INSTANCE.getLastUpdate(cacheRef); + if (lastUpdate.compareTo(lastUpdateCache) <= 0) { + cacheNeedsUpdate = false; + } + } + + List result; + if (cacheNeedsUpdate) { + + XSModel model = this.getXSModel(); + if (model == null) { + return Collections.emptySet(); + } + XSNamedMap components = model.getComponents(type); + //@SuppressWarnings("unchecked") + int len = components.getLength(); + result = new ArrayList(len); + for (int i = 0; i < len; i++) { + XSObject item = components.item(i); + // if queried for TYPE_DEFINITON, then XSD base types (such as IDREF) are also returned + // We want to return only types defined in the namespace of this resource + if (item.getNamespace().equals(this.id.getNamespace().getDecoded())) { + result.add(item.getName()); + } + } + + String cacheContent = null; + try { + cacheContent = Utils.mapper.writeValueAsString(result); + } catch (JsonProcessingException e) { + XSDImportResource.logger.error("Could not generate cache content", e); + } + try { + Repository.INSTANCE.putContentToFile(cacheRef, cacheContent, MediaType.APPLICATION_JSON_TYPE); + } catch (IOException e) { + XSDImportResource.logger.error("Could not update cache", e); + } + } else { + // read content from cache + // cache should contain most recent information + try (InputStream is = Repository.INSTANCE.newInputStream(cacheRef)) { + result = Utils.mapper.readValue(is, java.util.List.class); + } catch (IOException e) { + XSDImportResource.logger.error("Could not read from cache", e); + result = Collections.emptyList(); + } + } + return result; + } + + public Collection getAllDefinedElementsLocalNames() { + return this.getAllDefinedLocalNames(XSConstants.ELEMENT_DECLARATION); + } + + public Collection getAllDefinedTypesLocalNames() { + return this.getAllDefinedLocalNames(XSConstants.TYPE_DEFINITION); + } + + @GET + @RestDoc(methodDescription = "May be used by the modeler to generate an XML editor based on the XML schema") + // we cannot use "MimeTypes.MIMETYPE_XSD" here as the latter is "text/xml" and org.eclipse.winery.repository.resources.AbstractComponentInstanceResource.getDefinitionsAsResponse() also produces text/xml + @Produces("text/xsd") + public Response getXSD() { + String location; + if ((location = this.getLocation()) == null) { + return Response.status(Status.NOT_FOUND).build(); + } + RepositoryFileReference ref = new RepositoryFileReference(this.id, location); + return BackendUtils.returnRepoPath(ref, null); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/xsdimports/XSDImportsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/xsdimports/XSDImportsResource.java new file mode 100644 index 0000000000..35d0804f3d --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/imports/xsdimports/XSDImportsResource.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.imports.xsdimports; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.definitions.imports.XSDImportId; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources.AbstractComponentsResource; +import org.restdoc.annotations.RestDoc; + +import com.fasterxml.jackson.core.JsonProcessingException; + +/** + * Manages all imports of type XML Schema Definition
+ * The actual implementation is done in the AbstractComponentsResource + * + * FIXME: This class should be generalized to handle ImportId + */ +public class XSDImportsResource extends AbstractComponentsResource { + + @Path("{namespace}/") + @GET + @RestDoc(methodDescription = "Returns all available local names of defined elements in this namespace") + @Produces(MediaType.APPLICATION_JSON) + public String getAllElementLocalNames(@PathParam("namespace") String nsString, @QueryParam(value = "elements") String returnElements, @QueryParam(value = "types") String returnTypes) { + // returnElements is not read as either types or elements may be read + Set allNCNames = this.getAllElementLocalNamesAsSet(nsString, returnTypes != null); + try { + return Utils.mapper.writeValueAsString(allNCNames); + } catch (JsonProcessingException e) { + throw new IllegalStateException(e); + } + } + + /** + * @param nsString the namesapce as String + * @param returnTypes true: return ElementTypes, false: return Elements + */ + private Set getAllElementLocalNamesAsSet(final String nsString, final boolean getTypes) { + Set importsOfNS = this.getImportsOfNS(nsString); + + // TreeSet enables ordering + Set allNCNames = new TreeSet(); + + for (XSDImportId imp : importsOfNS) { + XSDImportResource res = new XSDImportResource(imp); + Collection col; + if (getTypes) { + col = res.getAllDefinedTypesLocalNames(); + } else { + col = res.getAllDefinedElementsLocalNames(); + } + allNCNames.addAll(col); + } + return allNCNames; + } + + /** + * Finds out all imports belonging to the given namespace + * + * @param nsString the namespace to query + */ + private Set getImportsOfNS(final String nsString) { + // FIXME: Currently not supported by the repository, therefore, we filter by hand + Set allImports = Repository.INSTANCE.getAllTOSCAComponentIds(XSDImportId.class); + Namespace ns = new Namespace(nsString, true); + Set importsOfNs = new HashSet(); + for (XSDImportId imp : allImports) { + if (imp.getNamespace().equals(ns)) { + importsOfNs.add(imp); + } + } + return importsOfNs; + } + + /** + * Returns a mapping from localnames to XSD files, containing the defined + * local names for the given namespace + */ + public Map getMapFromLocalNameToXSD(final String nsString, final boolean getTypes) { + Set importsOfNS = this.getImportsOfNS(nsString); + Map result = new HashMap<>(); + for (XSDImportId imp : importsOfNS) { + XSDImportResource res = new XSDImportResource(imp); + Collection col; + if (getTypes) { + col = res.getAllDefinedTypesLocalNames(); + } else { + col = res.getAllDefinedElementsLocalNames(); + } + RepositoryFileReference ref = res.getXSDFileReference(); + for (String localName : col) { + result.put(localName, ref); + } + } + return result; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/InterfaceResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/InterfaceResource.java new file mode 100644 index 0000000000..b7b7c155ce --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/InterfaceResource.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.interfaces; + +import java.util.List; + +import javax.ws.rs.Path; + +import org.eclipse.winery.model.tosca.TInterface; +import org.eclipse.winery.model.tosca.TOperation; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdResource; + +public class InterfaceResource extends EntityWithIdResource { + + private final TInterface iface; + + + public InterfaceResource(IIdDetermination idDetermination, TInterface o, int idx, List list, IPersistable res) { + super(idDetermination, o, idx, list, res); + this.iface = o; + } + + /** + * required by artifacts.jsp + */ + public String getName() { + return this.iface.getName(); + } + + @Path("operations/") + public OperationsResource getOperationsResouce() { + List list = this.o.getOperation(); + return new OperationsResource(list, this.res); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/InterfacesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/InterfacesResource.java new file mode 100644 index 0000000000..4acfbd97cb --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/InterfacesResource.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.interfaces; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.model.tosca.TInterface; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdCollectionResource; +import org.eclipse.winery.repository.resources.entitytypes.TopologyGraphElementEntityTypeResource; +import org.eclipse.winery.repository.resources.entitytypes.relationshiptypes.RelationshipTypeResource; +import org.restdoc.annotations.RestDoc; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; + +public class InterfacesResource extends EntityWithIdCollectionResource { + + private static final Logger logger = LoggerFactory.getLogger(InterfacesResource.class); + + private TopologyGraphElementEntityTypeResource typeResource; + + private String urlPrefix; + + + public InterfacesResource(IPersistable res, List list) { + super(InterfaceResource.class, TInterface.class, list, res); + } + + /** + * @param urlPrefix prefix to be prepended to the URL. + * "source"|"target"|null. E.g., "source" for "sourceinterfaces" + */ + public InterfacesResource(String urlPrefix, List list, IPersistable typeResource) { + super(InterfaceResource.class, TInterface.class, list, typeResource); + this.urlPrefix = urlPrefix; + this.typeResource = (TopologyGraphElementEntityTypeResource) typeResource; + } + + @Override + public Viewable getHTML() { + return new Viewable("/jsp/interfaces/interfaces.jsp", this); + } + + /** + * Implementation base:
+ * {@link org.eclipse.winery.repository.resources.AbstractComponentResource. + * onPost(String)} + * + * @return entity: id of the stored interface + */ + @POST + @RestDoc(methodDescription = "Creates a new interface. Returns conflict if interface already exists") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + public Response onPost(@FormParam("interfaceName") String interfaceName) { + if (StringUtils.isEmpty(interfaceName)) { + return Response.status(Status.BAD_REQUEST).entity("null interfaceName").build(); + } + + TInterface iface = new TInterface(); + iface.setName(interfaceName); + + // check for duplicates + // return "conflict" if interface already exists + if (this.alreadyContains(iface)) { + return Response.status(Status.CONFLICT).build(); + } + + this.list.add(iface); + return BackendUtils.persist(this.res); + } + + /** + * Required by interfaces.jsp + */ + public String getUrlPrefix() { + return this.urlPrefix; + } + + @Override + public String getId(TInterface entity) { + return entity.getName(); + } + + /** + * @return the namespace of the node/relationship type + */ + public String getNamespace() { + return this.typeResource.getId().getNamespace().getDecoded(); + } + + /** + * @return the name of the node/relationship type + */ + public String getName() { + return this.typeResource.getName(); + } + + public String getRelationshipTypeOrNodeTypeURLFragment() { + if (this.typeResource instanceof RelationshipTypeResource) { + return "relationshiptype"; + } else { + return "nodetype"; + } + } + + public String getRelationshipTypeOrNodeType() { + if (this.typeResource instanceof RelationshipTypeResource) { + return "Relationship Type"; + } else { + return "Node Type"; + } + } + + public String getTypeQName() { + String res = this.typeResource.getId().getQName().toString(); + return res; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/OperationResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/OperationResource.java new file mode 100644 index 0000000000..7657e99425 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/OperationResource.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.interfaces; + +import java.util.List; + +import javax.ws.rs.Path; + +import org.eclipse.winery.model.tosca.TInterface; +import org.eclipse.winery.model.tosca.TOperation; +import org.eclipse.winery.model.tosca.TOperation.InputParameters; +import org.eclipse.winery.model.tosca.TOperation.OutputParameters; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OperationResource extends EntityWithIdResource { + + private static final Logger logger = LoggerFactory.getLogger(OperationResource.class); + + + public OperationResource(IIdDetermination idDetermination, TOperation o, int idx, List list, IPersistable res) { + super(idDetermination, o, idx, list, res); + } + + /** + * @return TOperation object for the corresponding object of operationName + * in the operation list contained in the given interface. null if + * interface could not be found in list + */ + public static TOperation getTOperation(String operationName, TInterface iface) { + List operationList = iface.getOperation(); + for (TOperation op : operationList) { + if (op.getName().equals(operationName)) { + return op; + } + } + return null; + } + + @Path("inputparameters/") + public ParametersResource getInputparameters() { + InputParameters inputParameters = this.o.getInputParameters(); + if (inputParameters == null) { + inputParameters = new InputParameters(); + this.o.setInputParameters(inputParameters); + } + return new ParametersResource(inputParameters.getInputParameter(), this.res); + } + + @Path("outputparameters/") + public ParametersResource getOutputparameters() { + OutputParameters outputParameters = this.o.getOutputParameters(); + if (outputParameters == null) { + outputParameters = new OutputParameters(); + this.o.setOutputParameters(outputParameters); + } + return new ParametersResource(outputParameters.getOutputParameter(), this.res); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/OperationsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/OperationsResource.java new file mode 100644 index 0000000000..3e214e4f01 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/OperationsResource.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.interfaces; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.model.tosca.TOperation; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdCollectionResource; +import org.restdoc.annotations.RestDocParam; + +import com.sun.jersey.api.view.Viewable; + +public class OperationsResource extends EntityWithIdCollectionResource { + + public OperationsResource(List list, IPersistable res) { + super(OperationResource.class, TOperation.class, list, res); + } + + @Override + public String getId(TOperation entity) { + return entity.getName(); + } + + @Override + public Viewable getHTML() { + throw new IllegalStateException("Not yet implemented."); + } + + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + public Response createOperation(@FormParam("name") @RestDocParam(description = "used as name and id") String operationName) { + if (StringUtils.isEmpty(operationName)) { + return Response.status(Status.BAD_REQUEST).entity("operationName not provided").build(); + } + + operationName = Util.URLdecode(operationName); + + // TODO: check for duplicates as in instance states + + TOperation operation = new TOperation(); + operation.setName(operationName); + this.list.add(operation); + + return BackendUtils.persist(this.res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/ParameterResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/ParameterResource.java new file mode 100644 index 0000000000..cfac3198c3 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/ParameterResource.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.interfaces; + +import java.util.List; + +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; + +import org.eclipse.winery.model.tosca.TBoolean; +import org.eclipse.winery.model.tosca.TParameter; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdResource; + +public class ParameterResource extends EntityWithIdResource { + + public ParameterResource(IIdDetermination idDetermination, TParameter o, int idx, List list, IPersistable res) { + super(idDetermination, o, idx, list, res); + } + + @GET + @Path("type") + public String getType() { + return this.o.getType(); + } + + @PUT + @Path("type") + public Response putType(@FormParam(value = "type") String type) { + this.o.setType(type); + return BackendUtils.persist(this.res); + } + + @GET + @Path("required") + public String getRequired() { + return this.o.getRequired().toString(); + } + + @PUT + @Path("required") + public Response putRequired(@FormParam(value = "required") String required) { + TBoolean tb = TBoolean.valueOf(required); + this.o.setRequired(tb); + return BackendUtils.persist(this.res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/ParametersResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/ParametersResource.java new file mode 100644 index 0000000000..c3afcbcb43 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/interfaces/ParametersResource.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.interfaces; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.model.tosca.TBoolean; +import org.eclipse.winery.model.tosca.TParameter; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdCollectionResource; +import org.restdoc.annotations.RestDocParam; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; + +public class ParametersResource extends EntityWithIdCollectionResource { + + private static final Logger logger = LoggerFactory.getLogger(ParametersResource.class); + + + public ParametersResource(List parameters, IPersistable typeResource) { + super(ParameterResource.class, TParameter.class, parameters, typeResource); + } + + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + // @formatter:off + public Response createParamter( + @FormParam("name") String name, + @FormParam("type") String type, + @FormParam("required") @RestDocParam(description="type tYesNo, not Boolean. For convenience, on/off is also supported. In case this parameter is not provided, 'off' is assumed. This is in contrast to the specification, but it eases implementing the UI") String required) { + // @formatter:on + if (StringUtils.isEmpty(name)) { + return Response.status(Status.BAD_REQUEST).entity("name must not be null").build(); + } + if (StringUtils.isEmpty(type)) { + return Response.status(Status.BAD_REQUEST).entity("type must not be null").build(); + } + + TParameter param = new TParameter(); + param.setName(name); + param.setType(type); + TBoolean tb; + if (required == null) { + // The specification states that the default value is "yes" + // We assume "no", because Chrome does not send the checkbox data if a checkbox is not checked + tb = TBoolean.NO; + } else { + if (required.equalsIgnoreCase("on")) { + tb = TBoolean.YES; + } else if (required.equalsIgnoreCase("off")) { + tb = TBoolean.NO; + } else { + try { + tb = TBoolean.valueOf(required); + } catch (java.lang.IllegalArgumentException e) { + return Response.status(Status.BAD_REQUEST).entity("Wrong format of required").build(); + } + } + } + param.setRequired(tb); + + this.list.add(param); + + return BackendUtils.persist(this.res); + } + + @Override + public String getId(TParameter entity) { + return entity.getName(); + } + + @Override + public Viewable getHTML() { + throw new IllegalStateException("Not yet implemented."); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/package-info.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/package-info.java new file mode 100644 index 0000000000..ea94a213c1 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/package-info.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +/** + * This package contains the REST resources + * + * Mostly, they produces Viewables, where a JSP and the current resource is + * passed As the JSP itself handles plain Java objects and not Responses, the + * resources have also methods returning POJOs. This might be ugly design, but + * was quick to implement. + * + * The package structure is mirrored in src/main/webapp/jsp to ease finding the + * JSPs belonging to a resource. + * + * The resources are not in line with the resource model of the TOSCA + * container. Especially, we do not employ HATEOAS here. + */ +package org.eclipse.winery.repository.resources; + diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/ServiceTemplateResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/ServiceTemplateResource.java new file mode 100644 index 0000000000..6a249df0e8 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/ServiceTemplateResource.java @@ -0,0 +1,263 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.xml.namespace.QName; + +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.common.ids.elements.PlanId; +import org.eclipse.winery.common.ids.elements.PlansId; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions; +import org.eclipse.winery.model.tosca.TExtensibleElements; +import org.eclipse.winery.model.tosca.TPlan; +import org.eclipse.winery.model.tosca.TPlan.PlanModelReference; +import org.eclipse.winery.model.tosca.TPlans; +import org.eclipse.winery.model.tosca.TServiceTemplate; +import org.eclipse.winery.model.tosca.TTopologyTemplate; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources.AbstractComponentInstanceWithReferencesResource; +import org.eclipse.winery.repository.resources.IHasName; +import org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.BoundaryDefinitionsResource; +import org.eclipse.winery.repository.resources.servicetemplates.plans.PlansResource; +import org.eclipse.winery.repository.resources.servicetemplates.selfserviceportal.SelfServicePortalResource; +import org.eclipse.winery.repository.resources.servicetemplates.topologytemplates.TopologyTemplateResource; +import org.restdoc.annotations.RestDoc; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ServiceTemplateResource extends AbstractComponentInstanceWithReferencesResource implements IHasName { + + private static final Logger logger = LoggerFactory.getLogger(ServiceTemplateResource.class); + + + public ServiceTemplateResource(ServiceTemplateId id) { + super(id); + } + + /** sub-resources **/ + + @Path("topologytemplate/") + public TopologyTemplateResource getTopologyTemplateResource() { + if (this.getServiceTemplate().getTopologyTemplate() == null) { + // the main service template resource exists + // default topology template: empty template + // This eases the JSPs etc. and is valid as a non-existant topology template is equal to an empty one + this.getServiceTemplate().setTopologyTemplate(new TTopologyTemplate()); + } + return new TopologyTemplateResource(this); + } + + @Path("plans/") + public PlansResource getPlansResource() { + TPlans plans = this.getServiceTemplate().getPlans(); + if (plans == null) { + plans = new TPlans(); + this.getServiceTemplate().setPlans(plans); + } + return new PlansResource(plans.getPlan(), this); + } + + @Path("selfserviceportal/") + public SelfServicePortalResource getSelfServicePortalResource() { + return new SelfServicePortalResource(this); + } + + @Path("boundarydefinitions/") + public BoundaryDefinitionsResource getBoundaryDefinitionsResource() { + TBoundaryDefinitions boundaryDefinitions = this.getServiceTemplate().getBoundaryDefinitions(); + if (boundaryDefinitions == null) { + boundaryDefinitions = new TBoundaryDefinitions(); + this.getServiceTemplate().setBoundaryDefinitions(boundaryDefinitions); + } + return new BoundaryDefinitionsResource(this, boundaryDefinitions); + } + + @Override + public String getName() { + String name = this.getServiceTemplate().getName(); + if (name == null) { + // place default + name = this.getId().getXmlId().getDecoded(); + } + return name; + } + + @Override + public Response setName(String name) { + this.getServiceTemplate().setName(name); + return BackendUtils.persist(this); + } + + // @formatter:off + @GET + @RestDoc(methodDescription="Returns the associated node type, which can be substituted by this service template.
" + + "@return a QName of the form {namespace}localName is returned.") + @Path("substitutableNodeType") + @Produces(MediaType.TEXT_PLAIN) + // @formatter:on + public Response getSubstitutableNodeTypeAsResponse() { + QName qname = this.getServiceTemplate().getSubstitutableNodeType(); + if (qname == null) { + return Response.status(Status.NOT_FOUND).build(); + } else { + return Response.ok(qname.toString()).build(); + } + } + + /** + * + * @return null if there is no substitutable node type + */ + public QName getSubstitutableNodeType() { + return this.getServiceTemplate().getSubstitutableNodeType(); + } + + @DELETE + @RestDoc(methodDescription = "Removes the association to substitutable node type") + @Path("substitutableNodeType") + public Response deleteSubstitutableNodeType() { + this.getServiceTemplate().setSubstitutableNodeType(null); + BackendUtils.persist(this); + return Response.noContent().build(); + } + + public TServiceTemplate getServiceTemplate() { + return (TServiceTemplate) this.getElement(); + } + + @Override + protected TExtensibleElements createNewElement() { + return new TServiceTemplate(); + } + + @Override + protected void copyIdToFields() { + this.getServiceTemplate().setId(this.getId().getXmlId().getDecoded()); + this.getServiceTemplate().setTargetNamespace(this.getId().getNamespace().getDecoded()); + } + + /** + * Synchronizes the known plans with the data in the XML. When there is a + * stored file, but no known entry in the XML, we guess "BPEL" as language + * and "build plan" as type. + * + * @throws IOException + */ + @Override + public void synchronizeReferences() { + // locally stored plans + TPlans plans = this.getServiceTemplate().getPlans(); + + // plans stored in the repository + PlansId plansContainerId = new PlansId((ServiceTemplateId) this.getId()); + SortedSet nestedPlans = Repository.INSTANCE.getNestedIds(plansContainerId, PlanId.class); + + Set plansToAdd = new HashSet(); + plansToAdd.addAll(nestedPlans); + + if (nestedPlans.isEmpty()) { + if (plans == null) { + // data on the file system equals the data -> no plans + return; + } else { + // we have to check for equality later + } + } + + if (plans == null) { + plans = new TPlans(); + this.getServiceTemplate().setPlans(plans); + } + + for (Iterator iterator = plans.getPlan().iterator(); iterator.hasNext();) { + TPlan plan = iterator.next(); + if (plan.getPlanModel() != null) { + // in case, a plan is directly contained in a Model element, we do not need to do anything + continue; + } + PlanModelReference planModelReference = plan.getPlanModelReference(); + if ((planModelReference = plan.getPlanModelReference()) != null) { + String ref = planModelReference.getReference(); + if ((ref == null) || ref.startsWith("../")) { + // references to local plans start with "../" + // special case (due to errors in the importer): empty PlanModelReference field + if (plan.getId() == null) { + // invalid plan entry: no id. + // we remove the entry + iterator.remove(); + continue; + } + PlanId planId = new PlanId(plansContainerId, new XMLId(plan.getId(), false)); + if (nestedPlans.contains(planId)) { + // everything allright + // we do NOT need to add the plan on the HDD to the XML + plansToAdd.remove(planId); + } else { + // no local storage for the plan, we remove it from the XML + iterator.remove(); + } + } + } + } + + // add all plans locally stored, but not contained in the XML, as plan element to the plans of the service template. + List thePlans = plans.getPlan(); + for (PlanId planId : plansToAdd) { + SortedSet files = Repository.INSTANCE.getContainedFiles(planId); + if (files.size() != 1) { + throw new IllegalStateException("Currently, only one file per plan is supported."); + } + RepositoryFileReference ref = files.iterator().next(); + + TPlan plan = new TPlan(); + plan.setId(planId.getXmlId().getDecoded()); + plan.setName(planId.getXmlId().getDecoded()); + plan.setPlanType(org.eclipse.winery.repository.Constants.TOSCA_PLANTYPE_BUILD_PLAN); + plan.setPlanLanguage(org.eclipse.winery.common.constants.Namespaces.URI_BPEL20_EXECUTABLE); + + // create a PlanModelReferenceElement pointing to that file + String path = Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(ref)); + // path is relative from the definitions element + path = "../" + path; + PlanModelReference pref = new PlanModelReference(); + pref.setReference(path); + + plan.setPlanModelReference(pref); + thePlans.add(plan); + } + + try { + this.persist(); + } catch (IOException e) { + throw new IllegalStateException("Could not persist resource", e); + } + return; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/ServiceTemplatesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/ServiceTemplatesResource.java new file mode 100644 index 0000000000..d429cdb62c --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/ServiceTemplatesResource.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates; + +import org.eclipse.winery.repository.resources.AbstractComponentsResource; + +public class ServiceTemplatesResource extends AbstractComponentsResource { + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/BoundaryDefinitionsJSPData.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/BoundaryDefinitionsJSPData.java new file mode 100644 index 0000000000..0d4b141cbf --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/BoundaryDefinitionsJSPData.java @@ -0,0 +1,113 @@ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.SortedSet; + +import javax.xml.namespace.QName; + +import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.taglibs.standard.functions.Functions; +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.common.ids.definitions.PolicyTypeId; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions.Properties; +import org.eclipse.winery.model.tosca.TPlan; +import org.eclipse.winery.model.tosca.TPlans; +import org.eclipse.winery.model.tosca.TServiceTemplate; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.datatypes.TypeWithShortName; +import org.eclipse.winery.repository.datatypes.select2.Select2DataItem; +import org.eclipse.winery.repository.resources.admin.types.ConstraintTypesManager; + +public class BoundaryDefinitionsJSPData { + + private final TServiceTemplate ste; + private final TBoundaryDefinitions defs; + private URI baseURI; + + + /** + * + * @param ste the service template of the boundary definitions. Required to + * get a list of all plans + * @param baseURI the base URI of the service. Requried for rendering the + * topology template for the selections + */ + public BoundaryDefinitionsJSPData(TServiceTemplate ste, URI baseURI) { + this.ste = ste; + this.defs = ste.getBoundaryDefinitions(); + this.baseURI = baseURI; + } + + private String getDefinedProperties() { + Properties p = ModelUtilities.getProperties(this.defs); + Object o = p.getAny(); + if (o == null) { + // nothing stored -> return empty string + return ""; + } else { + // something stored --> return that + return Utils.getXMLAsString(p.getAny()); + } + } + + /** + * Helper method to return an initialized properties object only containing + * the user-defined properties. The TOSCA properties-element is not returned + * as the TOSCA XSD allows a single element only + */ + public String getDefinedPropertiesAsEscapedHTML() { + String s = this.getDefinedProperties(); + s = StringEscapeUtils.escapeHtml4(s); + return s; + } + + public String getDefinedPropertiesAsJSONString() { + String s = this.getDefinedProperties(); + s = StringEscapeUtils.escapeEcmaScript(s); + return s; + } + + public TBoundaryDefinitions getDefs() { + return this.defs; + } + + public String getBoundaryDefinitionsAsXMLStringEncoded() { + String res = Utils.getXMLAsString(this.defs); + return Functions.escapeXml(res); + } + + public Collection getConstraintTypes() { + return ConstraintTypesManager.INSTANCE.getTypes(); + } + + public Collection getAllPolicyTypes() { + SortedSet allTOSCAComponentIds = Repository.INSTANCE.getAllTOSCAComponentIds(PolicyTypeId.class); + return BackendUtils.convertTOSCAComponentIdCollectionToQNameCollection(allTOSCAComponentIds); + } + + public String getRepositoryURL() { + return this.baseURI.toString(); + } + + public List getlistOfAllPlans() { + TPlans plans = this.ste.getPlans(); + if (plans == null) { + return null; + } else { + List res = new ArrayList<>(plans.getPlan().size()); + for (TPlan plan : plans.getPlan()) { + String id = plan.getId(); + String name = ModelUtilities.getNameWithIdFallBack(plan); + Select2DataItem di = new Select2DataItem(id, name); + res.add(di); + } + return res; + } + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/BoundaryDefinitionsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/BoundaryDefinitionsResource.java new file mode 100644 index 0000000000..58dfbe93c1 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/BoundaryDefinitionsResource.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions.Capabilities; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions.Interfaces; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions.Policies; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions.Properties; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions.Properties.PropertyMappings; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions.Requirements; +import org.eclipse.winery.model.tosca.TCapabilityRef; +import org.eclipse.winery.model.tosca.TRequirementRef; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; +import org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.interfaces.InterfacesResource; +import org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.policies.PoliciesResource; +import org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.reqscaps.CapabilitiesResource; +import org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.reqscaps.RequirementsResource; +import org.restdoc.annotations.RestDoc; +import org.restdoc.annotations.RestDocParam; +import org.w3c.dom.Document; + +import com.sun.jersey.api.view.Viewable; + +public class BoundaryDefinitionsResource { + + private final ServiceTemplateResource serviceTemplateResource; + private final TBoundaryDefinitions boundaryDefinitions; + + + public BoundaryDefinitionsResource(ServiceTemplateResource serviceTemplateResource, TBoundaryDefinitions boundaryDefinitions) { + this.serviceTemplateResource = serviceTemplateResource; + this.boundaryDefinitions = boundaryDefinitions; + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML(@Context UriInfo uriInfo) { + return new Viewable("/jsp/servicetemplates/boundarydefinitions/boundarydefinitions.jsp", new BoundaryDefinitionsJSPData(this.serviceTemplateResource.getServiceTemplate(), uriInfo.getBaseUri())); + } + + @PUT + @RestDoc(methodDescription = "Replaces the boundary definitions by the information given in the XML") + @Consumes(MediaType.TEXT_XML) + public Response setModel(TBoundaryDefinitions boundaryDefinitions) { + this.serviceTemplateResource.getServiceTemplate().setBoundaryDefinitions(boundaryDefinitions); + return BackendUtils.persist(this.serviceTemplateResource); + } + + @Path("properties/") + @PUT + @Consumes(MediaType.TEXT_XML) + @RestDoc(resourceDescription = "Models the user-defined properties. The property mappings go into a separate resource propertymappings.") + public Response putProperties(@RestDocParam(description = "Stored properties. The XSD allows a single element only. Therefore, we go for the contained element") Document doc) { + org.eclipse.winery.model.tosca.TBoundaryDefinitions.Properties properties = ModelUtilities.getProperties(this.boundaryDefinitions); + properties.setAny(doc.getDocumentElement()); + return BackendUtils.persist(this.serviceTemplateResource); + } + + @Path("requirements/") + public RequirementsResource getRequiremensResource() { + Requirements requirements = this.boundaryDefinitions.getRequirements(); + if (requirements == null) { + requirements = new Requirements(); + this.boundaryDefinitions.setRequirements(requirements); + } + List refs = requirements.getRequirement(); + return new RequirementsResource(this.serviceTemplateResource, refs); + } + + @Path("capabilities/") + public CapabilitiesResource getCapabilitiesResource() { + Capabilities caps = this.boundaryDefinitions.getCapabilities(); + if (caps == null) { + caps = new Capabilities(); + this.boundaryDefinitions.setCapabilities(caps); + } + List refs = caps.getCapability(); + return new CapabilitiesResource(this.serviceTemplateResource, refs); + } + + @Path("policies/") + public PoliciesResource getPoliciesResource() { + Policies policies = this.boundaryDefinitions.getPolicies(); + if (policies == null) { + policies = new Policies(); + this.boundaryDefinitions.setPolicies(policies); + } + return new PoliciesResource(policies.getPolicy(), this.serviceTemplateResource); + } + + /** + * This path is below "boundary definitions" to ease implementation If it + * was modeled following the XSD, it would have been nested below + * "properties". We did not do that + */ + @Path("propertymappings/") + public PropertyMappingsResource getPropertyMappings() { + Properties properties = this.boundaryDefinitions.getProperties(); + if (properties == null) { + properties = new Properties(); + this.boundaryDefinitions.setProperties(properties); + } + PropertyMappings propertyMappings = properties.getPropertyMappings(); + if (propertyMappings == null) { + propertyMappings = new PropertyMappings(); + properties.setPropertyMappings(propertyMappings); + } + return new PropertyMappingsResource(propertyMappings, this.serviceTemplateResource); + } + + @Path("interfaces/") + public InterfacesResource getInterfacesResource() { + Interfaces interfaces = this.boundaryDefinitions.getInterfaces(); + if (interfaces == null) { + interfaces = new Interfaces(); + this.boundaryDefinitions.setInterfaces(interfaces); + } + return new InterfacesResource(interfaces.getInterface(), this.serviceTemplateResource); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/PropertyMappingsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/PropertyMappingsResource.java new file mode 100644 index 0000000000..a6872e0e82 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/PropertyMappingsResource.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2013-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions; + +import java.util.Iterator; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.model.tosca.TBoundaryDefinitions.Properties.PropertyMappings; +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.model.tosca.TPropertyMapping; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; +import org.restdoc.annotations.RestDoc; + +public class PropertyMappingsResource { + + private final PropertyMappings propertyMappings; + private final ServiceTemplateResource res; + + + public PropertyMappingsResource(PropertyMappings propertyMappings, ServiceTemplateResource res) { + this.propertyMappings = propertyMappings; + this.res = res; + } + + @Path("{serviceTemplatePropertyRef}") + @DELETE + public Response onDelete(@PathParam("serviceTemplatePropertyRef") String serviceTemplatePropertyRef) { + serviceTemplatePropertyRef = Util.URLdecode(serviceTemplatePropertyRef); + Iterator iterator = this.propertyMappings.getPropertyMapping().iterator(); + while (iterator.hasNext()) { + TPropertyMapping propertyMapping = iterator.next(); + if (propertyMapping.getServiceTemplatePropertyRef().equals(serviceTemplatePropertyRef)) { + iterator.remove(); + return BackendUtils.persist(this.res); + } + } + // if the property mapping was not found, we reach this point + // otherwise "iterator.remove()" has called and the resource persisted + return Response.status(Status.NOT_FOUND).build(); + } + + private void updatePropertyMapping(TPropertyMapping propertyMapping, String serviceTemplatePropertyRef, TEntityTemplate template, String targetPropertyRef) { + propertyMapping.setServiceTemplatePropertyRef(serviceTemplatePropertyRef); + propertyMapping.setTargetObjectRef(template); + propertyMapping.setTargetPropertyRef(targetPropertyRef); + } + + @RestDoc(methodDescription = "Creates or updates a property mapping with the given fields") + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + // @formatter:off + public Response onPost( + @FormParam("serviceTemplatePropertyRef") String serviceTemplatePropertyRef, + @FormParam("targetObjectRef") String targetObjectRef, + @FormParam("targetPropertyRef") String targetPropertyRef + ) { + // @formatter:on + if (StringUtils.isEmpty(serviceTemplatePropertyRef)) { + return Response.status(Status.BAD_REQUEST).entity("serviceTemplatePropertyRef must not be empty").build(); + } + if (StringUtils.isEmpty(targetObjectRef)) { + return Response.status(Status.BAD_REQUEST).entity("targetObjectRef must not be empty").build(); + } + if (StringUtils.isEmpty(targetPropertyRef)) { + return Response.status(Status.BAD_REQUEST).entity("targetPropertyRef must not be empty").build(); + } + + TEntityTemplate template = ModelUtilities.findNodeTemplateOrRequirementOfNodeTemplateOrCapabilityOfNodeTemplateOrRelationshipTemplate(this.res.getServiceTemplate().getTopologyTemplate(), targetObjectRef); + if (template == null) { + return Response.status(Status.BAD_REQUEST).entity("targetObjectRef " + targetObjectRef + " could not be resolved.").build(); + } + + // replace propertyMapping if it exists + Iterator iterator = this.propertyMappings.getPropertyMapping().iterator(); + while (iterator.hasNext()) { + TPropertyMapping propertyMapping = iterator.next(); + if (propertyMapping.getServiceTemplatePropertyRef().equals(serviceTemplatePropertyRef)) { + // we found a property with the same mapping + // just update it ... + this.updatePropertyMapping(propertyMapping, serviceTemplatePropertyRef, template, targetPropertyRef); + // ... and finish processing + return BackendUtils.persist(this.res); + } + } + + // the property mapping didn't exist, + // we create a new one + TPropertyMapping newPropertyMapping = new TPropertyMapping(); + this.updatePropertyMapping(newPropertyMapping, serviceTemplatePropertyRef, template, targetPropertyRef); + return BackendUtils.persist(this.res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedInterfaceResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedInterfaceResource.java new file mode 100644 index 0000000000..b69e802642 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedInterfaceResource.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.interfaces; + +import java.util.List; + +import javax.ws.rs.Path; + +import org.eclipse.winery.model.tosca.TExportedInterface; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdResource; + +public class ExportedInterfaceResource extends EntityWithIdResource { + + public ExportedInterfaceResource(IIdDetermination idDetermination, TExportedInterface o, int idx, List list, IPersistable res) { + super(idDetermination, o, idx, list, res); + } + + @Path("exportedoperations/") + public ExportedOperationsResource getExportedOperationsResource() { + return new ExportedOperationsResource(this.o.getOperation(), this.res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedOperationResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedOperationResource.java new file mode 100644 index 0000000000..dd10751202 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedOperationResource.java @@ -0,0 +1,249 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.interfaces; + +import java.io.StringWriter; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.model.tosca.TExportedOperation; +import org.eclipse.winery.model.tosca.TExportedOperation.NodeOperation; +import org.eclipse.winery.model.tosca.TExportedOperation.Plan; +import org.eclipse.winery.model.tosca.TExportedOperation.RelationshipOperation; +import org.eclipse.winery.model.tosca.TNodeTemplate; +import org.eclipse.winery.model.tosca.TPlan; +import org.eclipse.winery.model.tosca.TRelationshipTemplate; +import org.eclipse.winery.model.tosca.TServiceTemplate; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdResource; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; + +public class ExportedOperationResource extends EntityWithIdResource { + + private static final Logger logger = LoggerFactory.getLogger(ExportedOperationResource.class); + + + public ExportedOperationResource(IIdDetermination idDetermination, TExportedOperation o, int idx, List list, IPersistable res) { + super(idDetermination, o, idx, list, res); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public String getJSONRepresentation() { + JsonFactory jsonFactory = new JsonFactory(); + StringWriter sw = new StringWriter(); + try { + JsonGenerator jg = jsonFactory.createGenerator(sw); + jg.writeStartObject(); + String type = this.getType(); + jg.writeStringField("type", type); + jg.writeStringField("ref", this.getReference()); + if ((type != null) && (!type.equals("Plan"))) { + jg.writeStringField("interfacename", this.getInterfaceName()); + jg.writeStringField("operationname", this.getOperationName()); + } + jg.writeEndObject(); + jg.close(); + } catch (Exception e) { + ExportedOperationResource.logger.error(e.getMessage(), e); + throw new WebApplicationException(Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build()); + } + String res = sw.toString(); + return res; + } + + /** + * + * @return "NodeOperation" | "RelationshipOperation" | "Plan" | null. null + * is returned if no type is set + */ + @Path("type") + @GET + public String getType() { + if (this.o.getNodeOperation() != null) { + return "NodeOperation"; + } else if (this.o.getRelationshipOperation() != null) { + return "RelationshipOperation"; + } else if (this.o.getPlan() != null) { + return "Plan"; + } else { + return null; + } + } + + @Path("type") + @PUT + public Response setType(String type) { + switch (type) { + case "NodeOperation": + if (this.o.getNodeOperation() == null) { + // only do something, if the type is really changed + this.o.setRelationshipOperation(null); + this.o.setPlan(null); + NodeOperation no = new NodeOperation(); + this.o.setNodeOperation(no); + } + break; + case "RelationshipOperation": + if (this.o.getRelationshipOperation() == null) { + // only do something, if the type is really changed + this.o.setNodeOperation(null); + this.o.setPlan(null); + RelationshipOperation ro = new RelationshipOperation(); + this.o.setRelationshipOperation(ro); + } + break; + case "Plan": + if (this.o.getPlan() == null) { + // only do something, if the type is really changed + this.o.setNodeOperation(null); + this.o.setRelationshipOperation(null); + Plan plan = new Plan(); + this.o.setPlan(plan); + } + break; + default: + return Response.status(Status.BAD_REQUEST).entity("Unknown type " + type).build(); + } + return BackendUtils.persist(this.res); + } + + /** + * @return null if no reference is set + */ + @Path("ref") + @GET + public String getReference() { + if (this.o.getNodeOperation() != null) { + TNodeTemplate nt = (TNodeTemplate) this.o.getNodeOperation().getNodeRef(); + if (nt == null) { + return null; + } + return nt.getId(); + } else if (this.o.getRelationshipOperation() != null) { + TRelationshipTemplate rt = (TRelationshipTemplate) this.o.getRelationshipOperation().getRelationshipRef(); + if (rt == null) { + return null; + } + return rt.getId(); + } else if (this.o.getPlan() != null) { + TPlan plan = (TPlan) this.o.getPlan().getPlanRef(); + if (plan == null) { + return null; + } + return plan.getId(); + } else { + // no type set -> no reference can be returned + return null; + } + } + + @Path("ref") + @PUT + public Response setReference(String ref) { + TServiceTemplate ste = ((ServiceTemplateResource) this.res).getServiceTemplate(); + + // we assume that a correctly set type also means that getX (getNodeOperation, ...) returns non null + switch (this.getType()) { + case "NodeOperation": + TNodeTemplate nodeTemplate = ModelUtilities.resolveNodeTemplate(ste, ref); + this.o.getNodeOperation().setNodeRef(nodeTemplate); + break; + case "RelationshipOperation": + TRelationshipTemplate relationshipTemplate = ModelUtilities.resolveRelationshipTemplate(ste, ref); + this.o.getRelationshipOperation().setRelationshipRef(relationshipTemplate); + break; + case "Plan": + TPlan plan = ModelUtilities.resolvePlan(ste, ref); + this.o.getPlan().setPlanRef(plan); + break; + default: + return Response.status(Status.INTERNAL_SERVER_ERROR).entity("Unknown type " + this.getType()).build(); + } + return BackendUtils.persist(this.res); + } + + @Path("interfacename") + @GET + public String getInterfaceName() { + if (this.o.getNodeOperation() != null) { + return this.o.getNodeOperation().getInterfaceName(); + } else if (this.o.getRelationshipOperation() != null) { + return this.o.getRelationshipOperation().getInterfaceName(); + } else if (this.o.getPlan() != null) { + throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("A plan does not carry an interface").build()); + } else { + throw new WebApplicationException(Response.status(Status.INTERNAL_SERVER_ERROR).entity("Unsupported state of ExportedOperation").build()); + } + } + + @Path("interfacename") + @PUT + public Response setInterfaceName(String interfacename) { + if (this.o.getNodeOperation() != null) { + this.o.getNodeOperation().setInterfaceName(interfacename); + } else if (this.o.getRelationshipOperation() != null) { + this.o.getRelationshipOperation().setInterfaceName(interfacename); + } else if (this.o.getPlan() != null) { + throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("A plan does not carry an interface").build()); + } else { + throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("No type set").build()); + } + return BackendUtils.persist(this.res); + } + + @Path("operationname") + @GET + public String getOperationName() { + if (this.o.getNodeOperation() != null) { + return this.o.getNodeOperation().getOperationName(); + } else if (this.o.getRelationshipOperation() != null) { + return this.o.getRelationshipOperation().getOperationName(); + } else if (this.o.getPlan() != null) { + throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("A plan does not carry an operation").build()); + } else { + throw new WebApplicationException(Response.status(Status.INTERNAL_SERVER_ERROR).entity("Unsupported state of ExportedOperation").build()); + } + } + + @Path("operationname") + @PUT + public Response setOperationName(String name) { + if (this.o.getNodeOperation() != null) { + this.o.getNodeOperation().setOperationName(name); + } else if (this.o.getRelationshipOperation() != null) { + this.o.getRelationshipOperation().setOperationName(name); + } else if (this.o.getPlan() != null) { + throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("A plan does not carry an operation").build()); + } else { + throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("No type set").build()); + } + return BackendUtils.persist(this.res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedOperationsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedOperationsResource.java new file mode 100644 index 0000000000..d8788fd8bf --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/ExportedOperationsResource.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.interfaces; + +import java.util.List; + +import org.eclipse.winery.model.tosca.TExportedOperation; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdCollectionResource; + +import com.sun.jersey.api.view.Viewable; + +public class ExportedOperationsResource extends EntityWithIdCollectionResource { + + public ExportedOperationsResource(List list, IPersistable res) { + super(ExportedOperationResource.class, TExportedOperation.class, list, res); + } + + @Override + public String getId(TExportedOperation entity) { + return entity.getName(); + } + + @Override + public Viewable getHTML() { + throw new IllegalStateException("No implementation required: boundarydefinitions.jsp contains all required html."); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/InterfacesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/InterfacesResource.java new file mode 100644 index 0000000000..301f45749f --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/InterfacesResource.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.interfaces; + +import java.util.List; + +import org.eclipse.winery.model.tosca.TExportedInterface; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdCollectionResource; + +import com.sun.jersey.api.view.Viewable; + +public class InterfacesResource extends EntityWithIdCollectionResource { + + public InterfacesResource(List list, IPersistable res) { + super(ExportedInterfaceResource.class, TExportedInterface.class, list, res); + } + + @Override + public String getId(TExportedInterface entity) { + return entity.getName(); + } + + @Override + public Viewable getHTML() { + throw new IllegalStateException("No implementation required: boundarydefinitions.jsp contains all required html."); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/package-info.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/package-info.java new file mode 100644 index 0000000000..6a342ea5eb --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/interfaces/package-info.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ + +/** + * This package models exported interfaces nested in a boundary definitions. + */ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.interfaces; \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/PoliciesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/PoliciesResource.java new file mode 100644 index 0000000000..b18341f5cf --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/PoliciesResource.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.policies; + +import java.util.List; + +import javax.ws.rs.PUT; +import javax.ws.rs.core.Response; + +import org.eclipse.winery.model.tosca.TPolicy; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdCollectionResource; + +import com.sun.jersey.api.view.Viewable; + +public class PoliciesResource extends EntityWithoutIdCollectionResource { + + public PoliciesResource(List list, IPersistable res) { + super(PolicyResource.class, TPolicy.class, list, res); + } + + @Override + public Viewable getHTML() { + throw new IllegalStateException("Not required: boundarydefinitions.jsp also includes the content of the Policy tab."); + } + + @PUT + public Response replaceAll(List newList) { + this.list.clear(); + for (TPolicy policy : newList) { + this.list.add(policy); + } + return BackendUtils.persist(this.res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/PolicyResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/PolicyResource.java new file mode 100644 index 0000000000..08fbd8d541 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/PolicyResource.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.policies; + +import java.util.List; + +import org.eclipse.winery.model.tosca.TPolicy; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdResource; + +public class PolicyResource extends EntityWithoutIdResource { + + public PolicyResource(TPolicy o, int idx, List list, IPersistable res) { + super(o, idx, list, res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/package-info.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/package-info.java new file mode 100644 index 0000000000..45bc0c7122 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/policies/package-info.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ + +/** + * This package models policies nested in a boundary definitions. It could be resued for the topology modeler, but currently, this is not necessary. + */ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.policies; \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/CapabilitiesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/CapabilitiesResource.java new file mode 100644 index 0000000000..80f2640a79 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/CapabilitiesResource.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.reqscaps; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.model.tosca.TCapability; +import org.eclipse.winery.model.tosca.TCapabilityRef; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.CollectionsHelper; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdCollectionResource; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; + +import com.sun.jersey.api.view.Viewable; + +/** + * This class is an adaption from + * {@link org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.reqscaps.RequirementsResource} + */ +public class CapabilitiesResource extends EntityWithoutIdCollectionResource { + + public CapabilitiesResource(IPersistable res, List refs) { + super(CapabilityResource.class, TCapabilityRef.class, refs, res); + } + + @Override + public Viewable getHTML() { + throw new IllegalStateException("Not yet required: boundarydefinitions.jsp renders all tab content."); + } + + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public Response addNewElement(@FormParam("name") String name, @FormParam("ref") String reference) { + // Implementation adapted from super addNewElement + + if (reference == null) { + return Response.status(Status.BAD_REQUEST).entity("A reference has to be provided").build(); + } + + TCapabilityRef ref = new TCapabilityRef(); + ref.setName(name); // may also be null + + // The XML model fordces us to put a reference to the object and not just the string + ServiceTemplateResource rs = (ServiceTemplateResource) this.res; + TCapability resolved = ModelUtilities.resolveCapability(rs.getServiceTemplate(), reference); + // In case nothing was found: report back to the user + if (resolved == null) { + return Response.status(Status.BAD_REQUEST).entity("Reference could not be resolved").build(); + } + + ref.setRef(resolved); + + // "this.alreadyContains(ref)" cannot be called as this leads to a mappable exception: The data does not contain an id where the given ref attribute may point to + + this.list.add(ref); + return CollectionsHelper.persist(this.res, this, ref); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/CapabilityResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/CapabilityResource.java new file mode 100644 index 0000000000..7cb7b49888 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/CapabilityResource.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.reqscaps; + +import java.util.List; + +import org.eclipse.winery.model.tosca.TCapabilityRef; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdResource; + +public class CapabilityResource extends EntityWithoutIdResource { + + public CapabilityResource(TCapabilityRef o, int idx, List list, IPersistable res) { + super(o, idx, list, res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/RequirementResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/RequirementResource.java new file mode 100644 index 0000000000..72a7476437 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/RequirementResource.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.reqscaps; + +import java.util.List; + +import org.eclipse.winery.model.tosca.TRequirementRef; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdResource; + +public class RequirementResource extends EntityWithoutIdResource { + + public RequirementResource(TRequirementRef o, int idx, List list, IPersistable res) { + super(o, idx, list, res); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/RequirementsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/RequirementsResource.java new file mode 100644 index 0000000000..dc6ad94f1c --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/RequirementsResource.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.reqscaps; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.common.ModelUtilities; +import org.eclipse.winery.model.tosca.TRequirement; +import org.eclipse.winery.model.tosca.TRequirementRef; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources._support.collections.CollectionsHelper; +import org.eclipse.winery.repository.resources._support.collections.withoutid.EntityWithoutIdCollectionResource; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; + +import com.sun.jersey.api.view.Viewable; + +/** + * This class is mirrored at + * {@link org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.reqscaps.CapabilitiesResource} + */ +public class RequirementsResource extends EntityWithoutIdCollectionResource { + + public RequirementsResource(IPersistable res, List refs) { + super(RequirementResource.class, TRequirementRef.class, refs, res); + } + + @Override + public Viewable getHTML() { + throw new IllegalStateException("Not yet required: boundarydefinitions.jsp renders all tab content."); + } + + /** + * Adds an element using form-encoding + * + * This is necessary as TRequirementRef contains an IDREF and the XML + * snippet itself does not contain the target id + * + * @param name the optional name of the requirement + * @param reference the reference to a requirement in the topology + */ + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public Response addNewElement(@FormParam("name") String name, @FormParam("ref") String reference) { + // Implementation adapted from super addNewElement + + if (reference == null) { + return Response.status(Status.BAD_REQUEST).entity("A reference has to be provided").build(); + } + + TRequirementRef ref = new TRequirementRef(); + ref.setName(name); // may also be null + + // The XML model forces us to put a reference to the object and not just the string + ServiceTemplateResource rs = (ServiceTemplateResource) this.res; + TRequirement resolved = ModelUtilities.resolveRequirement(rs.getServiceTemplate(), reference); + // In case nothing was found: report back to the user + if (resolved == null) { + return Response.status(Status.BAD_REQUEST).entity("Reference could not be resolved").build(); + } + + ref.setRef(resolved); + + // "this.alreadyContains(ref)" cannot be called as this leads to a mappable exception: The data does not contain an id where the given ref attribute may point to + + this.list.add(ref); + return CollectionsHelper.persist(this.res, this, ref); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/package-info.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/package-info.java new file mode 100644 index 0000000000..f6a3c5d596 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/boundarydefinitions/reqscaps/package-info.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ + +/** + * This package contains all classes for requirement refs and capability refs + * + * They are nested as "Requirements" / "Capabilities" in the boundary definitions, but the things itself are called "...Ref" + */ +package org.eclipse.winery.repository.resources.servicetemplates.boundarydefinitions.reqscaps; \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlanResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlanResource.java new file mode 100644 index 0000000000..d8c7092622 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlanResource.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.plans; + +import java.io.IOException; +import java.util.List; + +import javax.ws.rs.DELETE; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.common.ids.elements.PlanId; +import org.eclipse.winery.common.ids.elements.PlansId; +import org.eclipse.winery.model.tosca.TPlan; +import org.eclipse.winery.model.tosca.TPlan.InputParameters; +import org.eclipse.winery.model.tosca.TPlan.OutputParameters; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources.IHasName; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdResource; +import org.eclipse.winery.repository.resources.interfaces.ParametersResource; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Does not implement + * {@link org.eclipse.winery.repository.resources.IHasTypeReference}, because + * the type of a plan is outside the system of TOSCA. + */ +public class PlanResource extends EntityWithIdResource implements IHasName { + + private static final Logger logger = LoggerFactory.getLogger(PlanResource.class); + + + public PlanResource(IIdDetermination idDetermination, TPlan o, int idx, List list, ServiceTemplateResource res) { + super(idDetermination, o, idx, list, res); + } + + /** + * Ugly hack to get the parent service template resource + * + */ + public ServiceTemplateResource getServiceTemplateResource() { + // Solution proposal 1: Each sub-resource should know its parent service + // template + // + // Solution proposal 2 (Generic solution): Each resource should know its + // parent resource + // + // Does not work when plan is used at as component instance (then, + // serviceTemplateResource is null). In this case, a plan is not associated + // with a service template. + + // we cannot use "((PlanId) id).getParent()" as this "only" returns an + // ID + // we could create a newly resource based on that ID + // However, the parent resource has already been created when the + // PlanResource has been generated: + // Jersey crawls down from the main resource through the service + // template resource to the plan resource + return (ServiceTemplateResource) this.res; + } + + @Override + @DELETE + public Response onDelete() { + Response res = super.onDelete(); + if (Utils.isSuccessFulResponse(res)) { + ServiceTemplateId sId = (ServiceTemplateId) this.getServiceTemplateResource().getId(); + PlansId psId = new PlansId(sId); + PlanId pId = new PlanId(psId, new XMLId(this.o.getId(), false)); + try { + Repository.INSTANCE.forceDelete(pId); + } catch (IOException e) { + return Response.status(Status.INTERNAL_SERVER_ERROR).entity("Could not remove plan file").build(); + } + return BackendUtils.persist(this.res); + } else { + return res; + } + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Response getHTML() { + return Response.ok().entity("No editor plugin found for plan language " + this.o.getPlanLanguage()).build(); + } + + @Override + public String getName() { + String name = this.o.getName(); + if (name == null) { + name = this.o.getId(); + } + return name; + } + + @Override + public Response setName(@FormParam("value") String name) { + this.o.setName(name); + return BackendUtils.persist(this.res); + } + + @GET + @Path("type") + public String getType() { + return this.o.getPlanType(); + } + + @PUT + @Path("type") + public Response setType(@FormParam("type") String type) { + this.o.setPlanType(type); + return BackendUtils.persist(this.res); + } + + @GET + @Path("language") + public String getLanguage() { + return this.o.getPlanLanguage(); + } + + @PUT + @Path("language") + public Response setLanguage(@FormParam("language") String language) { + this.o.setPlanType(language); + return BackendUtils.persist(this.res); + } + + @Path("inputparameters/") + public ParametersResource getInputParametersResource() { + InputParameters inputParameters = this.o.getInputParameters(); + if (inputParameters == null) { + inputParameters = new InputParameters(); + this.o.setInputParameters(inputParameters); + } + return new ParametersResource(inputParameters.getInputParameter(), this.getServiceTemplateResource()); + } + + @Path("outputparameters/") + public ParametersResource getOutputParametersResource() { + OutputParameters outputParameters = this.o.getOutputParameters(); + if (outputParameters == null) { + outputParameters = new OutputParameters(); + this.o.setOutputParameters(outputParameters); + } + return new ParametersResource(outputParameters.getOutputParameter(), this.getServiceTemplateResource()); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlansResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlansResource.java new file mode 100644 index 0000000000..9b6cd92e26 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlansResource.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.plans; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.common.ids.elements.PlanId; +import org.eclipse.winery.common.ids.elements.PlansId; +import org.eclipse.winery.model.tosca.TPlan; +import org.eclipse.winery.model.tosca.TPlan.PlanModelReference; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdCollectionResource; +import org.eclipse.winery.repository.resources.admin.types.PlanLanguagesManager; +import org.eclipse.winery.repository.resources.admin.types.PlanTypesManager; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; +import org.restdoc.annotations.RestDoc; +import org.restdoc.annotations.RestDocParam; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonGenerator; +import com.sun.jersey.api.view.Viewable; +import com.sun.jersey.core.header.FormDataContentDisposition; +import com.sun.jersey.multipart.FormDataBodyPart; +import com.sun.jersey.multipart.FormDataParam; + +/** + * Presents the plans nested in one Service Template + */ +public class PlansResource extends EntityWithIdCollectionResource { + + private static final Logger logger = LoggerFactory.getLogger(PlansResource.class); + + + public PlansResource(List plans, ServiceTemplateResource res) { + super(PlanResource.class, TPlan.class, plans, res); + } + + @Override + public Viewable getHTML() { + return new Viewable("/jsp/servicetemplates/plans/plans.jsp", new PlansResourceData(this.list)); + } + + @POST + @RestDoc(methodDescription = "

Linked plans are currently not supported. Existing plans with the same id are overwritten

@return JSON with .tableData: Array with row data for dataTable

") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + // the supertype consumes JSON and XML at org.eclipse.winery.repository.resources._support.collections.EntityCollectionResource.addNewElement(EntityT) + // @formatter:off + public Response onPost( + @FormDataParam("planName") String name, + @FormDataParam("planType") String type, + @FormDataParam("planLanguage") @RestDocParam(description = "the plan language (e..g, BPMN or BPEL). Full URL.") String language, + @FormDataParam("file") InputStream uploadedInputStream, + @FormDataParam("file") FormDataContentDisposition fileDetail, + @FormDataParam("file") FormDataBodyPart body + ) { + // @formatter:on + if (StringUtils.isEmpty(name)) { + return Response.status(Status.BAD_REQUEST).entity("planName must be given").build(); + } + if (StringUtils.isEmpty(type)) { + return Response.status(Status.BAD_REQUEST).entity("planType must be given").build(); + } + if (StringUtils.isEmpty(language)) { + return Response.status(Status.BAD_REQUEST).entity("planLanguage must be given").build(); + } + if (uploadedInputStream == null) { + return Response.status(Status.BAD_REQUEST).entity("file has to be provided").build(); + } + + // A plan carries both a name and an ID + // To be user-friendly, we create the ID based on the name + // the drawback is, that we do not allow two plans with the same name + // during creation, but allow renaming plans to the same name (as we do + // not allow ID renaming) + String xmlId = Utils.createXMLidAsString(name); + + // BEGIN: Store plan file + + // Determine Id + PlansId plansId = new PlansId((ServiceTemplateId) ((ServiceTemplateResource) this.res).getId()); + PlanId planId = new PlanId(plansId, new XMLId(xmlId, false)); + // Ensure overwriting + if (Repository.INSTANCE.exists(planId)) { + try { + Repository.INSTANCE.forceDelete(planId); + } catch (IOException e) { + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); + } + } + + // We use the filename also as local file name. Alternatively, we could use the xml id + // With URL encoding, this should not be an issue + final String fileName = Util.URLencode(fileDetail.getFileName()); + + // Really store it + RepositoryFileReference ref = new RepositoryFileReference(planId, fileName); + try { + Repository.INSTANCE.putContentToFile(ref, uploadedInputStream, body.getMediaType()); + } catch (IOException e1) { + return Response.status(Status.INTERNAL_SERVER_ERROR).entity("Could not store plan. " + e1.getMessage()).build(); + } + // END: Store plan file + + TPlan plan = new TPlan(); + plan.setId(xmlId); + plan.setName(name); + plan.setPlanType(type); + plan.setPlanLanguage(language); + PlanModelReference pref = new PlanModelReference(); + // Set path relative to Definitions/ path inside CSAR. + pref.setReference("../" + Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(planId)) + fileName); + plan.setPlanModelReference(pref); + this.list.add(plan); + + // prepare result + JsonFactory jsonFactory = new JsonFactory(); + StringWriter sw = new StringWriter(); + try { + JsonGenerator jGenerator = jsonFactory.createGenerator(sw); + jGenerator.writeStartObject(); + jGenerator.writeFieldName("tableData"); + jGenerator.writeStartArray(); + jGenerator.writeString(xmlId); + jGenerator.writeString(""); // precondition + jGenerator.writeString(name); + jGenerator.writeString(PlanTypesManager.INSTANCE.getShortName(type)); + jGenerator.writeString(PlanLanguagesManager.INSTANCE.getShortName(language)); + jGenerator.writeEndArray(); + jGenerator.writeEndObject(); + jGenerator.close(); + sw.close(); + } catch (JsonGenerationException e) { + PlansResource.logger.error(e.getMessage(), e); + return Response.serverError().build(); + } catch (IOException e) { + PlansResource.logger.error(e.getMessage(), e); + return Response.serverError().build(); + } + + Response res = BackendUtils.persist(this.res); + if (res.getStatus() == 204) { + // everything OK, return created + return Response.created(Utils.createURI(Util.URLencode(xmlId))).entity(sw.toString()).build(); + } else { + return res; + } + } + + @Override + public String getId(TPlan plan) { + return plan.getId(); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlansResourceData.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlansResourceData.java new file mode 100644 index 0000000000..8527eb4938 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/plans/PlansResourceData.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.plans; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Collection; +import java.util.List; + +import org.eclipse.winery.model.tosca.TPlan; +import org.eclipse.winery.model.tosca.TPlan.PlanModelReference; +import org.eclipse.winery.repository.datatypes.TypeWithShortName; +import org.eclipse.winery.repository.resources.admin.types.PlanLanguagesManager; +import org.eclipse.winery.repository.resources.admin.types.PlanTypesManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonGenerator; + +public class PlansResourceData { + + private static final Logger logger = LoggerFactory.getLogger(PlansResourceData.class); + + // data: [ [id, pre, name, type, lang]* ] + private String embeddedPlansTableData; + + // data: [ [id, pre, name, type, lang, reference]* ] + private String linkedPlansTableData; + + + /** + * Data object for the JSP + * + * @param serviceTemplateResource the service template the plans belong to + */ + public PlansResourceData(List plans) { + if (plans.isEmpty()) { + this.embeddedPlansTableData = "[]"; + this.linkedPlansTableData = "[]"; + return; + } + JsonFactory jsonFactory = new JsonFactory(); + StringWriter embeddedPlansTableDataSW = new StringWriter(); + StringWriter linkedPlansTableDataSW = new StringWriter(); + try { + JsonGenerator jGeneratorEmbedded = jsonFactory.createGenerator(embeddedPlansTableDataSW); + JsonGenerator jGeneratorLinked = jsonFactory.createGenerator(linkedPlansTableDataSW); + + jGeneratorEmbedded.writeStartArray(); + jGeneratorLinked.writeStartArray(); + + for (TPlan plan : plans) { + String name = plan.getName(); + if (name == null) { + // name defaults to id + name = plan.getId(); + } + String type = PlanTypesManager.INSTANCE.getShortName(plan.getPlanType()); + String language = PlanLanguagesManager.INSTANCE.getShortName(plan.getPlanLanguage()); + PlanModelReference planModelReference = plan.getPlanModelReference(); + String reference = planModelReference != null ? planModelReference.getReference() : null; + JsonGenerator gen; + boolean writeReference; + if (reference == null) { + gen = jGeneratorEmbedded; + writeReference = false; + } else if (reference.startsWith("../")) { + gen = jGeneratorEmbedded; + writeReference = false; + } else { + gen = jGeneratorLinked; + writeReference = true; + } + + gen.writeStartArray(); + gen.writeString(plan.getId()); + gen.writeString(""); // precondition + gen.writeString(name); + gen.writeString(type); + gen.writeString(language); + if (writeReference) { + gen.writeString(reference); + } + gen.writeEndArray(); + } + + jGeneratorEmbedded.writeEndArray(); + jGeneratorLinked.writeEndArray(); + + jGeneratorEmbedded.close(); + embeddedPlansTableDataSW.close(); + jGeneratorLinked.close(); + linkedPlansTableDataSW.close(); + } catch (JsonGenerationException e) { + PlansResourceData.logger.error(e.getMessage(), e); + this.embeddedPlansTableData = "[]"; + this.linkedPlansTableData = "[]"; + return; + } catch (IOException e) { + PlansResourceData.logger.error("", e); + this.embeddedPlansTableData = "[]"; + this.linkedPlansTableData = "[]"; + return; + } + this.embeddedPlansTableData = embeddedPlansTableDataSW.toString(); + this.linkedPlansTableData = linkedPlansTableDataSW.toString(); + } + + public String getEmbeddedPlansTableData() { + return this.embeddedPlansTableData; + } + + public String getLinkedPlansTableData() { + return this.linkedPlansTableData; + } + + public Collection getPlanTypes() { + return PlanTypesManager.INSTANCE.getTypes(); + } + + public Collection getPlanLanguages() { + return PlanLanguagesManager.INSTANCE.getTypes(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/OptionResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/OptionResource.java new file mode 100644 index 0000000000..9ce11f9fae --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/OptionResource.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.selfserviceportal; + +import java.io.IOException; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.winery.model.selfservice.ApplicationOption; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.datatypes.ids.elements.SelfServiceMetaDataId; +import org.eclipse.winery.repository.resources._support.collections.IIdDetermination; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OptionResource extends EntityWithIdResource { + + private static final Logger logger = LoggerFactory.getLogger(OptionResource.class); + + static final String ICON_JPG = "icon.jpg"; + static final String PLAN_INPUT_XML = "plan.input.xml"; + private SelfServiceMetaDataId ssmdId; + + + public OptionResource(IIdDetermination idDetermination, ApplicationOption o, int idx, List list, SelfServicePortalResource res) { + super(idDetermination, o, idx, list, res); + this.ssmdId = ((SelfServicePortalResource) this.res).getId(); + } + + private String getFileNamePrefix() { + return OptionResource.getFileNamePrefix(this.o.getId()); + } + + public static String getFileNamePrefix(String id) { + return "option_" + id + "_"; + } + + @Path(OptionResource.ICON_JPG) + @GET + public Response getIcon(@HeaderParam("If-Modified-Since") String modified) { + RepositoryFileReference ref = new RepositoryFileReference(this.ssmdId, this.getFileNamePrefix() + OptionResource.ICON_JPG); + return BackendUtils.returnRepoPath(ref, modified); + } + + @Path("planinputmessage") + @GET + public Response getPlanInputMessage(@HeaderParam("If-Modified-Since") String modified) { + RepositoryFileReference ref = new RepositoryFileReference(this.ssmdId, this.getFileNamePrefix() + OptionResource.PLAN_INPUT_XML); + return BackendUtils.returnRepoPath(ref, modified); + } + + @Override + public Response onDelete() { + // delete icon and plan model reference ... + + // delete icon + // we use the URL stored in the data instead of the generated URL to be compatible with manually edits + RepositoryFileReference ref = new RepositoryFileReference(this.ssmdId, this.o.getIconUrl()); + try { + Repository.INSTANCE.forceDelete(ref); + } catch (IOException e) { + OptionResource.logger.error("Could not remove file", e); + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); + } + + // delete plan input + // we use the URL stored in the data instead of the generated URL to be compatible with manually edits + ref = new RepositoryFileReference(this.ssmdId, this.o.getPlanInputMessageUrl()); + try { + Repository.INSTANCE.forceDelete(ref); + } catch (IOException e) { + OptionResource.logger.error("Could not remove file", e); + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); + } + + // after deleting files, continue with list deletion + return super.onDelete(); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/OptionsResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/OptionsResource.java new file mode 100644 index 0000000000..86fa102fef --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/OptionsResource.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.selfserviceportal; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.winery.model.selfservice.ApplicationOption; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.datatypes.ids.elements.SelfServiceMetaDataId; +import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdCollectionResource; +import org.restdoc.annotations.RestDoc; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; +import com.sun.jersey.core.header.FormDataContentDisposition; +import com.sun.jersey.multipart.FormDataBodyPart; +import com.sun.jersey.multipart.FormDataParam; + +public class OptionsResource extends EntityWithIdCollectionResource { + + private static final Logger logger = LoggerFactory.getLogger(OptionsResource.class); + + + public OptionsResource(List list, SelfServicePortalResource res) { + super(OptionResource.class, ApplicationOption.class, list, res); + } + + @Override + public String getId(ApplicationOption entity) { + return entity.getId(); + } + + @Override + public Viewable getHTML() { + throw new IllegalStateException("Not yet implemented."); + } + + @POST + @RestDoc(methodDescription = "Adds a new option

TODO: @return JSON with .tableData: Array with row data for dataTable

") + @Consumes(MediaType.MULTIPART_FORM_DATA) + // @formatter:off + public Response onPost( + @FormDataParam("name") String name, + @FormDataParam("description") String description, + @FormDataParam("planServiceName") String planServiceName, + @FormDataParam("planInputMessage") String planInputMessage, + @FormDataParam("file") InputStream uploadedInputStream, + @FormDataParam("file") FormDataContentDisposition fileDetail, + @FormDataParam("file") FormDataBodyPart body + ) { + // @formatter:on + if (StringUtils.isEmpty(name)) { + return Response.status(Status.BAD_REQUEST).entity("planName must be given").build(); + } + if (StringUtils.isEmpty(description)) { + return Response.status(Status.BAD_REQUEST).entity("description must be given").build(); + } + if (StringUtils.isEmpty(planServiceName)) { + return Response.status(Status.BAD_REQUEST).entity("planServiceName must be given").build(); + } + if (StringUtils.isEmpty(planInputMessage)) { + return Response.status(Status.BAD_REQUEST).entity("planInputMessage must be given").build(); + } + if (uploadedInputStream == null) { + return Response.status(Status.BAD_REQUEST).entity("file has to be provided").build(); + } + ApplicationOption option = new ApplicationOption(); + + String id = Utils.createXMLidAsString(name); + + String fileNamePrefix = OptionResource.getFileNamePrefix(id); + String iconFileName = fileNamePrefix + OptionResource.ICON_JPG; + String planInputMessageFileName = fileNamePrefix + OptionResource.PLAN_INPUT_XML; + + // create option data + option.setId(id); + option.setName(name); + option.setDescription(description); + option.setIconUrl(iconFileName); + option.setPlanInputMessageUrl(planInputMessageFileName); + option.setPlanServiceName(planServiceName); + + // BEGIN: store icon and planInputMessage + + SelfServiceMetaDataId ssmdId = ((SelfServicePortalResource) this.res).getId(); + + RepositoryFileReference iconRef = new RepositoryFileReference(ssmdId, iconFileName); + try { + Repository.INSTANCE.putContentToFile(iconRef, uploadedInputStream, body.getMediaType()); + } catch (IOException e) { + OptionsResource.logger.error(e.getMessage(), e); + return Response.serverError().entity(e.getMessage()).build(); + } + + RepositoryFileReference planInputMessageRef = new RepositoryFileReference(ssmdId, planInputMessageFileName); + try { + Repository.INSTANCE.putContentToFile(planInputMessageRef, planInputMessage, MediaType.TEXT_XML_TYPE); + } catch (IOException e) { + OptionsResource.logger.error(e.getMessage(), e); + return Response.serverError().entity(e.getMessage()).build(); + } + + // END: store icon and planInputMessage + + this.list.add(option); + Response response = BackendUtils.persist(this.res); + return response; + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/SelfServicePortalResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/SelfServicePortalResource.java new file mode 100644 index 0000000000..98e1dcf993 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/selfserviceportal/SelfServicePortalResource.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.selfserviceportal; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import org.apache.commons.io.IOUtils; +import org.apache.taglibs.standard.functions.Functions; +import org.eclipse.winery.common.RepositoryFileReference; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.model.selfservice.Application; +import org.eclipse.winery.model.selfservice.Application.Options; +import org.eclipse.winery.model.tosca.TDocumentation; +import org.eclipse.winery.repository.JAXBSupport; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.datatypes.ids.elements.SelfServiceMetaDataId; +import org.eclipse.winery.repository.resources._support.IPersistable; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.sun.jersey.api.view.Viewable; +import com.sun.jersey.multipart.FormDataBodyPart; +import com.sun.jersey.multipart.FormDataParam; + +public class SelfServicePortalResource implements IPersistable { + + private static final Logger logger = LoggerFactory.getLogger(SelfServicePortalResource.class); + + private final ServiceTemplateResource serviceTemplateResource; + + public final RepositoryFileReference data_xml_ref; + public final RepositoryFileReference icon_jpg_ref; + public final RepositoryFileReference image_jpg_ref; + + private final Application application; + + private final SelfServiceMetaDataId id; + + + public SelfServicePortalResource(ServiceTemplateId serviceTemplateId) { + this(null, serviceTemplateId); + } + + public SelfServicePortalResource(ServiceTemplateResource serviceTemplateResource) { + this(serviceTemplateResource, (ServiceTemplateId) serviceTemplateResource.getId()); + } + + SelfServiceMetaDataId getId() { + return this.id; + } + + /** + * @param serviceTemplateResource may be null + * @param serviceTemplateId the id, must not be null + */ + private SelfServicePortalResource(ServiceTemplateResource serviceTemplateResource, ServiceTemplateId serviceTemplateId) { + this.serviceTemplateResource = serviceTemplateResource; + this.id = new SelfServiceMetaDataId(serviceTemplateId); + this.data_xml_ref = new RepositoryFileReference(this.id, "data.xml"); + this.icon_jpg_ref = new RepositoryFileReference(this.id, "icon.jpg"); + this.image_jpg_ref = new RepositoryFileReference(this.id, "image.jpg"); + this.application = this.getData(); + } + + private Application getData() { + if (Repository.INSTANCE.exists(this.data_xml_ref)) { + Unmarshaller u = JAXBSupport.createUnmarshaller(); + try (InputStream is = Repository.INSTANCE.newInputStream(this.data_xml_ref);) { + return (Application) u.unmarshal(is); + } catch (IOException | JAXBException e) { + SelfServicePortalResource.logger.error("Could not read from " + this.data_xml_ref, e); + return new Application(); + } + } else { + return this.getDefaultApplicationData(); + } + } + + private Application getDefaultApplicationData() { + Application app = new Application(); + app.setIconUrl("icon.jpg"); + app.setImageUrl("image.jpg"); + if (this.serviceTemplateResource != null) { + app.setDisplayName(this.serviceTemplateResource.getName()); + List documentation = this.serviceTemplateResource.getServiceTemplate().getDocumentation(); + if ((documentation != null) && (!documentation.isEmpty())) { + TDocumentation doc = documentation.get(0); + List content = doc.getContent(); + if ((content != null) && (!content.isEmpty())) { + app.setDescription(content.get(0).toString()); + } + } + } + return app; + } + + @GET + @Produces(MediaType.TEXT_HTML) + public Viewable getHTML() { + return new Viewable("/jsp/servicetemplates/selfservicemetadata/selfservicemetadata.jsp", this); + } + + @Override + public void persist() throws IOException { + BackendUtils.persist(this.application, this.data_xml_ref, MediaType.TEXT_XML_TYPE); + } + + @PUT + @Consumes(MediaType.TEXT_XML) + public Response onPutXML(Application data) { + String content = Utils.getXMLAsString(data); + return BackendUtils.putContentToFile(this.data_xml_ref, content, MediaType.TEXT_XML_TYPE); + } + + @Path("icon.jpg") + @GET + public Response getIcon(@HeaderParam("If-Modified-Since") String modified) { + RepositoryFileReference ref = new RepositoryFileReference(this.id, "icon.jpg"); + return BackendUtils.returnRepoPath(ref, modified); + } + + @Path("icon.jpg") + @PUT + @Consumes(MediaType.MULTIPART_FORM_DATA) + public Response putIcon(@FormDataParam("file") InputStream uploadedInputStream, @FormDataParam("file") FormDataBodyPart body) { + RepositoryFileReference ref = new RepositoryFileReference(this.id, "icon.jpg"); + return BackendUtils.putContentToFile(ref, uploadedInputStream, body.getMediaType()); + } + + @Path("image.jpg") + @GET + public Response getImage(@HeaderParam("If-Modified-Since") String modified) { + RepositoryFileReference ref = new RepositoryFileReference(this.id, "image.jpg"); + return BackendUtils.returnRepoPath(ref, modified); + } + + @Path("image.jpg") + @PUT + @Consumes(MediaType.MULTIPART_FORM_DATA) + public Response putImage(@FormDataParam("file") InputStream uploadedInputStream, @FormDataParam("file") FormDataBodyPart body) { + RepositoryFileReference ref = new RepositoryFileReference(this.id, "image.jpg"); + return BackendUtils.putContentToFile(ref, uploadedInputStream, body.getMediaType()); + } + + @Path("displayname") + @PUT + public Response onPutOnDisplayName(@FormParam("value") String value) { + this.application.setDisplayName(value); + return BackendUtils.persist(this); + } + + @Path("description") + @PUT + public Response onPutOnDescription(@FormParam("value") String value) { + this.application.setDescription(value); + return BackendUtils.persist(this); + } + + @Path("options/") + public OptionsResource getOptionsResource() { + Options options = this.application.getOptions(); + if (options == null) { + options = new Options(); + this.application.setOptions(options); + } + return new OptionsResource(options.getOption(), this); + } + + /** + * @return the internal application object. Used for the export. + */ + public Application getApplication() { + return this.application; + } + + /** + * Used in JSP only + */ + public String getApplicationAsXMLStringEncoded() { + String res; + if (Repository.INSTANCE.exists(this.data_xml_ref)) { + StringWriter sw = new StringWriter(); + try (InputStream is = Repository.INSTANCE.newInputStream(this.data_xml_ref);) { + IOUtils.copy(is, sw); + } catch (IOException e) { + SelfServicePortalResource.logger.error("Could not read from file", e); + } + res = sw.toString(); + } else { + // return skeleton for application + // application object is already filled with default values if no file exists in repo + res = Utils.getXMLAsString(this.getApplication()); + } + return Functions.escapeXml(res); + } +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/NodeTemplateResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/NodeTemplateResource.java new file mode 100644 index 0000000000..71ffeb9e71 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/NodeTemplateResource.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.topologytemplates; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.HEAD; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; + +import org.eclipse.winery.model.tosca.TNodeTemplate; +import org.eclipse.winery.common.constants.Namespaces; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.resources.INodeTemplateResourceOrNodeTypeImplementationResource; +import org.eclipse.winery.repository.resources.artifacts.DeploymentArtifactsResource; +import org.eclipse.winery.repository.resources.entitytemplates.TEntityTemplateResource; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; +import org.restdoc.annotations.RestDoc; + +public class NodeTemplateResource extends TEntityTemplateResource implements INodeTemplateResourceOrNodeTypeImplementationResource { + + private final TNodeTemplate nodeTemplate; + + + /** + * + * @param nodeTemplate the node template this resource is modeling + * @param list the list the node template is contained in. It is NOT of type + * "List" as the list holding + * @param idx + * @param serviceTemplateResource + */ + public NodeTemplateResource(TNodeTemplate nodeTemplate, List list, int idx, ServiceTemplateResource serviceTemplateResource) { + super(nodeTemplate, list, idx, serviceTemplateResource); + this.nodeTemplate = nodeTemplate; + assert (this.template == this.nodeTemplate); + } + + @Path("deploymentartifacts/") + public DeploymentArtifactsResource getDeploymentArtifacts() { + return new DeploymentArtifactsResource(this.nodeTemplate, this); + } + + @GET + @RestDoc(methodDescription="* The following methods are currently *not* used by the topology modeler.
" + + "The modeler is using the repository client to interact with the repository") + @Path("minInstances") + public String getMinInstances() { + return Integer.toString(this.nodeTemplate.getMinInstances()); + } + + @PUT + @Path("minInstances") + public Response setMinInstances(@FormParam(value = "minInstances") String minInstances) { + int min = Integer.parseInt(minInstances); + this.nodeTemplate.setMinInstances(min); + return BackendUtils.persist(this.res); + } + + @GET + @Path("maxInstances") + public String getMaxInstances() { + return this.nodeTemplate.getMaxInstances(); + } + + @PUT + @Path("maxInstances") + public Response setMaxInstances(@FormParam(value = "maxInstances") String maxInstances) { + // TODO: check for valid integer | "unbound" + this.nodeTemplate.setMaxInstances(maxInstances); + return BackendUtils.persist(this.res); + } + + + /* * * + * The visual appearance + * + * We do not use a subresource "visualappearance" here to avoid generation of more objects + * * */ + + private final QName qnameX = new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "x"); + private final QName qnameY = new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "y"); + + @Path("x") + @GET + @RestDoc(methodDescription="@return the x coordinate of the node template") + public String getX() { + Map otherAttributes = this.nodeTemplate.getOtherAttributes(); + return otherAttributes.get(this.qnameX); + } + + @Path("x") + @PUT + public Response setX(String x) { + this.nodeTemplate.getOtherAttributes().put(this.qnameX, x); + return BackendUtils.persist(this.res); + } + + @Path("y") + @GET + @RestDoc(methodDescription="@return the y coordinate of the node template") + public String getY() { + Map otherAttributes = this.nodeTemplate.getOtherAttributes(); + return otherAttributes.get(this.qnameY); + } + + @Path("y") + @PUT + public Response setY(String y) { + this.nodeTemplate.getOtherAttributes().put(this.qnameY, y); + return BackendUtils.persist(this.res); + } + + @Override + public Namespace getNamespace() { + // TODO Auto-generated method stub + throw new IllegalStateException("Not yet implemented."); + } + + /** + * Required for persistence after a change of the deployment artifact. + * Required by DeploymentArtifactResource to be able to persist + * + * @return the service template this node template belongs to + */ + public ServiceTemplateResource getServiceTemplateResource() { + return (ServiceTemplateResource) this.res; + } + + /** + * required for topology modeler to check for existence of a node template + * at the server + * + * @return empty response + */ + @HEAD + public Response getHEAD() { + return Response.noContent().build(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/NodeTemplatesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/NodeTemplatesResource.java new file mode 100644 index 0000000000..585d383c7c --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/NodeTemplatesResource.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.topologytemplates; + +import java.util.List; + +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.model.tosca.TNodeTemplate; +import org.eclipse.winery.model.tosca.TTopologyTemplate; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.resources.entitytemplates.TEntityTemplatesResource; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; + +import com.sun.jersey.api.NotFoundException; + +public class NodeTemplatesResource extends TEntityTemplatesResource { + + private final TTopologyTemplate topologyTemplate; + + + public NodeTemplatesResource(List list, TTopologyTemplate topologyTemplate, ServiceTemplateResource res) { + super(list, TNodeTemplate.class, NodeTemplateResource.class, res); + this.topologyTemplate = topologyTemplate; + } + + @Path("{id}/") + @Override + public NodeTemplateResource getTEntityTemplateResource(@PathParam("id") String id) { + id = Util.URLdecode(id); + int idx = -1; + List list = this.topologyTemplate.getNodeTemplateOrRelationshipTemplate(); + for (TEntityTemplate template : list) { + idx++; + if (template instanceof TNodeTemplate) { + if (((TNodeTemplate) template).getId().equals(id)) { + // we illegally convert the List to List, because we know + // that the implementation works nevertheless + // The alternative is to remove type safety at the resource, which brings more disadvantages + @SuppressWarnings("unchecked") + List l = (List) (List) list; + return new NodeTemplateResource((TNodeTemplate) template, l, idx, (ServiceTemplateResource) this.res); + } + } + } + throw new NotFoundException(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/RelationshipTemplateResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/RelationshipTemplateResource.java new file mode 100644 index 0000000000..2d1b957483 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/RelationshipTemplateResource.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.topologytemplates; + +import java.util.List; + +import org.eclipse.winery.model.tosca.TRelationshipTemplate; +import org.eclipse.winery.repository.resources.entitytemplates.TEntityTemplateResource; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; + +public class RelationshipTemplateResource extends TEntityTemplateResource { + + private final TRelationshipTemplate relationshipTemplate; + + + public RelationshipTemplateResource(TRelationshipTemplate relationshipTemplate, List list, int idx, ServiceTemplateResource res) { + super(relationshipTemplate, list, idx, res); + this.relationshipTemplate = relationshipTemplate; + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/RelationshipTemplatesResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/RelationshipTemplatesResource.java new file mode 100644 index 0000000000..96b9e3d3e2 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/RelationshipTemplatesResource.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.topologytemplates; + +import java.util.List; + +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +import org.eclipse.winery.model.tosca.TEntityTemplate; +import org.eclipse.winery.model.tosca.TRelationshipTemplate; +import org.eclipse.winery.model.tosca.TTopologyTemplate; +import org.eclipse.winery.common.Util; +import org.eclipse.winery.repository.resources.entitytemplates.TEntityTemplatesResource; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; + +import com.sun.jersey.api.NotFoundException; + +public class RelationshipTemplatesResource extends TEntityTemplatesResource { + + private final TTopologyTemplate topologyTemplate; + + + public RelationshipTemplatesResource(List list, TTopologyTemplate topologyTemplate, ServiceTemplateResource res) { + super(list, TRelationshipTemplate.class, RelationshipTemplateResource.class, res); + this.topologyTemplate = topologyTemplate; + } + + @Path("{id}/") + @Override + public RelationshipTemplateResource getTEntityTemplateResource(@PathParam("id") String id) { + id = Util.URLdecode(id); + List list = this.topologyTemplate.getNodeTemplateOrRelationshipTemplate(); + for (int i = 0; i < list.size(); i++) { + TEntityTemplate template = list.get(i); + if (template instanceof TRelationshipTemplate) { + if (((TRelationshipTemplate) template).getId().equals(id)) { + // we illegally convert the List to List, because we know + // that the implementation works nevertheless + // The alternative is to remove type safety at the resource, which brings more disadvantages + @SuppressWarnings("unchecked") + List l = (List) (List) list; + return new RelationshipTemplateResource((TRelationshipTemplate) template, l, i, (ServiceTemplateResource) this.res); + } + } + } + throw new NotFoundException(); + } + +} diff --git a/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/TopologyTemplateResource.java b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/TopologyTemplateResource.java new file mode 100644 index 0000000000..b74262bbbf --- /dev/null +++ b/org.eclipse.winery.repository/src/main/java/org/eclipse/winery/repository/resources/servicetemplates/topologytemplates/TopologyTemplateResource.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.servicetemplates.topologytemplates; + +import java.net.URI; +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.eclipse.winery.common.Util; +import org.eclipse.winery.common.ids.definitions.ServiceTemplateId; +import org.eclipse.winery.model.tosca.TNodeTemplate; +import org.eclipse.winery.model.tosca.TRelationshipTemplate; +import org.eclipse.winery.model.tosca.TTopologyTemplate; +import org.eclipse.winery.repository.Prefs; +import org.eclipse.winery.repository.Utils; +import org.eclipse.winery.repository.backend.BackendUtils; +import org.eclipse.winery.repository.client.IWineryRepositoryClient; +import org.eclipse.winery.repository.client.WineryRepositoryClientFactory; +import org.eclipse.winery.repository.json.TopologyTemplateModule; +import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource; +import org.restdoc.annotations.RestDoc; +import org.restdoc.annotations.RestDocParam; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.sun.jersey.api.view.Viewable; + +public class TopologyTemplateResource { + + private static final Logger logger = LoggerFactory.getLogger(TopologyTemplateResource.class); + + private final TTopologyTemplate topologyTemplate; + + private final ServiceTemplateResource serviceTemplateRes; + + + /** + * A topology template is always nested in a service template + */ + public TopologyTemplateResource(ServiceTemplateResource parent) { + this.topologyTemplate = parent.getServiceTemplate().getTopologyTemplate(); + this.serviceTemplateRes = parent; + } + + + public static class DataForJSP { + + private String location; + private TTopologyTemplate topologyTemplate; + private URI repositoryURI; + private String additonalCSS; + private Boolean autoLayoutOnLoad; + private String additionalScript; + + + public DataForJSP(String location, URI repositoryURI, TTopologyTemplate topologyTemplate, String additonalCSS, String additionalScript, Boolean autoLayoutOnLoad) { + this.location = location; + this.repositoryURI = repositoryURI; + this.topologyTemplate = topologyTemplate; + this.additonalCSS = additonalCSS; + this.additionalScript = additionalScript; + this.autoLayoutOnLoad = autoLayoutOnLoad; + } + + public String getLocation() { + return this.location; + } + + public TTopologyTemplate getTopologyTemplate() { + return this.topologyTemplate; + } + + public String getAdditonalCSS() { + return this.additonalCSS; + } + + public String getAdditionalScript() { + return this.additionalScript; + } + + public Boolean getAutoLayoutOnLoad() { + return this.autoLayoutOnLoad; + } + + public IWineryRepositoryClient getClient() { + // Quick hack + // IWineryRepository is not implemented by Prefs.INSTANCE.getRepository() + // Therefore, we have to generate a real WineryRepositoryClient even if that causes more http load + IWineryRepositoryClient client = WineryRepositoryClientFactory.getWineryRepositoryClient(); + client.addRepository(this.repositoryURI.toString()); + return client; + } + + } + + + @GET + @RestDoc(methodDescription = "?edit is used in the URL to get the jsPlumb-based editor") + @Produces(MediaType.TEXT_HTML) + // @formatter:off + public Response getHTML( + @QueryParam(value = "edit") String edit, + @QueryParam(value = "script") @RestDocParam(description = "the script to include in a \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/addComponentInstance.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/addComponentInstance.tag new file mode 100644 index 0000000000..a82901a107 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/addComponentInstance.tag @@ -0,0 +1,147 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="used by genericcomponentpage.jsp and by implementations.jsp to create a component instance" pageEncoding="UTF-8"%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions"%> +<%-- +function createResource(nameOfResource, fields, url, onSuccess) cannot be used as this method is more diverse +--%> + +<%@attribute name="label" required="true" description="The lable to display"%> + +<%@attribute name="URL" description=""%> +<%@attribute name="onSuccess" description=""%> +<%@attribute name="type" description="added to dataToSend when doing a POST"%> +<%@attribute name="typeSelectorData" type="java.util.Collection" description="All available types when creating a template. We do not support types with names (additional to the id) as the current TOSCA specification does not foresee the usage of both name and id at types"%> +<%@attribute name="openinnewwindow" description="if true, the editor for the created component instance is openend in a new window"%> + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/colorpickerloading.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/colorpickerloading.tag new file mode 100644 index 0000000000..618f80fcb6 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/colorpickerloading.tag @@ -0,0 +1,52 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="initializes a color picker. Uses global variables cp_currentColorPicker, cp_oldColor, cp_written" pageEncoding="UTF-8"%> + +<%@attribute name="elementId" required="true" description="id of the element to convert to a color picker"%> +<%@attribute name="url" required="true" description="URL to put to"%> +<%@attribute name="color" required="true" description="the initial color"%> + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/common/.gitignore b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/common/.gitignore new file mode 100644 index 0000000000..6e112edf18 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/common/.gitignore @@ -0,0 +1,3 @@ +#This directory is generated via mvn generate-sources +#The content is copied from org.eclipse.winery.topologymodeler +* \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstance.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstance.tag new file mode 100644 index 0000000000..5bb0bcd467 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstance.tag @@ -0,0 +1,162 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Wrapper for resources, which are backed by definitions and thus offer an XML div" pageEncoding="UTF-8"%> + +<%-- + quick hack to avoid specifying windowtitle at elements having it.name, too. + TODO: check why in this class a check on it.name is done, although there is componentinstancewithname.tag +--%> +<%@attribute name="windowtitle" description="If it.name is not available, this parameter should be given"%> + +<%@attribute name="selected" required="true"%> + +<%@attribute name="cssClass" required="true"%> + +<%@attribute name="image" required="false"%> + +<%@attribute name="libs" fragment="true" %> + +<%@attribute name="subMenus" required="false" type="java.util.List" description="list of SubMenuData objects stating the content of the submenus. The first submenu is used as default page. Subpage #xml must not be included, it is added automatically."%> + +<%@attribute name="implementationFor" description="In case the component instance is an implementation for another type, the link (a href) to the type is put here"%> + +<%@attribute name="type" description="In case the component instance is a template, the link (a href) to the type is put here"%> + +<%@attribute name="twolines" required="false" description="if set, two lines are required for the tabs"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions" %> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + + + + + + + + + +
twolines"> + + + + + <%-- Quick hack to enable usage of this tag at adminresource --%> + + + <%@ include file="/jsp/componentnaming.jspf" %> +
+
+ + XML + CSAR + + + +
+ +
+ Implementation for ${implementationFor} +
+
+ +
+ Type ${type} +
+
+
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstancewithName.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstancewithName.tag new file mode 100644 index 0000000000..f970b99808 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstancewithName.tag @@ -0,0 +1,33 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag import="org.eclipse.winery.repository.resources.SubMenuData"%> +<%@tag description="Wrapper for component instances with a name. Name is also used for window title." pageEncoding="UTF-8"%> + +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + +<%@tag import="java.util.ArrayList"%> + + +<%@attribute name="selected" required="true"%> +<%@attribute name="cssClass" required="true"%> +<%@attribute name="image" required="false"%> +<%@attribute name="libs" fragment="true" %> +<%@attribute name="implementationFor" %> +<%@attribute name="twolines" required="false" description="if set, two lines are required for the tabs"%> +<%@attribute name="type" description="In case the component instance is a template, the link (a href) to the type is put here"%> + +<%@attribute name="subMenus" required="false" type="java.util.List" %> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstancewithNameDerivedFromAbstractFinal.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstancewithNameDerivedFromAbstractFinal.tag new file mode 100644 index 0000000000..a8ea212771 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/componentinstancewithNameDerivedFromAbstractFinal.tag @@ -0,0 +1,45 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag import="org.eclipse.winery.repository.resources.SubMenuData"%> +<%@tag description="Wrapper for component instances with name, derived from, abstract, final (equivalent to AbstractComponentInstanceWithName..." pageEncoding="UTF-8"%> + +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + +<%@tag import="java.util.ArrayList"%> + + +<%@attribute name="selected" required="true"%> +<%@attribute name="cssClass" required="true"%> +<%@attribute name="image" required="false"%> +<%@attribute name="libs" fragment="true" %> +<%@attribute name="implementationFor" %> +<%@attribute name="twolines" required="false" description="if set, two lines are required for the tabs"%> + +<%@attribute name="subMenus" required="false" type="java.util.List" description="list of SubMenuData objects stating the content of the submenus. The first submenu is used as default page. Subpage #xml must not be included, it is added automatically."%> + + +<% + +if (subMenus == null) { + subMenus = new ArrayList(1); +} + +SubMenuData data; + +data = new SubMenuData("#inheritance", "Inheritance"); +subMenus.add(data); +%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/constraints/constraint.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/constraints/constraint.tag new file mode 100644 index 0000000000..30607b64aa --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/constraints/constraint.tag @@ -0,0 +1,83 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Models editing a single constraint" pageEncoding="UTF-8"%> + +<%@taglib prefix="o" tagdir="/WEB-INF/tags/common/orioneditor"%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags"%> + + + + +<%-- +Quick hack to get the representation of an empty constraint +TODO: A resource should provide the empty representation (?!) + +The alternative is not to use the complete XML as the specification only allows the content of the XML wrapper to be modified. +If we use that method, this textarea is not required, but the sending of an existing constraint has to be modified to send only lines 2 to n-1, i.e., send without the wrapping lines. +This is not possible if the stored constraint is empty, then there are 2 lines only. +--%> + + + \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytemplate.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytemplate.tag new file mode 100644 index 0000000000..781e2d8586 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytemplate.tag @@ -0,0 +1,43 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Wrapper for instances of entity types" pageEncoding="UTF-8"%> + +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + +<%@tag import="java.util.ArrayList"%> +<%@tag import="org.eclipse.winery.repository.resources.SubMenuData"%> + + +<%@attribute name="selected" required="true"%> +<%@attribute name="cssClass" required="true"%> +<%@attribute name="image" required="false"%> +<%@attribute name="libs" fragment="true" %> + +<%@attribute name="subMenus" required="false" type="java.util.List" description="list of SubMenuData objects stating the content of the submenus. The first submenu is used as default page. Subpage #xml must not be included, it is added automatically."%> + + +<% + +if (subMenus == null) { + subMenus = new ArrayList(2); +} + +SubMenuData data; + +data = new SubMenuData("#properties", "Properties"); +subMenus.add(data); +%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytype.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytype.tag new file mode 100644 index 0000000000..6bd1d3d644 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytype.tag @@ -0,0 +1,49 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Wrapper for instances of entity types" pageEncoding="UTF-8"%> + +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + +<%@tag import="java.util.ArrayList"%> +<%@tag import="org.eclipse.winery.repository.resources.SubMenuData"%> + + +<%@attribute name="selected" required="true"%> +<%@attribute name="cssClass" required="true"%> +<%@attribute name="image" required="false"%> +<%@attribute name="twolines" required="false" description="if set, two lines are required for the tabs"%> +<%@attribute name="libs" fragment="true" %> + +<%@attribute name="subMenus" required="false" type="java.util.List" description="list of SubMenuData objects stating the content of the submenus. The first submenu is used as default page. Subpage #xml must not be included, it is added automatically."%> + + +<% + +if (subMenus == null) { + subMenus = new ArrayList(2); +} + +SubMenuData data; + +data = new SubMenuData("#propertiesdefinition", "Properties Definition"); +subMenus.add(data); + +// Tags are currently not implemented -> Don't confuse users by showing the tab +// has to be enabled again, when tags are implemented +//data = new SubMenuData("#tags", "Tags"); +//subMenus.add(data); +%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytypes/nodetypes/reqandcapdefs/reqandcapdefs.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytypes/nodetypes/reqandcapdefs/reqandcapdefs.tag new file mode 100644 index 0000000000..ce637a6940 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/entitytypes/nodetypes/reqandcapdefs/reqandcapdefs.tag @@ -0,0 +1,333 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3, integration with spinnerwithinphty + *******************************************************************************/ +--%> +<%@tag description="Models Requirement and Capability Definitions" pageEncoding="UTF-8"%> + +<%@attribute name="labelForSingleItem" required="true" %> +<%@attribute name="url" required="true"%> +<%@attribute name="allSubResources" required="true" type="java.util.List" description="All available req-/cap-defs" %> +<%@attribute name="allTypes" required="true" type="java.util.Collection" description="All available types of req-/cap-def" %> +<%@attribute name="typeClass" required="true" type="java.lang.Class" description="The class of the type" %> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="ct" tagdir="/WEB-INF/tags/common" %> +<%@taglib prefix="con" tagdir="/WEB-INF/tags/constraints" %> +<%@taglib prefix="o" tagdir="/WEB-INF/tags/common/orioneditor"%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions"%> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions"%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
nametypelower boundupper boundconstraints
${r.def.name}${wc:qname2href(pageContext.request.contextPath, typeClass, r.type)}${w:renderMinInstances(r.def.lowerBound)}${w:renderMaxInstances(r.def.upperBound)}
+ +<%-- Editing a set of constraints --%> + + + + + + +<%-- Editing a single constraint --%> + + + + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/genericpage.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/genericpage.tag new file mode 100644 index 0000000000..9fbe4e4155 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/genericpage.tag @@ -0,0 +1,344 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@tag description="Global Wrapper" pageEncoding="UTF-8"%> + +<%@attribute name="windowtitle" required="true" description="String to be used as window title"%> +<%@attribute name="selected" required="true"%> +<%@attribute name="cssClass" required="true"%> + +<%@attribute name="libs" fragment="true" %> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="ct" tagdir="/WEB-INF/tags/common"%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags"%> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions"%> + +<%@tag import="org.eclipse.winery.repository.Prefs" %> + + + + + + ${windowtitle} + + + + + + + <%-- CSS to style the file input field as button and adjust the Bootstrap progress bars --%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + +
+ +
+ +
+
+ + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/imageUpload.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/imageUpload.tag new file mode 100644 index 0000000000..6ef5d189e9 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/imageUpload.tag @@ -0,0 +1,42 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="form div to upload an icon" pageEncoding="UTF-8"%> + +<%@attribute name="label" required="true" description="LAbel to be used. Also used as title of the dialog"%> +<%@attribute name="URL" required="true" description="URL to post to"%> +<%@attribute name="id" required="true" description="id to form basis for ...Diag: id of diag; ...Form: id of input field used for file upload; ...Img: Image to refresh"%> +<%@attribute name="accept" description="if not null/'': list of accepted MIME file types"%> +<%@attribute name="width" required="true" description="Width of the image to display"%> +<%@attribute name="resize" description="if not null/'': enables image resizing. Currently not supported"%> + +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + + + +
+ +
+
+ n/a +
+ or drop the image in this area. +
+
diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/namespaceChooser.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/namespaceChooser.tag new file mode 100644 index 0000000000..56b0712dbc --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/namespaceChooser.tag @@ -0,0 +1,52 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="places a bootstrap form control to chooose a namespace. A new namespace can be created" pageEncoding="UTF-8"%> + + + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +<%@attribute name="allNamespaces" required="true" type="java.util.Collection" description="All known namespaces"%> +<%@attribute name="idOfInput" required="true" description="The id if the input field storing the namespace. Also used as name"%> +<%@attribute name="nameOfInput" required="false" description="The name if the input field storing the namespace. If not provided, ifOfInput is used"%> +<%@attribute name="selected" description="The currently selected namespace (optional)"%> + + + + +
+ + +
+ + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersHTML.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersHTML.tag new file mode 100644 index 0000000000..7474851df2 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersHTML.tag @@ -0,0 +1,38 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Input or Output parameters" pageEncoding="UTF-8"%> + +<%@attribute name="label" required="true" %> +<%@attribute name="inOrOut" required="true" %> +<%@attribute name="tableId" required="true" %> +<%@attribute name="baseURL" required="true" description="JavaScript expression for determining the baseURL"%> + +
+
+ + + +
+ + + + + + + + + + +
NameTypeRequired
+
diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersInput.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersInput.tag new file mode 100644 index 0000000000..73b8c1b874 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersInput.tag @@ -0,0 +1,20 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag pageEncoding="UTF-8"%> + +<%@attribute name="baseURL" required="true" description="JavaScript expression for determining the baseURL"%> + +<%@ taglib prefix="p" tagdir="/WEB-INF/tags/parameters" %> + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersJS.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersJS.tag new file mode 100644 index 0000000000..c493eeff7a --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersJS.tag @@ -0,0 +1,163 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Input and Output parameters handling. Used at interface/operation and plan" pageEncoding="UTF-8"%> + +<%@attribute name="afterLoad" description="JavaScript code to be executed after successfully loading/initialization"%> + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersOutput.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersOutput.tag new file mode 100644 index 0000000000..32a5565302 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/parameters/parametersOutput.tag @@ -0,0 +1,20 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag pageEncoding="UTF-8"%> + +<%@attribute name="baseURL" required="true" description="JavaScript expression for determining the baseURL"%> + +<%@ taglib prefix="p" tagdir="/WEB-INF/tags/parameters" %> + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/relationshiptype/validnodetypeendingsselect.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/relationshiptype/validnodetypeendingsselect.tag new file mode 100644 index 0000000000..1e0702d238 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/relationshiptype/validnodetypeendingsselect.tag @@ -0,0 +1,43 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Offers choice for valid endings" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> + +<%@attribute name="shortName" required="true" description="source|target"%> +<%@attribute name="currentSelection" required="false"%> +<%@attribute name="possibleValidEndings" type="java.util.Collection" %> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForReqOrCap.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForReqOrCap.tag new file mode 100644 index 0000000000..5195f9b6d8 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForReqOrCap.tag @@ -0,0 +1,161 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> + +<%@tag pageEncoding="UTF-8"%> + +<%@attribute name="label" description="Requirement|Capability" required="true" %> +<%@attribute name="requirementsOrCapabilities" description="requirements|capabilities" required="true" %> +<%@attribute name="reqOrCap" description="requirement|capability" required="true" %> + +<%@taglib prefix="b" tagdir="/WEB-INF/tags/servicetemplates/boundarydefinitions"%> + + + + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForServiceTemplatePropertyReqOrCap.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForServiceTemplatePropertyReqOrCap.tag new file mode 100644 index 0000000000..430d4db5c8 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForServiceTemplatePropertyReqOrCap.tag @@ -0,0 +1,166 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> + +<%@tag pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="bd" tagdir="/WEB-INF/tags/servicetemplates/boundarydefinitions" %> + +<%@attribute name="definedPropertiesAsJSONString" required="true" %> + + + +<%-- Browse for property --%> +<%-- +The following cannot be used as we return TWO things: the template and the property + +--%> + + + + + + \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForX.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForX.tag new file mode 100644 index 0000000000..4b38b62474 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/servicetemplates/boundarydefinitions/browseForX.tag @@ -0,0 +1,49 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> + +<%@tag pageEncoding="UTF-8"%> + +<%@attribute name="XShort" description="The X to browse for. Short form. E.g., Req, Cap, ..." required="true" %> +<%@attribute name="XLong" description="The X to browse for. Long form. E.g., Requirement, Capability, ..." required="true" %> + + +<%-- Browse for property --%> + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/simpleSingleFileUpload.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/simpleSingleFileUpload.tag new file mode 100644 index 0000000000..9774ba3a4b --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/simpleSingleFileUpload.tag @@ -0,0 +1,114 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@tag description="Global Wrapper" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> + +<%@attribute name="title" required="true" description="title of the dialog"%> +<%@attribute name="text" required="true" description="text to show before upload box"%> +<%@attribute name="URL" required="true" description="URL to post to"%> +<%@attribute name="type" required="true" description="PUT|POST"%> +<%@attribute name="additionalDropZone" required="false" description="jQuery selector for an additional dropzone"%> +<%@attribute name="id" required="true" description="id to form basis for ...Diag: id of diag; ...Form: id of input field used for file upload; ...Img: Image to refresh"%> +<%@attribute name="accept" description="if not null/'': list of accepted MIME file types"%> +<%@attribute name="resize" description="if not null/'': enables image resizing. Currently not supported"%> + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/submenu.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/submenu.tag new file mode 100644 index 0000000000..0e6a3204e3 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/submenu.tag @@ -0,0 +1,26 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> + +<%@tag description="submenu" pageEncoding="UTF-8"%> + +<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + +<%@attribute name="subMenuData" required="true" type="org.eclipse.winery.repository.resources.SubMenuData"%> +<%@attribute name="selected" required="true"%> + + selected"> +
+
${subMenuData.text}
+
+
diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/topologyTemplateRenderer.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/topologyTemplateRenderer.tag new file mode 100644 index 0000000000..28dd5c58d5 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/topologyTemplateRenderer.tag @@ -0,0 +1,206 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Pascal Hirmer - skeletton for topology rendering + * Oliver Kopp - converted to .tag and integrated in the repository + *******************************************************************************/ +--%> +<%@tag description="Renders a toplogytemplate. This tag is used to render a topology template readonly. The topoology modeler does the rendering on itself." pageEncoding="UTF-8" %> + +<%@tag import="java.lang.Math"%> +<%@tag import="java.util.ArrayList"%> +<%@tag import="java.util.Collection"%> +<%@tag import="java.util.Map"%> +<%@tag import="java.util.HashMap"%> +<%@tag import="java.util.UUID"%> +<%@tag import="javax.xml.namespace.QName"%> +<%@tag import="org.eclipse.winery.common.ModelUtilities"%> +<%@tag import="org.eclipse.winery.model.tosca.TEntityTemplate"%> +<%@tag import="org.eclipse.winery.model.tosca.TNodeTemplate"%> +<%@tag import="org.eclipse.winery.model.tosca.TNodeType"%> +<%@tag import="org.eclipse.winery.model.tosca.TRelationshipTemplate"%> +<%@tag import="org.eclipse.winery.model.tosca.TRelationshipTemplate.SourceElement"%> +<%@tag import="org.eclipse.winery.model.tosca.TRelationshipTemplate.TargetElement"%> +<%@tag import="org.eclipse.winery.model.tosca.TRelationshipType"%> +<%@tag import="org.eclipse.winery.model.tosca.TTopologyTemplate"%> +<%@tag import="org.eclipse.winery.repository.Utils"%> + +<%@attribute name="topology" required="true" description="the topology template to be rendered" type="org.eclipse.winery.model.tosca.TTopologyTemplate" %> +<%@attribute name="repositoryURL" required="true" %> +<%@attribute name="client" required="true" type="org.eclipse.winery.common.interfaces.IWineryRepository" %> +<%@attribute name="fullscreen" required="false" type="java.lang.Boolean" %> +<%@attribute name="additonalCSS" required="false"%> +<%@attribute name="autoLayoutOnLoad" required="false" type="java.lang.Boolean" %> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="tmpl" tagdir="/WEB-INF/tags/common/templates" %> +<%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions"%> + +<%-- required for vShowError --%> + + + +<%-- required for vShowError --%> + + + +<%-- winery-common.css also contains definitions for properties --%> + + + + + + +<% + Collection relationshipTypes = client.getAllTypes(TRelationshipType.class); + + // quick hack + // better would be to collect all types used in the curren topoloy template + Collection nodeTypes = client.getAllTypes(TNodeType.class); +%> + + + + + +<% + // used for the position of the NodeTemplates + int topCounter = 0; +%> + +
+
+ + +
+
+<%-- div #editorArea required for layouter --%> +
+
+ + + +<% + // can be used later to call a doLayout() + boolean somethingWithoutPosition = false; + + Collection relationshipTemplates = new ArrayList(); + Collection nodeTemplates = new ArrayList(); + + // the minimum x/y coordinates. + // used to move the content to the top left corner + int minTop = Integer.MAX_VALUE; + int minLeft = Integer.MAX_VALUE; + + for (TEntityTemplate entity: topology.getNodeTemplateOrRelationshipTemplate()) { + if (entity instanceof TNodeTemplate) { + TNodeTemplate nodeTemplate = (TNodeTemplate) entity; + nodeTemplates.add(nodeTemplate); + + // determine minTop and minLeft + String top = ModelUtilities.getTop(nodeTemplate); + if (top != null) { + int intTop = Utils.convertStringToInt(top); + if (intTop != 0) { + minTop = Math.min(minTop, intTop); + } + } + + String left = ModelUtilities.getLeft(nodeTemplate); + if (left != null) { + int intLeft = Utils.convertStringToInt(left); + if (intLeft != 0) { + minLeft = Math.min(minLeft, intLeft); + } + } + + } else { + assert(entity instanceof TRelationshipTemplate); + relationshipTemplates.add((TRelationshipTemplate) entity); + } + } + + for (TNodeTemplate nodeTemplate: nodeTemplates) { + // assuming the topology can be displayed as a stack, else call doLayout() afterwards + topCounter = topCounter + 150; + + String left = ModelUtilities.getLeft(nodeTemplate); + if (left == null) { + left = "0"; + somethingWithoutPosition = true; + } else { + // calulate offset + // we could hash the coordinate in the loop before + // but that would obfuscate the code and currently, we don't have speed issues here + left = Integer.toString(Utils.convertStringToInt(left) - minLeft); + } + String top = ModelUtilities.getTop(nodeTemplate); + if (top == null) { + top = Integer.toString(topCounter); + somethingWithoutPosition = true; + } else { + // calulate offset + top = Integer.toString(Utils.convertStringToInt(top) - minTop); + } +%> + +<% + } + if (somethingWithoutPosition) { + autoLayoutOnLoad = true; + } +%> + + + +
+
diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/typeswithshortnameasselect.tag b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/typeswithshortnameasselect.tag new file mode 100644 index 0000000000..98c1731444 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/tags/typeswithshortnameasselect.tag @@ -0,0 +1,48 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Renders pairs of types with shortname as select element" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +<%@attribute name="label" required="true"%> +<%@attribute name="selectname" required="true"%> +<%@attribute name="typesWithShortNames" required="true" type="java.util.Collection"%> +<%@attribute name="type" required="true" description="The type of all types. E.g., planlanguage"%> + +
+ + +
+ + + Manage +
+
+ + diff --git a/org.eclipse.winery.repository/src/main/webapp/WEB-INF/web.xml b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..8f25d5ceda --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,93 @@ + + + + Winery Repository + + WineryResources + com.sun.jersey.spi.container.servlet.ServletContainer + + com.sun.jersey.spi.container.ContainerResponseFilters + org.eclipse.winery.repository.RestDocFilter + + + com.sun.jersey.config.property.packages + org.eclipse.winery.repository.resources + + + com.sun.jersey.config.feature.FilterForwardOn404 + false + + + com.sun.jersey.config.feature.CanonicalizeURIPath + true + + + com.sun.jersey.config.feature.NormalizeURI + true + + + com.sun.jersey.config.feature.Redirect + true + + + + + com.sun.jersey.api.json.POJOMappingFeature + true + + + + + WineryResources + + + + + + /imports/* + /servicetemplates/* + /nodetypes/* + /nodetypeimplementations/* + /relationshiptypes/* + /relationshiptypeimplementations/* + /requirementtypes/* + /capabilitytypes/* + /artifacttypes/* + /artifacttemplates/* + /policytypes/* + /policytemplates/* + + + / + /admin/* + /other/* + /test/* + + + + org.eclipse.winery.repository.Prefs + + + + COOKIE + + diff --git a/org.eclipse.winery.repository/src/main/webapp/css/topologyTemplateRenderer.css b/org.eclipse.winery.repository/src/main/webapp/css/topologyTemplateRenderer.css new file mode 100644 index 0000000000..f24db2c6c8 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/css/topologyTemplateRenderer.css @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - initial implementation + * Pascal Hirmer - improvements + * Oliver Kopp - improvements + *******************************************************************************/ + +#templateDrawingArea { + height: 500px; + position: relative; + overflow-y: scroll; +} + +#templateEditorArea { + width: 100%; + height: 100%; + margin-top: 45px; +} + +div.NodeTemplateShape { + cursor: default; +} + +div.topbar { + position: absolute; + height: 30px; + width: 100%; + z-index: 1000; +} + +div.topbarbuttons { + display: none; +} + +div.topbar:hover > div.topbarbuttons { + display: inherit; +} + +/* hide the area to add a deployment artifact */ +div.addDA { + display: none; +} \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/css/topologyTemplateRendererFullscreen.css b/org.eclipse.winery.repository/src/main/webapp/css/topologyTemplateRendererFullscreen.css new file mode 100644 index 0000000000..b5535ba769 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/css/topologyTemplateRendererFullscreen.css @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial implementation + *******************************************************************************/ + +#templateDrawingArea { + height: 100%; + background: white; +} + +#templateEditorArea { + margin-top: 0px; +} + +/* + * used if elements should be hidden forever. Cannot be undone with $(...).show() + * + * not globally defined + */ +.hidden { + display: none; +} + diff --git a/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/CapSelection.css b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/CapSelection.css new file mode 100644 index 0000000000..1032dd245d --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/CapSelection.css @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial implementation + *******************************************************************************/ + +div.NodeTemplateShape > div.capabilitiesContainer { + display: inherit; +} diff --git a/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/NodeTemplateSelection.css b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/NodeTemplateSelection.css new file mode 100644 index 0000000000..53b69efedd --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/NodeTemplateSelection.css @@ -0,0 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial implementation + *******************************************************************************/ + +/* nothing special needed */ \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/RelationshipTemplateSelection.css b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/RelationshipTemplateSelection.css new file mode 100644 index 0000000000..53b69efedd --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/RelationshipTemplateSelection.css @@ -0,0 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial implementation + *******************************************************************************/ + +/* nothing special needed */ \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/ReqSelection.css b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/ReqSelection.css new file mode 100644 index 0000000000..f4bcfae3b0 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/ReqSelection.css @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial implementation + *******************************************************************************/ + +div.NodeTemplateShape > div.requirementsContainer { + display: inherit; +} diff --git a/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/propertySelection.css b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/propertySelection.css new file mode 100644 index 0000000000..f3673ebeef --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/propertySelection.css @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial implementation + *******************************************************************************/ + +div.NodeTemplateShape > div.propertiesContainer { + display: inherit; +} diff --git a/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/small.css b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/small.css new file mode 100644 index 0000000000..d7f298c64a --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/css/topologytemplaterendering/small.css @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - initial implementation + *******************************************************************************/ +div.relationshipTypeLabel { + display:none; +} + +div.nodetemplate.name { + display: none; +} +div.NodeTemplateShape > .headerContainer > div.type { + top: 15px; + left: 34px; + width: 111px; + text-align: center; + font-size: 11px; +} + +div.NodeTemplateShape > .headerContainer > img.icon { + height: 35px; + margin: 4px 4px; +} + +div.NodeTemplateShape { + border-width: 1px; + height: 45px; + width: 150px; + border-radius: 8px; +} diff --git a/org.eclipse.winery.repository/src/main/webapp/css/winery-repository.css b/org.eclipse.winery.repository/src/main/webapp/css/winery-repository.css new file mode 100644 index 0000000000..be513cf1a4 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/css/winery-repository.css @@ -0,0 +1,868 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - initial implementation + * Oliver Kopp - improvements + *******************************************************************************/ + +/* override jquery redmond theme */ + +.hidden { + display: none; +} + +.ui-widget { + font-size: 11px; +} + +body { + width: 1000px; + background: #eaeaea; +} + +#header { + width: 100%; + height: 87px; + background: url('../images/header_background.png'); + background-repeat: no-repeat; +} + +#showabout { + float: right +} + +#header > div#buttonContainer { + + height: 30px; + top: 40px; + position: relative; +} + +#header > div#buttonContainer > a { + height: 30px; + float: left; + display: block; + margin-left: 30px; + padding-left: 10px; + padding-right: 10px; + border-radius: 10px 10px 0px 0px; + line-height: 27px; + text-decoration: none; + font-family: arial; + color: #787878; + font-size: 14px; + text-shadow: 1px 1px 0px white; +} + +#header > span { + position: relative; + top: 42px; + left: 10px; +} + +#headerelements { + position: relative; + bottom: 0px; +} + +#tabs { + box-shadow: 3px 3px 9px #888888; + min-height: 350px; +} + +#mainContainer { + border-left: 1px solid #AEAEAE; + position: absolute; + left: 50%; + margin: 10px 0 0 -500px; + padding-bottom: 15px; + border-radius: 0px 0px 18px 18px; + border-bottom: 1px solid #AEAEAE; + border-right: 1px solid #AEAEAE; + box-shadow: 3px 3px 9px #888888; + background: white; + width: 1000px; +} + +/* bootstrap removes scrollbar making the content moving. Undo that effect: + 15 / 2 = 7.5. We choose 8. 500+8=508 */ +body.modal-open > #mainContainer.overflown { + margin: 10px 0 0 -508px; +} + +/* resulting in the same alignment if a scrollbar is shown or not (two browser tabs with different tabs) */ +#mainContainer.notoverflown { + margin: 10px 0 0 -508px; +} + + +#mainContent { + padding-left: 5px; + min-height: 350px; +} + +#naming { + margin-bottom: 15px; +} + +#namespacesListContainer { + width: 300px; + float: left; +} + +.listheading { + margin: 0px 0px 15px 0px; +} + +.listcontent { + width: 100%; +} + +#buttonList { + width: 140px; +} + +#buttonList > a { + width: 85px; + float: left; + margin-top: 10px; +} + +.rightbutton { + float: right; + margin: 0 0 2px 2px; +} + +.label { + font-family: sans-serif; +} + +a.squareButton { + border: 1px solid #aeaeae; + background: #eaeaea; + height: 20px; + width: 20px; + text-align: center; + text-decoration: none; + line-height: 20px; + margin-left: 4px; + float: left; +} + +a.button { + border: 1px solid #aeaeae; + background: #eaeaea; + height: 20px; + padding-left: 4px; + padding-right: 4px; + text-align: center; + text-decoration: none; + line-height: 20px; + margin-left: 4px; + float: left; +} + +table tr.even.row_selected td { + background-color: #B0BED9; +} + +table tr.odd.row_selected td { + background-color: #9FAFD1; +} + +table tr.even.row_selected td.sorting_1 { + background-color: #B0BED9; +} + +table tr.odd.row_selected td.sorting_1 { + background-color: #9FAFD1; +} + + +div#mainMenuContainer { + height: 28px; + position: relative; + top: 38px; +} + +/* jquery file upload styling */ +.fileupload-buttonbar .ui-progressbar-value { + background: url(../images/jquery-fileupload/progressbar.gif); +} +.fileupload-loading { + background: url(../images/jquery-fileupload/loading.gif) center no-repeat; +} + + +/* tabs */ + +a.styledTabMenuButton { + margin-bottom: 3px; + float: left; +} + +a.styledTabMenuButton > div { + height: 28px; + float: left; +} + +a.styledTabMenuButton > div.left { + width: 19px; +} + +a.styledTabMenuButton > div.center { + line-height: 29px; + text-decoration: none; + font-family: arial; + color: #787878; + font-size: 14px; + text-shadow: 1px 1px 0px white; + padding-left: 5px; +} + +a.styledTabMenuButton > div.right { + width: 29px; +} + +a.styledTabMenuButton.selected > div.left, a.styledTabMenuButton:hover > div.left { + background: url('../images/styledTabMenuButtonLeft.jpg'); + width: 19px; +} + +a.styledTabMenuButton.selected > div.center, a.styledTabMenuButton:hover > div.center { + background: url('../images/styledTabMenuButtonCenter.jpg'); +} + +a.styledTabMenuButton.selected > div.right, a.styledTabMenuButton:hover > div.right { + background: url('../images/styledTabMenuButtonRight.jpg'); + width: 29px; +} + +/* main containers */ + +div.mainContentContainer, div.mainContentContainer > div { + float: left; + width: 989px; +} +div.mainContentContainer > div.top { + height: 150px; +} + +div.mainContentContainer > div.top.twolines { + height: 179px; +} + +div.mainContentContainer > div.middle { + width: 987px; + min-height: 350px; + padding: 0px 35px 0px 35px; + font-family: arial, verdana; + font-size: 12px; + line-height: 19px; + color: #494949; +} +div.mainContentContainer > div.bottom { + height: 40px; +} + +div.mainContentContainer.serviceTemplate > div.top { + background: url('../images/containers/st/FrameTop.jpg'); +} +div.mainContentContainer.serviceTemplate > div.middle { + background: url('../images/containers/st/FrameMiddle.jpg'); +} +div.mainContentContainer.serviceTemplate > div.bottom { + background: url('../images/containers/st/FrameBottom.jpg'); +} + +div.mainContentContainer.relationshipType > div.top { + background: url('../images/containers/rt/FrameTopLarge.jpg'); +} +div.mainContentContainer.relationshipType > div.middle { + background: url('../images/containers/rt/FrameMiddle.jpg'); +} +div.mainContentContainer.relationshipType > div.bottom { + background: url('../images/containers/rt/FrameBottom.jpg'); +} + +div.mainContentContainer.nodeType > div.top { + background: url('../images/containers/nt/FrameTopLarge.jpg'); +} +div.mainContentContainer.nodeType > div.middle { + background: url('../images/containers/nt/FrameMiddle.jpg'); +} +div.mainContentContainer.nodeType > div.bottom { + background: url('../images/containers/nt/FrameBottom.jpg'); +} + +div.mainContentContainer.admin > div.top { + background: url('../images/containers/admin/FrameTop.jpg'); +} +div.mainContentContainer.admin > div.middle { + background: url('../images/containers/admin/FrameMiddle.jpg'); +} +div.mainContentContainer.admin > div.bottom { + background: url('../images/containers/admin/FrameBottom.jpg'); +} + + +/* quick hack for new types: just use the administration */ + +div.mainContentContainer.artifactTemplate > div.top { + background: url('../images/containers/admin/FrameTop.jpg'); +} +div.mainContentContainer.artifactTemplate > div.middle { + background: url('../images/containers/admin/FrameMiddle.jpg'); +} +div.mainContentContainer.artifactTemplate > div.bottom { + background: url('../images/containers/admin/FrameBottom.jpg'); +} + +div.mainContentContainer.artifactType > div.top { + background: url('../images/containers/admin/FrameTop.jpg'); +} +div.mainContentContainer.artifactType > div.middle { + background: url('../images/containers/admin/FrameMiddle.jpg'); +} +div.mainContentContainer.artifactType > div.bottom { + background: url('../images/containers/admin/FrameBottom.jpg'); +} + +div.mainContentContainer.nodeTypeImplementation > div.top { + background: url('../images/containers/admin/FrameTop.jpg'); +} +div.mainContentContainer.nodeTypeImplementation > div.middle { + background: url('../images/containers/admin/FrameMiddle.jpg'); +} +div.mainContentContainer.nodeTypeImplementation > div.bottom { + background: url('../images/containers/admin/FrameBottom.jpg'); +} + +div.mainContentContainer.relationshipTypeImplementation > div.top { + background: url('../images/containers/admin/FrameTop.jpg'); +} +div.mainContentContainer.relationshipTypeImplementation > div.middle { + background: url('../images/containers/admin/FrameMiddle.jpg'); +} +div.mainContentContainer.relationshipTypeImplementation > div.bottom { + background: url('../images/containers/admin/FrameBottom.jpg'); +} + +div.mainContentContainer.requirementType > div.top { + background: url('../images/containers/admin/FrameTop.jpg'); +} +div.mainContentContainer.requirementType > div.middle { + background: url('../images/containers/admin/FrameMiddle.jpg'); +} +div.mainContentContainer.requirementType > div.bottom { + background: url('../images/containers/admin/FrameBottom.jpg'); +} + +div.mainContentContainer.capabilityType > div.top { + background: url('../images/containers/admin/FrameTop.jpg'); +} +div.mainContentContainer.capabilityType > div.middle { + background: url('../images/containers/admin/FrameMiddle.jpg'); +} +div.mainContentContainer.capabilityType > div.bottom { + background: url('../images/containers/admin/FrameBottom.jpg'); +} + +div.mainContentContainer.policyTemplate > div.top { + background: url('../images/containers/admin/FrameTop.jpg'); +} +div.mainContentContainer.policyTemplate > div.middle { + background: url('../images/containers/admin/FrameMiddle.jpg'); +} +div.mainContentContainer.policyTemplate > div.bottom { + background: url('../images/containers/admin/FrameBottom.jpg'); +} + +div.mainContentContainer.policyType > div.top { + background: url('../images/containers/admin/FrameTop.jpg'); +} +div.mainContentContainer.policyType > div.middle { + background: url('../images/containers/admin/FrameMiddle.jpg'); +} +div.mainContentContainer.policyType > div.bottom { + background: url('../images/containers/admin/FrameBottom.jpg'); +} + +div.mainContentContainer.xsdimport > div.top { + background: url('../images/containers/admin/FrameTop.jpg'); +} +div.mainContentContainer.xsdimport > div.middle { + background: url('../images/containers/admin/FrameMiddle.jpg'); +} +div.mainContentContainer.xsdimport > div.bottom { + background: url('../images/containers/admin/FrameBottom.jpg'); +} + + + + +div.mainContentContainer > div.top > div.informationContainer { + position: relative; + top: 30px; + left: 120px; + height: 45px; + width: 100%; + + color: #787878; + font-family: arial; + font-size: 14px; + padding-left: 5px; + text-decoration: none; + text-shadow: 1px 1px 0 white; +} + + +div.mainContentContainer > div.top > div.informationContainer > div.name { + font-size: 17px; + font-weight: bold; + height: 22px; +} + +div.mainContentContainer > div.top > div.informationContainer > div.namespace { +} + + +div.mainContentContainer > div.top { + position: relative; +} + +div.mainContentContainer > div.top > div.subMenu { + position: absolute; + top: 97px; + left: 20px; +} + +/** lists of components (service templates, node types, relationship types) **/ + +div.entityContainer { + float: left; + margin-bottom: 10px; + cursor: pointer; +} + +div.entityContainer > div { + float: left; + height: 86px; +} + +div.entityContainer > div.left { + width: 117px; +} + +div.entityContainer > div.center { + width: 500px; +} + +div.entityContainer > div.right { + width: 33px; +} + +div.entityContainer > div.center > div.informationContainer { + margin-top: 25px; + height: 45px; + color: #787878; + font-family: arial; + font-size: 12px; + padding-left: 5px; + text-decoration: none; + text-shadow: 1px 1px 0 white; + float: left; + max-width: 313px; +} + + +div.entityContainer > div.center > div.informationContainer > div.name { + font-size: 14px; + font-weight: bold; + height: 18px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + +div.entityContainer > div.center > div.informationContainer > div.namespace { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + +div.entityContainer.serviceTemplate > div.left { + background: url('../images/entityBox/serviceTemplate/left.jpg'); +} + +div.entityContainer.serviceTemplate > div.center { + background: url('../images/entityBox/serviceTemplate/center.jpg'); +} + +div.entityContainer.serviceTemplate > div.right { + background: url('../images/entityBox/serviceTemplate/right.jpg'); +} + +div.entityContainer.nodeType > div.left { + background: url('../images/entityBox/nodeType/left.jpg'); +} + +div.entityContainer.nodeType > div.center { + background: url('../images/entityBox/nodeType/center.jpg'); +} + +div.entityContainer.nodeType > div.right { + background: url('../images/entityBox/nodeType/right.jpg'); +} + +div.entityContainer.relationshipType > div.left { + background: url('../images/entityBox/relationshipType/left.jpg'); +} + +div.entityContainer.relationshipType > div.center { + background: url('../images/entityBox/relationshipType/center.jpg'); +} + +div.entityContainer.relationshipType > div.right { + background: url('../images/entityBox/relationshipType/right.jpg'); +} + +div.entityContainer.admin > div.left { + background: url('../images/entityBox/admin/left.jpg'); +} + +div.entityContainer.admin > div.center { + background: url('../images/entityBox/admin/center.jpg'); +} + +div.entityContainer.admin > div.right { + background: url('../images/entityBox/admin/right.jpg'); +} + + +div.entityContainer.artifactTemplate > div.left { + background: url('../images/entityBox/admin/left.jpg'); +} + +div.entityContainer.artifactTemplate > div.center { + background: url('../images/entityBox/admin/center.jpg'); +} + +div.entityContainer.artifactTemplate > div.right { + background: url('../images/entityBox/admin/right.jpg'); +} + + +div.entityContainer.artifactType > div.left { + background: url('../images/entityBox/admin/left.jpg'); +} + +div.entityContainer.artifactType > div.center { + background: url('../images/entityBox/admin/center.jpg'); +} + +div.entityContainer.artifactType > div.right { + background: url('../images/entityBox/admin/right.jpg'); +} + + +div.entityContainer.nodeTypeImplementation > div.left { + background: url('../images/entityBox/admin/left.jpg'); +} + +div.entityContainer.nodeTypeImplementation > div.center { + background: url('../images/entityBox/admin/center.jpg'); +} + +div.entityContainer.nodeTypeImplementation > div.right { + background: url('../images/entityBox/admin/right.jpg'); +} + + +div.entityContainer.relationshipTypeImplementation > div.left { + background: url('../images/entityBox/admin/left.jpg'); +} + +div.entityContainer.relationshipTypeImplementation > div.center { + background: url('../images/entityBox/admin/center.jpg'); +} + +div.entityContainer.relationshipTypeImplementation > div.right { + background: url('../images/entityBox/admin/right.jpg'); +} + +div.entityContainer.requirementType > div.left { + background: url('../images/entityBox/admin/left.jpg'); +} + +div.entityContainer.requirementType > div.center { + background: url('../images/entityBox/admin/center.jpg'); +} + +div.entityContainer.requirementType > div.right { + background: url('../images/entityBox/admin/right.jpg'); +} + +div.entityContainer.capabilityType > div.left { + background: url('../images/entityBox/admin/left.jpg'); +} + +div.entityContainer.capabilityType > div.center { + background: url('../images/entityBox/admin/center.jpg'); +} + +div.entityContainer.capabilityType > div.right { + background: url('../images/entityBox/admin/right.jpg'); +} + +div.entityContainer.policyTemplate > div.left { + background: url('../images/entityBox/admin/left.jpg'); +} + +div.entityContainer.policyTemplate > div.center { + background: url('../images/entityBox/admin/center.jpg'); +} + +div.entityContainer.policyTemplate > div.right { + background: url('../images/entityBox/admin/right.jpg'); +} + +div.entityContainer.policyType > div.left { + background: url('../images/entityBox/admin/left.jpg'); +} + +div.entityContainer.policyType > div.center { + background: url('../images/entityBox/admin/center.jpg'); +} + +div.entityContainer.policyType > div.right { + background: url('../images/entityBox/admin/right.jpg'); +} + +div.entityContainer.xSDImport > div.left { + background: url('../images/entityBox/admin/left.jpg'); +} + +div.entityContainer.xSDImport > div.center { + background: url('../images/entityBox/admin/center.jpg'); +} + +div.entityContainer.xSDImport > div.right { + background: url('../images/entityBox/admin/right.jpg'); +} + + +/* buttons */ +div.entityContainer > div.center > div.buttonContainer { + float: right; + height: 42px; + + margin-top: 23px; + margin-left: 40px; +} + +div.entityContainer > div.center > div.buttonContainer > a { + float: left; + height: 42px; + margin-right: 5px; +} + +div.entityContainer > div.center > div.buttonContainer > a.editButton { + background: url('../images/entityBox/editButton.jpg'); + width: 41px; +} +div.entityContainer > div.center > div.buttonContainer > a.editButton:hover { + background: url('../images/entityBox/editButtonHover.jpg'); +} + +div.entityContainer > div.center > div.buttonContainer > a.exportButton { + background: url('../images/entityBox/exportButton.jpg'); + width: 53px; +} +div.entityContainer > div.center > div.buttonContainer > a.exportButton:hover { + background: url('../images/entityBox/exportButtonHover.jpg'); +} + +div.entityContainer > div.center > div.buttonContainer > a.deleteButton { + background: url('../images/entityBox/deleteButton.jpg'); + width: 33px; +} +div.entityContainer > div.center > div.buttonContainer > a.deleteButton:hover { + background: url('../images/entityBox/deleteButtonHover.jpg'); +} + +input.highlight { + background-color: lightskyblue; +} + +input.qnameinput { + width: 600px; +} + +/* fixes wrong z-index of autocompleter in jQuery UI 1.10.3 */ +.ui-autocomplete { + z-index: 1000; +} + +#warning { + color: blue; + font-weight: bold; + cursor: default; + float: right; + margin-right: 10px; + /* 0px is required to have the tabs below not being pushed down */ + height: 0px; +} + +#constraintlist { + cursor: pointer; +} + +#searchBox { + background: url("../images/searchBoxBackground.jpg") no-repeat scroll 2px -4px transparent; + border: 2px solid #BEBEBE; + border-radius: 15px 15px 15px 15px; + box-shadow: 5px 5px 5px #EAEAEA; + color: #676767; + font-size: 15px; + height: 35px; + margin-bottom: 30px; + padding: 5px 5px 5px 70px; + width: 660px; +} + +#gcprightcolumn { + background: url('../images/overviewShadowMiddle.jpg'); + width: 35px; + position: relative; + padding:0px;" +} + +#overviewtopshadow { + top: 0px; + background-image: url("../images/overviewShadowTop.jpg"); + height: 269px; +} + +#overviewbottomshadow { + bottom: 0px; + background-image: url("../images/overviewShadowBottom.jpg"); + height: 269px; + position: absolute; + width: 35px; +} + +span.cursorpointer { + cursor: pointer; +} + +div.otherelements > a.btn { + width: 250px; +} + +#bigIconDiv { + height: 50px; +} + +div.colorpickerdiv { + height: 35px; + width: 35px; + background: url("../components/colorPicker/images/select.png") +} + +#applicationDescriptionDiv { + overflow-x: hidden; + overflow-y: scroll; + height: 200px; +} + +.XMLtextarea { + height: 300px; +} + +div.col-xs-4.bordered { + width: 32%; + border: 1px solid #DADADA; + padding: 0px; + +} + +div.col-xs-4.bordered div.listheading { + height: 36px; + padding-right: 3px; +} + +div.col-xs-4.middlebox { + margin-left: 18px; + margin-right: 18px; +} + +div.col-xs-4.bordered div.listheading > button { + margin-top: 3px; +} + +table.dataTable { + font-size: 12px; +} + +table.dataTable thead th { + font-size: 11px; + color: #3F3F3F; +} + +div.titledTableBox { + box-shadow: 2px 2px 5px #AEAEAE; + margin-bottom: 5px; + margin-right: 10px; + border: 1px solid #aeaeae; + padding: 0px; + margin-left: 0px; + padding-left: 0px !important; +} +.listheading { + background: url("../images/header_background.png") repeat scroll 0 -39px transparent; + height: 30px; + margin: 0px; + padding-left: 7px; + line-height: 30px; + font-size: 12px; + color: #606060; + text-shadow: 1px 1px 0 white; +} + +#names { + width: 200px; + overflow: hidden; + padding-left: 10px; + float: left; +} + +.listcontent { + border: 0px; + width: 100%; + margin: 0px; + border-top: 0px; +} + +.topologyTemplatePreviewSizing { + height:400px; + width:921px; +} + +#topologyTemplatePreview { + border: 0; +} + +div.policiesContainer > div.header { + display: none; +} + +div.policiesContainer > div.content > div.policy > textarea.policy_xml { + display: none; +} diff --git a/org.eclipse.winery.repository/src/main/webapp/images/back_disabled.png b/org.eclipse.winery.repository/src/main/webapp/images/back_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..881de7976ff98955e2a5487dca66e618a0655f3d GIT binary patch literal 1361 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S1|*9D%+3HQ$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%u1Od5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|80+w{G(j&jGsVin+1c5}%-r12$=KP@(AChw*vQht)WY1&)XmVs z#Kj1v*Cju>G&eP`1g19yq1OVZUQklVEdbi=l3J8mmYU*Ll%J~r_OewbZnv1?G!Lpb z1-DzwaO%|uIz}H9u}BdO69T3l5EGtkfgE_kPt60S_99@i-f{BMZ3YI$qn<8~Ar-gQ zOt$tu93XPMc=CmoA1oW4o1+WYIB!k3r72K4*@xA>;l+b1ClB@qaOE!8@r8RwiN1wc zl+_Cb3(lEQAv#$bmh>Mfe(I7Woy4{G!}EFf?)^FUc%F02^;EH~5owLt3k}+qS-P)U z616t%^wT0PX2liq$807FHoQ4d$0`5rkQ{U2Kkgclu0)Awnd5T>ob((vrABTq*u(RS z>E?oy`!@uw+@i*D$dKV&#I(EL&;9;u$GTQAMM5faVZejQCzo(NvvlZ75dZt%IYnd( z*RL;GX3W}R-P)5>-Zsu`&nUT&Ho^GzHq{#}Ya$hT91>M0@O`!9^}b&yQ@87fac$Vj zkb72h`!2pMTYunpu!r@;1)uFRXDvHO zu{mw?PmW#JOy1f}J}ILj)G2cQ^TrhhTtyr5@7eCYm=Uoy?6qTPsOnt5?2i>S(pg>~ z>M~M93=YlxcD}*xKl_@hz5j0IZGT@9Yu_^8_RN8=&YkAdFR(fGAAWd4CvkG#0^hlN z8>(g;?I=2=cEEAHaL+WiOvRp~fl`n5dTf5V)bNv|ZcjyzLHRnz@2)SdPWo#3tF@Nf ZfT6u;&2Oo-XD5RSIZszVmvv4FO#nm}^+Nyv literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/back_enabled.png b/org.eclipse.winery.repository/src/main/webapp/images/back_enabled.png new file mode 100644 index 0000000000000000000000000000000000000000..c608682b04a6d9b8002602450c8ef7e80ebba099 GIT binary patch literal 1379 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 HD-Zt*o(L(c literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/containers/admin/FrameMiddle.jpg b/org.eclipse.winery.repository/src/main/webapp/images/containers/admin/FrameMiddle.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7aa2d8f636c85ee8327b1b1bbe4eb8b222a3c98b GIT binary patch literal 1579 zcmb_cPiPcp6#pi>YhwuFHbuQTOb$Wq&dj&7e`ZG4ba!XRG<2@!NHGvtp1Sc`)$4 z_r2fyz4yNNCR_}c!JblJRsa|t-VeILx`amm_%6_Z^wzY>(9p zJdRi$TU?+y9AtS892yK9O|K%K9!C?Vonuyiy}{6?kz>ZvWxnhb(WE&v=b{sHM@RL! zsxBGK;9>euAP1IXAzz~dYufhYAjdR<%S5l6Ifiby_|+Vfud~u8%g5;=b`hOs`Gn4A zAe~9EFvUwL>0>&{L!N_4j?X3_FQ>CI59y{bgv~W7@`$1~xyUKUG>fX$YHUqlu{*&* zNs>4|$t9Bs;*s!XZC?u#w%6Z^pde3oO~*H}P1hr8<9No;F(lL1C0I_m+zz~9w=An( zSHs)$N6>m28+v=Avku}$kcVen9TE5b7MS$z-9&Xql8t=KHOZrB(+bvSEM)t`N{%5n ztYI2*L4c`ZDU;2o6utx@6bn*8%nHejs0b-2BwH~y!m6rJ$Us$6peRCEf_YU^B|*p* zm5eI#D&N8m+n%r4I%@Hngtv(m--(rrF4BDLj$%CBnt8F; zt3S`{Y8B*~Um!zuu|+rfE1MheE2T^(sb)oyS4id%N`jOw74mtJFREfGm13G$<9&L@ zkz}~~aC8hy%S0xyuC_;?9NNo+Y_c&fS&eW7>}U);Fm93+q{0W_D?n{ty4EGqmL|N5 zqR1`z+83Ku!kZx84R%MCB2*l7#i>Y~3V#EiHxgU_e-N!Z)A<%yKAY+ZI>K$O z8lA74e_nme&R+li?6qxs`+u1_{mCC+Z(qAzn_oQE_w4fBkN(?Q!j5R$cikCV`TNgP z|9^QP=Jy^xGIaOhnV)<6{{3Nf_r;$Eo|xzM{nO#Swd#k7A1^FjSh)IV?bDved&7IL E0I?Qme*gdg literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/containers/admin/FrameTop.jpg b/org.eclipse.winery.repository/src/main/webapp/images/containers/admin/FrameTop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3abcd7dba92f41e1b3aef1440d7cb7f6e9ba0a79 GIT binary patch literal 30099 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 mV~y!p;e<^bBQzxxwmCo;qU literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/containers/admin/styledTabMenuButtonCenter.jpg b/org.eclipse.winery.repository/src/main/webapp/images/containers/admin/styledTabMenuButtonCenter.jpg new file mode 100644 index 0000000000000000000000000000000000000000..06867f425a16ce72daaf1ac9f60a131565ac0271 GIT binary patch literal 1625 zcmb_cU2NM_6uwSMC}My~avo8{1vd z3Yex9HiinCgv0}y3M+^`>|xVhCV1Ewg$EGgM-}RTiM10F4;5obpdzZ7n=DC-sHP2Z zBunR>d(QWrb9~PA7Q999aHgW~1E8;O7ia}*;w^)aIIa{Y00vr+Sp~pb^qU3OwFHth zoQSNNc`c%tC9)!0B#clb*qy9cvQpGsJg<%FMuNEZ;duhr)dVpT%Tie@trhg%Nn6WJ z_75wQMTJ+1WH-LMB2-FNNpoeqQW`THp^_kK-~!UCW|F{bE^aYFq^hj=-s~PcZQ2?h zi%?;OibFikL?A=)4Bv&*6r@N{h8%t*hqkxI@}n8XI~$!xNT94rz`#ZYvsc?`#C4-rbt0>WH!t25cSu6nRWEmGP2h zxP4-RKsOOpSB0J^WYU>9n_@&N10m#k_#Tdp(s53VGB8RvFgA*nBpR}m#EOvPAk4s& z#7lfM%BID*#8DE}i0v~RS2h%_!K)+QdTjibu|nF`WY@HZO>?X<0ecFjYdQtf!qd4} z1mYvQp_*l<`g?9xD{8jBUsEO9EaA2O3i<~8VkRD^C6?nT5oHb`ALV12o>YpX(h`?p z7@{7l{+FJSC>gRk9P5UqVL}sFRhy%a4$bA!474#eS`F_Pu(>wyK)rxg5c9qVQvkbt z@vVu!DfMt4hM`;ZH7{;g@h*T+E7%4MKNbSM5athI-W(W3?}Q&)dq0pCxV!b<8rwgt zEq4Wi0P_X>>#bk=uwy53%0sg)J3{}ul-sevch30k&+mB5`wnbEEWVIG1d`y|mGu}% z4_=;WU-|02Q@uZawts8)&g*X%gEw-gFI`Vg`}ZFH?fA=IzOq{Am`lE~9Djb`>Qmot zUwvObyL6xJ_r*41+u%8Rb>~9r-Skm5@a)uI zt;~_;ZGQZREibk&c+=y5`@y{2))}rk{Q_)_G!f{_5b;7rj59 c{GFSxoE;K&CHiBJbj`nZ^!5MKA?IEC8?P?&1^@s6 literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/containers/admin/styledTabMenuButtonLeft.jpg b/org.eclipse.winery.repository/src/main/webapp/images/containers/admin/styledTabMenuButtonLeft.jpg new file mode 100644 index 0000000000000000000000000000000000000000..507e7386c2637753f459b1f62b10e4794504ac30 GIT binary patch literal 1549 zcmbVMe{2(V6#rhYU56T28JiOjkJ}cap}qTFe_o|7ZLc?`cBAbUOa_{+cWk$)%s&_rk$Nrd#vcnIzT}ec z_r1@1pZDJPz03TVnFJMqw6Fz$y1K_eF_@RkpTNW8Wpw^>oB&4zGCvTbFjHySyt?s;0DYu z$vkGakmeZafSAK(fi{x1(Q7e^gd_nef^?c8>9#xFB*gN9Yiu&N#T{nYJePL!;Q69b zsgxyUwMcR+0cn~hNQ$5+vxYD$-J%*zn?FpBY ziC}Op@Pgfn$Fp_i(25%7=hIjatu%Hgcp}UzQc{lb8oaXLto82hL|LGgjk`e>v`2|{ zGEyuV=S8)S@!*=p!U>$)XN5L@z~S`T7%~7MbopqX%W0(?F2-tuR;mzVAzzlIpp#^+ z40O353_veSv$WOf^fM0DMY3eUw@y^ls2Jl5yn@D?_oeRY>-NihRF&jLN$M<2z=k$S zm6SFqf%zkL3&b`GA}6Jk?DO2Nmf>aLd7fisDURj(>lPN^X95lf#X4OslF>4UkhaqH zfY0l7k$%<{u-WjuFZX|XMrg?p+2OcjSPCj_0<*`t(bq0>%fpM>#>m=gWUhe4xq%1V zF>M8r%uirDK<-_1^McMv-d%?vnpOMe4EK7-90R6euo9G_hzaOS2x>wyC%}$eV)OqG z0E|V&_aOk)`0mu|4Z0#@i3Tpx84ZgH799diOHo5nseU!|`j(X&LqAaASl8~u`y>5T zWlbi4pgPp3M+=+IKV>G)FU4Mq3K%MQ2fFRL5KP((`#HGvv%)p2R$d}OMx z7yqdI^qGq{D|Ds%K7D2M+&epusN)S>%TT}YHTExUG-qCvAm-1z1^{s x)2U7W65{aLlQ*V6{%x?ny?gZf-s`1fUw?SuE%qkSd?CJdiM8hR?6sQA__iD*gJ`vzWPu3D#$*W*8nxC3 zI@&fi>U7X4K3i$6V>^9_C^)E;GIWYmjoLwRT3cv+R9mebY`Vb&{J}V#o|&D!_nz~e z@0@ebxzR|p7i1a(&JqA}bEg6U7?$X7KxnA6m#+X2NMes207QGabQ!~V2o!bu#H53^ zQDQsoLIb1+#l;v3X3PqBNP9WOz&5JX>DC~(jx{5&)1g7Eax-T3=&3U2OVwVgpn6`R zy}I14b|AB6!ZQLyz~ymK3<(EZ6>c99&>(}(33eSjMiF?>gelh`+88TbWX^;2w3mYA zVoYSm6gaGqiE$aGmZ_(~5)8*sT!Las5sndZC4u2^To9Jc>nI`e4W>93yVD@?q^hc_ z#8px;?JY%dwOWm05>z4)u@)lV3O7RrL~dVp!h?bG*}YB=;#yt-IIx8hHNy%e6N$e z6tcoV+bdm^o5?k35LP30I30veip%syg;FasU`8CrRXVj!rIbn(DuYypOC<>(BVkP@ zsZN2La09MV;kXgkn$#w>RI1b)6ebmB!V=hAw~ry+b}GT^WO?IQ?1@-H@1;nF_7>7~ zMWO@p%4ml6mC+tpUmzFbu+`~y&{e+J^*qYfKzW^h%3<=-E_krMgmVObgHfT7n3O6N z8$m2@wNx!P>a#E8?*{=Q|;dz66A2w426pe?-9xjqK(%uWxUK*)LGP*k`Ogm;SD5;KawG?gF9;BEO7$bf~Av ze?fit583mUvo}+pyWB&8Uox+LaxAN-qgcqPf#u0xnCdTT4*vYkw(qxj24+X>C(4Ug zc9*P4pK)St`!sz+>Z@1M39aeY#2rVM%ip&vliLR(-)wB?y1RN65&S%>NVK}XuH(G1 z#}eAKZ;xPO=BFb4)Y{q*_1;$EZ|msD*B!3oQ)bRKhTFUP^A6pp$vxUp5jLlf3-3I> zz#7_lxaN*=@vd_zLDkz>iQrn(SN#j_SZ#H+%FhZy8_sNKT~v#&xV`*-hSOIx%T4ez$V+7&Ups<{LQ6X>VBwbybbwNqZj`Lc|S}% literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/containers/nt/FrameBottom.jpg b/org.eclipse.winery.repository/src/main/webapp/images/containers/nt/FrameBottom.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6adfebc282c36367566ec6e6d80f1d65f759b464 GIT binary patch literal 14574 zcmeHscTiJn*Y6G>O;7>`0YxAP(jg(#L+{c=y7T}+A_7X0UMv*pNR!@s7ZB-6mkyyG znj*dTUT*Ll&-rHVJKx;7_n&+3_{?OovsYhxt>3er?2FNh?*NsoGui?G?%!tv2!Vgs z#VP=naWu1X0YCsA_O>|yTztp1wRCWJCd|!kW6y;&w>3p^nb}%%J0qWQ!?<|30TFTM zXGk+Elmopf>M`0z6uME<0HsHpi$ZnyRCrXLNuw;$3a)l24Odl7Ggm7!A#

7`=$I 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 s*ZWU*c6~T8wdCTdMprXPJ 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 literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/containers/nt/FrameTopLarge.jpg b/org.eclipse.winery.repository/src/main/webapp/images/containers/nt/FrameTopLarge.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0cf4f2710e8312c809afc2090f3c60c88da6b1ba GIT binary patch literal 31898 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�^@^|lngxJ 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 literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/containers/rt/FrameTop.jpg b/org.eclipse.winery.repository/src/main/webapp/images/containers/rt/FrameTop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0bb76f1a82fe5ec5d93b199d07d18c2b5e5a8ae0 GIT binary patch literal 42281 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 A>i_@% literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/containers/st/FrameTop.jpg b/org.eclipse.winery.repository/src/main/webapp/images/containers/st/FrameTop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4c37ebf75da9c51ddda7f42a97fab0e1e649f261 GIT binary patch literal 43839 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 Va58sAl@uo3Vrh)RIJ{re{{f=%-Gl%D literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/admin/center.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/admin/center.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b22c1ffe2ba79fc0c3c0477986dca380d8b89d77 GIT binary patch literal 494 zcmex=C5UDGKfoZ!!4Ss4$IK|mz$D1XEXer(2tyvk zVL)fX0V_KP7b7E_3uOo}FfcK32_p$J3bQ3L1#M!U%p!6{;zQuXg%^b;T?(1PDjIq< zY#O_GxFCiZ|8FtyFf#%zXBK3zXZY^sefGwHzrTc<@IPU^%+@LXC^$MhmoCA)?} z)cJ$Bv!`x+?2OvxT~w{aO}j-7d&j6wbRdD<9m3s)sU#5-^7S|C<0^WparC literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/admin/left.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/admin/left.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e9e6559723343402feb191b2efc0cd16ead74df7 GIT binary patch literal 4377 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 B>*W9d literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/admin/right.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/admin/right.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a1d34b4898cc2f5f391ee9c9847668e0e2e4fd61 GIT binary patch literal 1257 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 literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/editButton.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/editButton.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0a58fa4efecb4470b0b5980664139c01d0514ea4 GIT binary patch literal 1299 zcmex=C5UDGKfoZ!!Jx&U$;>Foz$D1XEXer(2tyYG z1JEo+MxZ;PfP<5jotcG=feUOSOcYErGP4LUFfuc-Ff((o@I#~+nV4Bv*%$CA1X{z$f@~Qhlc1p^v!akvVA20u z3_Q$?K!-64GT1Zx?%At)nE#f~`6QDa`LTvo7oTo8(DjD{;AOJoKU@0XO>pC8ZMmd zQOUd8uKGm5p=HMk4@CRST%8$H6p*_`_YjwKn1lHnzK`$3p55KL_S))@9^cKAF2B6} zZPJ$;pVl#|{wz#8G1q<8312H&>ATIoHmBDc2L<}HO=&yU#G-cT&blkxC;gl--P8H2 zg_e!Gkj9q-{tVT73UjxY9GC35lw)iA;(Pz~pN1leKeny@vpG-mGt;M+u_p6u*w@@S z@|nHehUtUr-|K;%lP>F;-QJ{fs`gNu;*q{v^Cs&#@2M($ylJX#dY?m)x?*p7%5nLa zljC%1hz zU1AEF@`TBOnN?t(=<9mRy?I)Vk+xa0*wU51m;BKES@GGAasJoi)o&g!*2{i1b-c;y zbtU-X&KF(hZ8n`bDf{jYlm6~@5; z;p#kN?^WTd=Syegvua*TRxw=iTI&ScRkn?Mw-z5*blKFDk6ANQYEICd!kW94&qW-g z*X{6BZ;*V#;K9H$>3u4HR<+;a`H#={F?Lo+u9RGVZtA>6Umep8il0g;Rla(2!0dj7 z?f&@J39Rv=yVK1p%2uV$_g}5luNW#JYF`s$Y?0CMXxcWR!$ry(norg%tc_GZQbR&Z?5i*6|??q*|v!JWXBTLh9Y)P?bG&49tp>lyU*tpzxZuZeS7!< z9?{M?iT6vZGo8PuCP?%*=WbkoLuZv~sCTKGbAP)x>%xVJoL(X#ONEv!-KXAGm&0uG zy6^kV11=%|B;!j@#@D_o`t+^xw}Hr=`yKH=?%QX+PB689`a$kL!}J5?VfzjLYM=a2 Q^K)M9yg97B4gYTf0Io&)YybcN literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/editButtonHover.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/editButtonHover.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2fdfc349bb9334a134571e02ed5a66c07bbde88c GIT binary patch literal 2350 zcma)1c{tRI8vgyv42HO-}AoD`w4~xlYo?ioxL3Z3IRaib^(GV zK-z|YxfBI}02KH)2?#y_l9qv?=pZ2Q`8ERzI6wjb{&NWZACSNCms|)0x3Am%_u-!o zg6Dv=D4+#sLO^LiNE(DlgMv<=2>`aeKyW+fUl0)$h6_PqfEWmXPzV6|9}fT`fUqbW z0)>G>Vp0GIfq+n$i15z;NsL05Q=vlf2h~f|GyFZpQEH-!}uRv-aK>wE6 z!B({%OfbqZ_T04{02G2kpdv6~k^lH_%cY^f_9i1Ms-jn{?-r0D_eLI$Z#w9nvubIj znqX&up#)~z8Vg2&9T0FkKSUa^0JhRu`;(_z&9&!0R@h|Z*zB|;{i(k@oEX~jN9r2c zf#bKB>_D_Exp{o7(OQjFJ3GS|OY_73N;0;a`ChZgJJtCJ)kwSIc{DX^^fLWb=_OTf zr|8}u88a{R=~cd7NQcEt)3a6jtCGb*ZpBx=$y?K?FVXmZa@qx1`E~_I=e9_RKlgc* zSLp1*j$<8)QjTy{9dSr;Mazm&VCWq9*10e~UDcnZ2MspbAO ziSj1QwEc6^c&lF%;t{p4g+H`wIo-Y#=Ub8Q`Nj0EmCPV6!qyVMjsk*7@e4!;N zL(g^W)al_hD1V@4Q0b(DHaph}+Sx5YT?K7xi7Hb;Ro?gpPA*pCc@hcBo>8T_#8-5prP z)JxUFh7(gLA0a3s*9o2`npB??SuFifdu*)S?BNTV=j!5a!wNEA3mKh)b+DAc_K#Dz zcgJ52p8!>~Ru_K%>}WElfayP3d&KcUQ`tA)=2VFdR&1@)`gC_zSW$5EY1g-BF6#|D zO4KF!qj~dAiP@vF9YeAqHk^Vi)Q6{!{e6N=6SN0>xIN4;`zegeY$_6=SUs7o^`bK2 zHL|~qk>#|!mg`saIHrv`*Amlc^p<-K?i3_vn(B?+>#f|9iNB?0Ilc>aE5c;b>ucZK zD?K?54acOyE*~UXF)xV~149>G3Q;8P=xm~lh7FEaDiK@B>JKfs($HHSncHEvJ2G~D zvuEZzYVtw`F}?G$03dWO9fjT46VyPdyI)$hKA%Ku{QUKv^bK^u597|b_wo80E-!<< z-c~|MKMf9aq>YVw^oNJ>GP=U*9PpQ>D9WTv-#DivdwB54h)ho!IR$yxUDZ2e)Bh?p z^(W(Rlrmq+x5%ve4WaU-25b6GCEOh zS*>u*B1g`HoQ|$iTMvlsr-c5v_C+@)BCzZeV|R{I%{QV+AH|0foQ?|6mMVpHsi#+I ztnvq%=ITy+h|o~tUa{7Z{pa~Zzq__{oEX3b5g}&NH)7z_L z!`P=}?47D$c)gs2=?(xZyo1WzB&dTpI8qJ}lQ{1|Pi>@8)4KaLc+^BA$5S{>!P-WT)=FE@N!>1t%`~RYOd7qh`#E*+<)L4j?{{8osuUl9&uXYYq5Js8Tze(_ z5VA6kizUZiRS)vW{S-Bx?$yI?$Da^r^_b?pbGoFhv$K&BhU^xzxxQpt$?3fV zs;Ti}2W!&W@0B^>fvi@|iAq)&A~K-xm|Wq)$uRtCfkq2y+L7aN{w-q@i6*O3&V

  • bIXSA_&gK8FRZh3d}lm!3njtxog#b`Pv#o5?lG?Q zoqfnmx=xI=Zs_u*bEO=KZcL{aX^no4*<$0LUEKyJLJ8MV`_Fb&sWXnb^~fb-BvlXR z5fPmp3l2klVG{2Rf;sWVMYaMLfC(@!)Kh7SnRS5`i~W`M|xo4nZu)d)MpI z>6~fUNq4YbkU1j@m0lz%TX;0NlvF=EG$1A!J3uQo4y<6^ZA>%Gxj z!`<3o$LBUcs+Fkm?3V&SCr(i`_CVSG33gnb`7xzlV{^<4XzZyz#5=R;pH=U;=bdLV z3b|>RAL#E#^c&cFZ7sHje(1(r-Rm#D+tWIr#fAJUmcF!bm*h^$PUMJLJ12N_Y1$;v zs7su;4<-4F8eeB?a^1QvUvWp4Sni1nP@=;94pgJqZEkl>7dRn40rb+N9Cem?$cLi_ z+n;9olM#;A`<1e%c$InY@|p@wzCI=E>4xo5+Cm8t`sJ$DS literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/exportButton.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/exportButton.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b1ddd75edd0739d47ad4109389a9635ee7f0a63c GIT binary patch literal 1321 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 O?CO$l$_h^WzX<>ZRhbU} literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/nodeType/left.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/nodeType/left.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dda69ce419bb231d2357a3584a84b700a4ea721d GIT binary patch literal 6588 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 literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/nodeType/right.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/nodeType/right.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9d796c9fb71bb691979d559c8a8544a553ed6217 GIT binary patch literal 1729 zcma)1dpOez82@XLK#&z6 zodOU$PXve301%J^zL9`*8dz;lpau~ELW7I}rTxGK0Q`Bt{sZ&_|E|M8P^QZIhw!t5 zv;jaU0^Wcw1R?+!0)!Bt^Z_9FCl~;OWI?|}Q2{Ow$iblHpp2DWUE*brKmbfmUIDHw zn;;O9hcDCoE`l&f4nW8&=&HayRipTdruK*RxF;;*D$P)P)%FpvGZFa?L06v!GuTxd zEp}!UcC7It7OCrNtd#`;VW5KIie*b@Ko|lt)wPePl#@Rk_e90)IM;l}^SAuQ5r^}t zD6C%4)4go5ngv=x+6SzJWC;-v0@x0Gc`5};KU&SS)<=@^4AN61+Y7vnQ^UgZr}ky_ zFUP%Ac4{Z7B)t%|Osv*2)Lic(5~Nx5?rsf4*9m^TR?z4+G7wAhH(aSVW|DwTv`o++ zH9->%^+%YdTt}vsu8Q$%N|A(tsxmTft(z?0O~!DaQ$Ubhx*=~Jq{`tm%#oB$&$h+@ zl~O=4x%$ntl3#~WJD>3g|Egwl_V6Mux+Si6s@T?=zs7u1o>}DRD6cs$aV=asbpVI4 z`CLIY>s_@SdEE~~jk>z3K-~IZ@HkH})2MYOwfl4h`gMq)C-CC&nnIlE;2@?sf=rL{ z*>U?-u$@}py?&7;8;_4)-}!KxWcbO@$j#<7VP0t|c9ZoV80uZI<|5lTFV>lCnGrVx zE390V!|&GSPH-$n(I4n4?xhB6LUm^eQ}-$M%Qf)%c%0k{W#4ebM8|%#%dGjqOtLd) z7WViNW6+Hyvd1SKPOT_$45@oi^7)bp;haq}L=+fu#}}|_y=Mz+r^V_6)*l_QNdkvY5^7^y z81FQZagmMtvT&$$UR%y=!z}FUBPU6Y;48K4t}v^_xj3Zf%nc-+*X+L9Ryj^QtK|E> z1D(uW%4SNa!)&AK=V{9u|!x5cOh54g2JLQKHAztRq)mYs?9_| zC9&*nA*IKT_07@e|Bn16M)hidhCYL87WMXHR)uBJu>l@Uy{AU~Z?W!J$^Mf9A(PWB2fN{2Z%nhB(s$}aeR1sC zb_W*}Wjr66egH#aJGM9F+u${;4g6zobSD)@YNoyM?rZIgs@RixEd6pLK4Q#LY$D8< zOfd>Un_P5zpAq|M7&OFvB006!4d~|9Wzfju(Mr$#Ij_ZQBsGp!M~<|Ii&;b+tWf|d zbSI^!%6!X}Yi$+TDyl^OjNQX}HxeU%a1eW-pr0m=adW-3wQ=O}pD4MQvmUbylSvQe z?(wh%GR8KnhI1KAKeqGnfJ3?nqE5>eKJA*p9-MOmI@Dtt5$Q15+p#d$c@!T`Tjgz~ zKHE=erayjBUB$7IH{vgPxpKlg#X=U^`e?Cd0q@=iGkCW1)}%S17TSO$a_ypL!7}B> z%)7`c)j=&yX)3slH5$5iLwxt>9CL9tYcC%CB|CE9*fGNhcIJ)E`dR+CKBk{bLng#C zSf_e|k@qGSV;NMGh8^2XVxL#|%9PmM_+s*`r>uU{g_lx*Js)Fz`Q?UzKpIL*309JF zaoju?@4)Zjv{#oa>FAe;MxX;NHtC6o0=@NabmW%(V+EhvoiATon-ddu{`S|!y~&6H z5n+8wUx0%@N*H0xReaaR;HHHlv$!;2e?rZWdnk+IqsK1Eyybc8sheQT0V(bM8(Dwi AJ^%m! literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/relationshipType/center.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/relationshipType/center.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c66dbf0e1188ee77c115c1acdea4aad51c9da4b0 GIT binary patch literal 584 zcmex=C5UDGKfoZ!!4Ss4$IK|mz$D1XEXer(2txr%Elr9q?x#ck;EB=*%E^`F;8X@VZAExA#mbCCZS1} zf>Wkk5e*HSCLYcq$OsGPih)9n6Pc8fE(r%O25L+!Wcz=Mfd^UMZP5s$zQj0TKs32`>f=7;j-j2vsjC>YwozM4?P=xGdEbX W-zY=$?Ap(Tyg~a;XU&ZNe-i)+>6h04 literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/relationshipType/left.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/relationshipType/left.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5945f801ef7305bb23133f57be79a0628081fdb1 GIT binary patch literal 7282 zcmcI}Wl$Sjw{C(%i_2Sz7q_;!d$HglXpjPh;t(7{X@Md|ix<}b0YdTM1xkuTA-JTt z7PpoPm+yRczI)HV^XEK!_RN~+*=x<(Gi%nY+52|>b`?Mc($Llb0Pz5T7k3MA`yD|2 z%-_K+7ytwi0RBY+ZjS&IDlfe39RV+T?ik?h65uTW_&*2U{{#Mi@PFO$fWSNTZvRL4 zpBlG40BRC|DZn2eNDaWF2I5l#Z~FmLclqHF1MkxO4~R*C_ymMRq-1zN01%(>ziB{1 zB0PKoViHoSJLxV5B0_RC+|| z3=c?8!Y9G04O3!jGp4g<_7PmqGV6PNO2i@l7#`|>$0H^pxlcg+U-1BV_|ya(ghV1n zG$$%{;g4vEVJVZM_H@Pdy=$te5PGmrM8g!Pm~o>Y14&=0xP+Q-0a{dCsy%dMy(lhyGCdl|?iM#zinicwO?SC4)*b?+q^= zO^~PC`nHi?8_0E~Lg+?SK!Ar>2*UkK+8e4?i1zLDh|`;Kf27kaAA?s@FAX2dJ}ff`&M z@~FOBH-2-eCocVe%S5hf)eAQ4J1xcyKXe$UuZl~@JW7u`YU7`5XZSS?1lixWKC$-Y z%(UZ_;AelQ{4vG8$xZi^t>cLWN*Bo;)qRoeszZ09E7?~76){}@@$~r@cbb61L8L4A zoe|9iLA+@PX7(|%0d;iT(htq2w({W`(`bG6A(M+Y*H9J15`8};YPLM1Yt99>p8DSK z04d$gAun&xBlO|WN|W})6=Q<9i3*D3G`=kVQHff;Hx1PY`Cc7do0&p}`%ck4rO`V8 z+xk9QSuN`J5?_PECb2F&7NgRAuqafVp_*b;!&fPdm~o>g9f7`~J2gcb$RlJ@ID_)8 z)^}4Pvu!D2`9GPUfPcvyhCg0-cO6KD@~yvfxF+@;Ke}x9Yo!r#HfZF}Xxex}v!Tze zmf{Qs>93R)9e#NxH3gN|1`4N?7e&UN2`$N;J3cL-d4`f8>L8oEhIg+&y#QHN_l=Yd zA@>%S1#?+keIN(ss9-|bBP$C(Fa*!W^gQ8A8lr$@Aza&T8uT5I;+t4|m)-J3o`PX) zQZF&B$f)*4Tp?plk;?TCVa=vf-i+z{rG2%xV2aT|1-kj6u0oSrfNFGtu81U}eRWh- zWz?PH#dpr*4LIh#OIx-EPk{9q*NwQ$$Z(Z6X6>T2@CYtj;Yf z_L52l;cr^~Uyg4=d3O9Ag*zUWZ0k*Jr7}N@;t{x>+Tbn-IfZ_H(D371r6>_KJ}gsY zRA$q8_r@X6?ZaGpXz+>UeN=<%m@u_thx*H?Qh?0Xb0+>4mG+MhV$5C(1!^B%b2PQD zq>*bIj#AxRCHS_;&9Of`Htw#p{&oupUk~?92!MDI%~=m7Wpb<7n1DK_=)mF!4uGdg|(8!yK4%HgY^LgGpw ztg-vKHb_%;g|ua}rNOH4iXmr2d1}eKTHd%dKJv1cOH0w{t`u3zMQ@5T1KV{SalZ6n zE*^eyXV|K735T%QLs1&63y5fUzX&)eE8=M(ovf<8iCpulqB~NG`2urv;7ndS%_Grd z`@A7dm2^jWbJ)*0cIdVvXbC~6S$2;_ILdL3+XWtatyq+F2FL7*Y8)g3kB&l< zUgS7&U2Dj#mw?((9?SWYT4vHZgeBHO?& zb*SIAsgNMzr>F;7VbVT>zcVjeIT(|{TpEL)5|`wb6zB`iu^6xlva4mO^tlE2bqD^% zEd$OQJ6(DkDAMYG*PW;#GC^nwB%F<9V}5Y;3Sbf#k#w;3QN|$j3$88@ER6aYgo6ri0U7L zU67E}v^wmbj-zhf?uh*h2&>2QonLrQi>;n79u5f}bHb+i12Q@gvrRE}Rw313lZNHW zvJ!RCxwv62>t;#QykTa#Ya?p1E!Ayq<%pDoc=L{h5WJE4$WJ*HGoA{exB`TQda1Ec zhiit1QE4*+xh#`Njz<}Sbj1ZI*AI}aOc)od#SwCP_T(Me_6<|Key2Rhn-^5KY;4qD zn!F!W$EC@9k!eU{!8N!*Z(2Qk8dfSvtE>$P49=X*7)|J z4j69xCWf_Kd!38ExZzY-E>m4sw&|CGyHA!9;d1Symc9ucjpW zT1m>(0-BN{NH_#6NoyK9Iu8Ek?=J`I#H*_7RomP(Il8iDfx%W=dtti;e(kZ%NoySm z$;l76FdAZ>pu``AXx~K-kl2C4N^*rVAa3fW)>49++)E?uvE- zr*S7quiNdytTUkgvsD*^XHah;;W9pcE-Dp#&O(lf-XuC3+nUHEC8l$44rbVoZ@J-Q zJw4~q6*J2=)02CUDqn|e?k{;&!WJyyAPE5Jt`^2>_@qzZqI|=D*klNoT4i;hj!l#+ zGcLJ*u4W>aV>OIY*-Q+7@|Ywx?N2&IT1-vVQ*#?gBya3J2ad&!6Zea%rJQ;Zv^Dt{ zRGmFMtx{k4eplnJOoT|#09|V8c0}Ha7yj0oFA$&n9dnJf$#&omi3Q=Uq4d_hk=~Y) zguh2ta*Oj8pXL%PkXr7dc`YDP_Jm8J!M)ik?eZysxS0{v*cs0ZqDCSG`z>To*8D#8 zBuDDTs|*i5gy4#ihnvO;J6~d}#`30n$|OARqc5|ijspSYAzN8W){Rk`HgI?+V^V8d zx`Cn9q&$XIWX6zEwXar=(i)jQ9Az3`c~L!<198+tYBYLA8s(Ecq(R8>52kTpnW1_J zg8Z>d>cO;>q2bwAVnV2BH%--@9DJ@&_WT)wWCc8UUFTQyKlfYOM+#kkvh-o)<;i{9 zVyGSi3UbJ|pdR<0SUibSc=%CgPEe9IqX*8-P!R}Wszui>%P#V)E98 zqT+EM%)wC8;oIYA_ii(itG4=xv5ZRY&lHHX?B(5>l6@#NFK2C?&Ek7_xvb&C7)GWy zwOrxjl^=7ZEZjldPH5vf9a*1USC6)Iklu#O;(h^S_PGqp2U@#cO;))Hr*(#PGH{e{ zLgEOi_}1_55kl>z*SXBQJx+bDTCkpTLr=4Y_(a+~YmAFm>he=Pn}52AV)y#2!E2m# z?9Y`YxPpy?WveT10R#TY`Sxsoiu;pqUUU5tw{evGn>6*!4t-OVXMx5?%H_fJ&uuD}}jLsp3reX-oWQy7Ql>lIBZ)Ob~z1AZjjd8U5g*N_2vAV45Ik z9wwM!Vmx_p&o~8_I+Y)SCQ=&#zDVMmVDeJN5j)yXe4h|W#?T4vlY2X#J^pYKFM51| z72OE0PnlhXlb4njEzjd-DKT0ISQErWj8lk^u&%R_Z9x&3SPLka8I|K}d37ONuyC3m zh47cS@^;dMwVMg6zoQQu(jtx961=4?AYd34vb$1r<^}U*A{i*W zSrTMatnRLJF7wE1EA@R*x=8$9HeYARi>5)PqIvdZMt$egmaU2B+xOE+Es2#W@vGwP z@+&@Hhv`2WrbxoB{rbdz>Nqri9i{%1#kjO2J8F3vy5ue!itO=2=$o=||al^35jiaYAkM$scEo;7IAh z$R=pK+~{yAW-=5WeG5R$CrFjH)RgngFy#v)k6IB$byNJ;%-qLs^AFE4+W41o()Afu zR#5oJVUgdFR5Ae`p)8EhZu6h4mPdcCOq1J#M-hZ5Zx`opv5M;Z*cOyEZSlnHJbJzP z5x)1%SELcD)t7TBbW4t}$E*TU`|e~uc4-I%iHRfw4U+}V8m3vVtZc*Oe587W3;UVZ zukntklb;(xu>QdZD&X2}nM}uO&+M|zCXa+XkCdZ~)lX5ae^JG#YNVxi76kH;>^=4( z;3ch@--<$wVAvHpq`(_=-B|U7kqGlm@U`L_Y~e|PuCCa}EBMEsl)tB1Y%1xnQn!F% zou4tq(B=qp{Tf$$xFu~z*a~vxJi@3WBP3|B2uF<;-CdK)TCaF-JM?-{_;ptDIkD={ z)W$6!XXF-;8uP`QElOw>pEd7S*k)y6AC`&A5AGf27*-iBnd<@^s?o zj|ptC!clAVYfgdL=C2;Au(R-Xxh3_sA+t-AVQJZn!i_^&Ee4XyUh)6HL}Pq*2Pk-c zs^W;}H~iYWgt~SqWNRud(cT&flSUlW0t|nUX8NlWRT=vE?C)jHO{6QDhU&TEKD;L(Ry3q+-eIkkAlunumHzED z))VzAQ+^I9)TwbGMM#gD3V`uoS)nul8IP5O3onXgh@?>E03DZaM9z41zjZb4ahf^# zk?OP?zu)sC2Y>$&u-la3EL>q$U9>8(C!m0=VS+O~o+G2#Phb9bH@6^`R%G@J+WEC< zu5#my-lgNwU4b={xkd~K+}m)T4|r7lfX&=)+}G>=jPD|FAd^g;D^vH8nN|;_@DM|l zu_xM>99&hsyJFS-DsN6ehG_KV(l#Sp!Npwm?~6mn+|5&L(mKc7xgg8*cGU`hnUqQS z%(j$rnR?Nbng}#K@bn-J^--QJ%`xB6wX7FxAEt z*rGWXti_6@sI_93H>9|@FN!XsnAE#y(dJV%>uZjMSe$l6p|>q?=bcvLu0PY|>Ls!>hx+DGBl>wlc$GijZ%e6~9y5E_ME z%(Z`^nfi;Oig~2v8Shk#A;m@_s@aDwrIGP$hmpMhF}h%#^WLK68U_@>r>;&hhLKx# z)#HG>ac9hIb)XP-ZZVAXZc!wa#SeTVC_xC+QV7zzYDTcxk}$wTzh2Q1T*}c@D{7mo zaLoj04nl{YH%gG?bthPLw!t4(oO@D!IV?75gK8ptu{HzyCTf{JwCK=~520VBym9+XZ60}SByl1} zQ#&Da*S(>A-$Z8?GB9aN+#Mck%zFKhwm9Inf=ge8&w<8Gv8T@W zU|9c>ERu`17jDX>sXcGppX|JtB$M?78UPmC+#cZkv3=EH+CSN3DYcerpn6{Vs|2p! zg?@e+ZG+v(@lvq{mZ&UiKB+S>P(Dd;aU6@Eb5>+y+k37GzQijyZ>qd(br#6?0MS1~ z;7hT-p@LRvYBL3Vk$(>0)^TL_S%Ws)qJ!Mi6_LH1?FY_U(~0u$%v(&u{gzVgR!nQ& z`;1rXgVHNO-gHOxkm!y2tn3wL!_x1{UrcJY7h!yt!N1@2_3dt<57Yk+t{!vj>@Use z`{h|k`LU=rKbl^k&`1YY&OC&#=?x=hN($)aMRQC+F1u$`WtGg@M@1gXcv`38l@}p& z-TMnkbaY2t^e!tS>&2#RV_no+#n8RMi|lST1bE1@IVuq^ei3Oa_QUBM%D;C|WwDIZB|8=!xHCn85A3|DZM|7T8{nz|XI{92xD}CZ?Rmq+gLSqKi z*$gh=ltiYn;GpS&CWA{>RmlYw=$S<**DNJfvBel-G?e$MbZu)q2Zwao8mO4lMd@LK zhAY*PC<^WdVV z=e`c~8}MC{^{wG5bzl1h&UJ-Wt=+lOtAxuYKg8=X#Fcd10Y9+__?O@c@zJjz`goPs+ESd23SVEr zet3JAU0X=8s|TI4{j=8FlWwV{kI}aDo~k_OkwvY1F)aeM)A;OSzI-uGM7@0*sXnOK zZu`W|D+s0i$^890y1?pMBabbe{{|Pu+iPym+cq1rVDC4ex_xMCJE~QIUIBK%yp)f*HK~VS3j)& z;XM#AwzUP*p;e6LKo`A^Gm*U~Qjk-I_8yV9_{d@KM1sb&L7SJEG#jUry)CvaX4X|; zCVv5=aoJ=dRy|Xb?`)qC%dOeoWc|CpuC2c;y=-m3P83hT&xITkLwUDfu{N|OaoKNwP#>Qw{0SFMqtqlg5 zE}>8yT9#Ut40x$3fK|{OLjg|?Rcg*#GDHnFrAk=IwmH^}q9po9GnuiPd~Vg#H##+v z$>$_Y*?6W*3;8{2b#kWOerB9ef3m~yauL_Xrk7Zum4Jln-I=rZ<<$Ydi)mc1oT9h5 zfkr#cb^f*?ZE z9)Qf157SlL+AbOsepY_^5$myA9Ksh{V=>V$Q?zhQl?Nk8rC#LO^(~+(YVs3YPjl!e z!Z^gH+Y%^tk$u^Q4#L!et@K~9cYk+$QR|U?u@%SSo1w%Eoi-S34Eu@wcv-Nv<)XA| zLs4&a3z%{(obXe^J!oD0j+#{5KHy}YkGXkKUm@cqGmS_-_F%?b}a| z;`^K(j(T~^dS!mB@s9?=k9Kerqtp8eJFmWaG3;hG(jdT<9=1)I8`FY5ixBBEM-hW| zHb*0*(K2ir(I2^}qoWUxp}GZ7{no{{#|!;J^Eoi#q+y>ryg5oA;+a!AV_!;W%Fc8P z1s$%ZX14B{b2K(PM{&IGk3Pm3922<#X*4_dtkxFd6 z16e+V7T1Xizb4Kmb~z9DgKq)42jBJu%#QCf2M4kn9Y2I$7j6}Pg+BbO8qIn4DMQLx zjlu5u^X5i^!?Mf?HJ-&gBE3W~IMXvHG!5ONY#B_+oGyJ(e*ZxY>{4h~Z{EXFV7#y( zX48B|BbP@SVC6@aX2G0jnQx5fEU>9c2%2H<%H9q%M(5I-1(~#KRo~3_C=jrv3o&@* zP8BaQwOAQlh4QD~RBcbh>$+w2P|%^yE-1yYpyT1)bo7T7Cp;0=cFN3>ZaT8KHJf`5F~Vk`-kzX zg`gFn#DND;g&`C`pdc6p2|B=E00?oS!kFJBCN7E;0SH(^5)z&e^t~^fJ3}hPB4!Msg zY!SW=L_`o`NQv)g2xWkPRpai9$QjOCQl8O7or&pcxU)t@Z9W5=TubD|1Z*G;3*(?* z6fg&TM*&dle?6%t05VN+$;SGZ*s4A~UEPu&T>c2cXx@r9u`IWzDIPW_gbdsFO!z%z z29)*MT0^>=UY*X(>1R02AjWpa@Bzj2zR6`J5Y_;u=T<2nwJ+0N+lx^CMzDBA! zjzmlMaST3o;(R%KE@l;K?Cf$Io zsEJP0s(Rl0wA+R?!;G<}5)(EIld=cWOu;R#RD;KtaO99^I?LK!Am&KX@@PvlA#>&E&8e_DD{*IO1M2Xhy5!Xgr-`7hUJIosaGGo- z_tCX!3eQPj^0$_){N3Bwim8z`@{eD}3JvzC8`M4uSo`Bx+!eAh#l#YX7w-|y); zJj$su(rRrc>0zS?=_^Nfw{cQmE0#popz{m5LK`2STbM6mzAX%;tQD2>^9>wBwa2+; zwHwYzXne{qPct79Q*s$I|6vfKD-AD~y zRPjbW5KZn$BM&aD^W=Z8$gGSm&>4HZYI1S#9>Y7zMn12;)?v_&^-@~}&06Bx^EkZ2 zOMYjl>ro7=Z2oj5qy4f|QVgqmIjKY#T$Nc7k-N~puUyCT(!_dBmCZpc5vz=pFnYCo zMZaolYGI_V(`Nq=c_yb(h}1ofZm!Rmjd6XrHQ!yPdmpFRkiSBn5+YrHB0WPf-~LfS zKZ#~ypBnu4jMFlFEQHoOHgXg5&o+vxfivYf=95{SH?jQec(`v+LMcQgVeBUKL{id6 z&x}5I8P@%>)br|vcg5Z?jdiUje5v}xEcJP2&JBARJhh}T;GobH5<626@Tuuq? z-(!ZFAy4f#Xq+q#;F!4~+)kUyp(C$WBhR$*5dL@N?0i2|mHEaGZL#t&_G@Bwx>58@ zDJ$nuIDC85M1lSFIVZIxx?7tiuDv{3I#3X}WqWkbF>Un&P~Cpt-`9 KQkh^bc<~>7cgXYr literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/serviceTemplate/center.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/serviceTemplate/center.jpg new file mode 100644 index 0000000000000000000000000000000000000000..385327ad767fb01dd7953623feb23df3d5e7d1cb GIT binary patch literal 601 zcmex=C5UDGKfoZ!!4Ss4$IK|mz$D1XEXer(2tzx> zVL)fX0V_KP7b7DBGY}&IMkY2EW&xmYSa|qRgoW7x6Bh<;VxG(*!g^KW!$qM9DJEY_5Upf9%e?MtC$5D>>0j$ zz7iFm=9}{9$X181T-~SDHWemZWy>$oXDD&G7W2pHY{%!7C-hn$@O8{OJ-vvalas#WLG;4<)fL zU0K<1FE#7uq=R=#bC;Of)>_^@9WU82{pxMW2_L)9tc^E{uz&z;g?{Z$ tHj*=TJiYR3YI2T!q2&I#`*I@RUS^yg{OZ)P8+DK5t!s>LFJu3I69Ab4oizXe literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/serviceTemplate/left.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/serviceTemplate/left.jpg new file mode 100644 index 0000000000000000000000000000000000000000..eda0c8b558b7c9bc38fa800b8f591741af717233 GIT binary patch literal 7774 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Ⓢ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 NJG%c@3FFh!e*wH5rkMZ$ literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/entityBox/serviceTemplate/right.jpg b/org.eclipse.winery.repository/src/main/webapp/images/entityBox/serviceTemplate/right.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8d4cd7e3da0375e704aef0236ef6efefa225a576 GIT binary patch literal 1838 zcma)&cU03?7>4gJiz%2eL{QnQRA{I{Mga#qf`mNW z5M1!QFcOLWrwGB|2!KSRgp@H2*y9AL^RWiP0V?-ha7z?gu4T6V*_?h=i=ZFNf0uEU z9o#2}7QlleP{Ig=(5HSu95@1-@-tHTcmU@9*GmLS_EQ!8Beb*8seQ|;D5w4yI!8vG zKLW(zf>3BU8kmC(+g;kPtsIpd?^vu3TjuS$jmJ~jp?B{3IU|tmXbK_%)r@IIN`8Uz z=Q#b4R}nP(+$*fy=SvLFr>u)`b+sX0(Tgf-aUSM0;*x)0MEa(U7rC#M?nN_c&V2K| zKJM88&m}H?S>r{Bk9%L%Y~O1Gswc%T`Iz@Pp)k}{3-LX7)@uq^Ry_FN^P^LsjOM-DstfJUSrJYVTMu+ zL@+!-WFm=)$v3L({#3^Zs}et?mLL407AB_9Fq>bL7M+EiRaNtM2MmE2gfhkh{Q^agG^R!PDl<$**d?(~zRQCI8&+An}+%pa+5xSX_CZGqh~MSR0dET%|>l^Emm&~uWXreJINk9R_kfm zrZ0I4qE-pD+Y*c8`ztddWk_`w$&(^YC*=)(;;9rj>n{Z}AI+F)JaOXuRWS!6`IY)* zn$mRc4Cu#QZ`JFlmaQ_-uH^FW_nKFADKhK&PO}e%9Hh&nc1)k}*`)8z zYT%iJCRscir!CXr%QDq!(LLib>=_5{t;C$%BppA98Q($_d>8d#++==IEL0C$8ZbYl z-TfJa&PNcM!Jj~!$yJ&%N-XL87+F=0oHw+Pz*PQiE70g2?q{V7!6ilQx+e|e=0-CK z+xNC%v%J45GwP&&iEND@eI~o$5tv^;_l>2|R`3KnKC&yp{#%CTs{Ig>ruR~>^6p`(J^l*#Ka`JBI98zrB5G23U zt?5huN-%w&b)MXt=pI(PbIE5a4j-v_>F>a{3G*Vpx_;~ehcUUWp`_QSV(AA^za(WF z^PG0&gzA$-En2QTmr7po^FC}%7N;Jd;DeO4EJEWm9E(?uv6j-pIh|4GtB=VoTCoPr ze1FL3ovH82N>7fxo)m?b%zIDsj0>DsLoqsAP6t(ri%HeFYhTkttJpk^Fw5N-Tf2QL zWw(2Rq!fPyzU=GZC>C8nXb_s3igGY3*fbdD?aviJy0%MXf`^Rg7xrN*sp(CNFb zJyvPlSp7XNCX#B%*5+kapQ?HQq}i`hF!HZb^Qwn{*-WeAs=yZaw~z@ zh>VEElXQ49cEB>FPi-t9;gs<&6(tVQ98W1N8|pXd??U#uB~R6JPsoedp>_?EQ{L5* zZr7EVUmiJSt64Gddv}bw9j2fZ0>;ViEhTNad|6vtL<(A$*nkVtO*I@wRy7qp-4IZVU;oA^$xy90jqH7${ z5Qf&Zdaj|}F5EL#tIHxjD#DlhQ!#9C!>3wPl*!w$Rmr|dz1MEtgk5&c9}bx4Iq#>S S6rk{oc~?8E)}2b_5C08Qyam(% literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/favicon.ico b/org.eclipse.winery.repository/src/main/webapp/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..823222e7a66c48e86a226b87143a2115edccfc49 GIT binary patch literal 1150 zcmZvcOKePG7=}-2Y>+evqG%~vWx>jAfejMGy>V|+M78dXdnB$Qgb*Txun`fJT8PBb zMrco`opz?3wtCTa+7cSmR7!)qp6{F^>B2vG&z$*Zp7(pd|3CjYP7<$_6o+fNlb`H3 zqaDY|LQFB^&-3PukwYEFG;k>XAXRO*iq(9zOHCK0#`DsLv*?u6a6+m(f)1ktQmn8` zwY!T|lb329>U@%|PtUv6eoy*%O=`IWe*yLkY{1tag)M^JkM>A4JEUlCw<0;&sw*h* z*iSE|_Pcmo4Lr`lpGGHPkD)_ouc!?RAK4~VuPae#PC}8jQvANu^+IaHqZN-PGW50J z$-I{zJ{IsbdGMQ!?^S5FR5p{(%ka2^$1^`i8}~N)ng{TO)Za<{?NZf7v_=ZelFH%B z(tMBBn|PE+-(w!`U0QG8agh22^bQ}{O6~Phcm@0nWc(D#9nbt?spFB)etRqZN=Q8+ z_#nUWQFyBzCUYp8`p7&&S@@(%Uy7wa{rEiQ{*~`#`x@KluYF_-by&0TQrJv1Ef874 zbEV%s(r4KA+ju<0>!*|`hiCt4ZSOYG!zzBegqp@rMUxRdbi&xEnn$hW?B{jZ3Os(W zm&b$tZSDB3auE!fJy{0s`#Yqs?4z53(x^kmI2mkweNBdZ=GeRNN~vODz*>EBG~`OX zrSxXL__-6L(otk)trN`Kp4b{hd3J35Dvi%fc)3G(ST7;#V^UC`4DUzaf$Df>ny*Op z^bn;^^=hl%tMci^{`%4Tzjd_iW$A&&Nbiz;&wBR1@v{F6S9yF1^)sp8E!Xl|&*p>N ziST0)`QHyi=0Qd~4|blabGpf&?VUk4BNg_k+(~h-XP4UUI9PI*rI3F(8X~l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|80+w{G(j&jGsVin+1c5}%-qS)$=KP@(AChw*vQht)WY1&)XmVs z#Kj1v*Cju>G&eP`1g19yq1PFwUQklVEdbi=l3J8mmYU*Ll%J~r_OewbZns$CG!Lpb z1-Dxqaq86vIz}H9u}BdO69T3l5EGtkfgE_kPt60S_99@ies{+CJ_7^eaZeY=kcwMt zrucd@1&XviUp=W&hC_Vigxz9qe=+JQiRZ>#-OmxVbJNmo0?O0%xE7^$7hDVzS=7nq zBvt-aWrpIMi;ByGX0JatRXb+C`iBGE*Nwm1%=tcVr*ri@cU^6Xtj>)g66P@%1db+s zWSF+QYf((v=9^+`Y}d3l_I1DM*_La4%-~FX zOD#3=6_)Nj)~$1T^@J$qollO4A6gI{9eUN=bCTSutFMe5M0p+_TYIkc<*t8mtFJEc zTKXwVqK$2(et`HF?-Em4wsukSTsY4VW0ic bdL|wQU%!)=<|i%z6_yO1u6{1-oD!M<;V$ow literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/forward_enabled.png b/org.eclipse.winery.repository/src/main/webapp/images/forward_enabled.png new file mode 100644 index 0000000000000000000000000000000000000000..a4e6b5384b8454ee7f44a8f7c75b0321b7eeb9b1 GIT binary patch literal 1380 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S1|*9D%+3HQ$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%u1Od5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|80+w{G(j&jGsVip+||I$+{MJu$=KP@(AChw*vQht)WY1&)XmVs z#Kj1v*Cju>G&eP`1g19yq1P0rUQklVEdbi=l3J8mmYU*Ll%J~r_OewbZnqfWG!Lpb z1-Dy_aq86vIz}H9u}BdO69T3l5EGtkfgE_kPt60S_99@iW_)h2mVtrshNp{TNX4zB zKmY&RGjC-OW)@`(g)dh`10)R-NpU#bM1=1eo8Z2AYd)<-?^`_sqOFY@6XS7KM&8JXTA5$g^A9S z{TX;`xlCJF@2;-kt^WS)-(qj^YjbRh3Qo21zn9<7##PJs=)J=q?vtT6c$tqWSn$;S z{q^hJt*2*?^Szy4@bTi|;PVYm@{K=qh5oS|v0uoRWd7#=|NZ;-*VL7!+I+Ui=RzOdW2D@cF)|8@0kar@euUy>OYxL3%Wh|X{LVLRn7b4UH-Q)xXL zlsIOXI?k$WjNtJ4&-&^N(`qv`*KNBfVYRHPjKr+8GT t=fC*;><^O18kWptJjt-AJE?(znPJ1m)BPofdH;jTJx^CZmvv4FO#l_Q2A%)_ literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/forward_enabled_hover.png b/org.eclipse.winery.repository/src/main/webapp/images/forward_enabled_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..fc46c5ebf0524b72a509fe2d7c1bc74995cb8a9d GIT binary patch literal 1379 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S1|*9D%+3HQ$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%u1Od5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|80+w{G(j&jGsVi#&A{2f&C=1($=KD<(AChw*vQht)WY1&)XmVs z#Kj1v*Cju>G&eP`1g19yq1OqgUQklVEdbi=l3J8mmYU*Ll%J~r_OewbZns$AG!Lpb z1-Dx)aq86vIz}H9u}BdO69T3l5EGtkfgE_kPt60S_99@imN7BvVqjpr?&;zfQgJKk z&;S4S%v%{AKQQkRwI?VL9s)YsRaG&b6_ zgRo<91_J$Y%O?`e|&#$ZtS+eXp_f= zjUUrLb7!pi%4at>{rxttxB!poqO-MU1}Hz4_scgh+`O`|pzGU*Ppd<;SGk>1td!-8 z=;-~nzrMci*RP)sFMiM0pIiAYgm$R?>m2vx|wYgZ#kAH7}W-quPuJDiV$o>g2t#=I)c$y9~%y7A9 zTfgc1jk&Lj_4ZX)f0PV(p)9c9_0ar=AL>^e-n9Mw|Nr~<^YZ!qF*`48{dsWi)b|VZ zD%w*xPFz?Y(EM+~bAgn@|LT8!dGP4_dwn}*-YUka%$2Ws1@^aZs%Q9^A9It(GQY{> zGt)+aDgU^S%wM?fC!gsP`E`4^jM#4)q-B&8J6^t!zrwrDf%l)k#^S|Oq%QdIe*R^@ tLh*lxrsW37V+~Wv{w==9!pqEIz%cpgo%)U5J^Y|z&(qb2Z8_q literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/header_background.png b/org.eclipse.winery.repository/src/main/webapp/images/header_background.png new file mode 100644 index 0000000000000000000000000000000000000000..0a797ac880bcf61b182f75cfb1a86f683ece2d04 GIT binary patch literal 36799 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 literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/jquery-fileupload/loading.gif b/org.eclipse.winery.repository/src/main/webapp/images/jquery-fileupload/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..90f28cbdbb390b095e0d619cbe8d91208798e58f GIT binary patch literal 3897 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 D^>?LD literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/jquery-fileupload/progressbar.gif b/org.eclipse.winery.repository/src/main/webapp/images/jquery-fileupload/progressbar.gif new file mode 100644 index 0000000000000000000000000000000000000000..fbcce6bc9abfcc7893e65ef20b3e77ee16ec37b1 GIT binary patch literal 3323 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 literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/overviewShadowMiddle.jpg b/org.eclipse.winery.repository/src/main/webapp/images/overviewShadowMiddle.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ab770b2dc92f4263cca1039dfe440bf8b31c96d5 GIT binary patch literal 345 zcmex=C5UDGKfoZ!!NA0z%*-grz$D1XEXer(2ty15 z0~0gQkw}1*or8;!5lH~d6ae~wjU8E((Xf!oh}pQYY13g=Hg-V_9sh4J@Gvt1tzs5r muxGe(ex|qMCglRAH(!32Y|3r4__*ys(aRRL1q}87Zvp^LKP{#J literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/overviewShadowTop.jpg b/org.eclipse.winery.repository/src/main/webapp/images/overviewShadowTop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9b6afec3a999525df3124b06b646684a20616f38 GIT binary patch literal 1306 zcmex=C5UDGKfoZ!!N|*?%*-grz$D1XEXer(2ty?U z1JEpx;Xs!{00%2O3mYdh6C)RrAXH8O=y4_%ZZNm%*ArjJ2~4hteohZ^+%76T8^2%u&`2788of0oR>kz%&sn}dP? zhhass;OrDx52FbjEKD5lI4@>%9^-ISY5>YP6+Q25n`5B7n~8G^6C*=&0vyskppE@OrEXTd43=_@@G+$(B zaEy$-IdQt)jGskGi-Wl39J{S^8NhA`DbGqYdV0Bq??tm9&r#N;hj!__$-KzatO?ZP z6`MIRWsijQ3y~*Bn(jR~6Jhj*mu-sV3Kk|Vv6pANRo&U%6m}(*F4+0AvRk5Va)P58 z(B-k~TJD|<>ES&-Io*l-__W=HQxETPIwB18AnUB>K0P}_9*HC$pR`2$zE;7F)MWpk z9O^*NbL~Anqh4lKp-DMM`K88|r+hsdyQHmFI&K1bNM!azBb~_}%hN7c8z?0GH12<# zYp-E{?m=@lFbvegrBYH)N-}e9=gpAx^C*{o*&5+_Ng$7zVMRpqSB6HN9h=QnE*0>d z(%8yue!?f>@HDHf3U_BD9sA|lVK;$8@OP_`(G!kK4wu}lCYYGlygO~#HsQXA^ppL{ zS&rWt96Ikv&Yq-sa06>RheGDMmu%6R{~6+6KWaKO_3id;mw*A=$oBHjiA}yrbLZV) z<3vVs-L_SP_;my`1SJhJ^SP@@f0NfP{>(#yEEBZS2>E?%&})< z+=5b296Yc0j~DY?);q0drpATF?Ys5tdncYy$TCsbvZG$bxL2V<;X6=~zTdMv4~yCz z;a#RjnJdfuUr!HC413?j9p3isw{#NE6ehmhFHetu{P1Ig+=~i@{C7Khc9#5EB%0GA zcAuj@KH>TUV3an`inT0z&cpaKI@Kz`qCE8Wq{q!^QjAxCk$e92xv0zeT|7sa_)<$A zUQC(TpSp2f3!mvV!)d2lr$jV8da$SYg0ADN2FEjUvv(OixpG4O85a|~(X08_wRi8% zs8HBxA(h(ix2f5Zp?P|&X`#`R+F4sg_)0H-@>;p;Ld>82x0zo^DL!g)WN4l?*R=3Y zjEUXkdrs_5FLvon;!Bo#yk^0!o%Iv<_2vSTzvHQYv*wVQ<5_iK020tdY>1+WWf}mw7D6~BAokAo+o^5`nnD?xr_>r7PCtC*HsiI%>$~Kx%$k`k5GMnab^o=M pWfdd4hE;l#`@(H3d}q&pds;jH=Yl_bzyQSZ`6hF|bXD^ClJjCHuJH7UKCD48bPgg&ebxsLQ0AZF{ A;{X5v literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/DiamondTarget.png b/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/DiamondTarget.png new file mode 100644 index 0000000000000000000000000000000000000000..18b50ba4bec9b994bdeedcb8f87e693cd2e2029c GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucL8%hgh?3y^w370~qEv=}#LT=BJwMkFg)(D3 zQ$0figD*u3fvRdfT^vI!{EzlKay1z6uslB79QSw5_k9QRzpB;-`8Y9~=4mQDI&i`4 zt=^O$s`Eu;9_hR*lM>)I`)H)BwAp>nOqYlNuSVUB3}b#bZ(+Jt-DOiIrSc`nmtXObwc97j{V#-{9QD?YQH^hdjWI^gQu&X J%Q~loCIDVFS@Hk? literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/PlainArrowSource.png b/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/PlainArrowSource.png new file mode 100644 index 0000000000000000000000000000000000000000..8fd1883d733c13ed52f0e1851ddbaf2a644f9143 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9F5M?jcysy3fAP;i^4 zi(^Q|oU@Y*xmpYaTqpbXJz(AAv`XecG{;WIcM0h;m6mVV;yKkXXRD9+2Zn82hYZTP z1IvzPeV=ap-|+LpU>6ntFI7+eS#DUj`uo23zf-!z&wjpR;u|?Fa+;vit6g?^KWEQb zcGB|tw%qHbr#IDDc?%l0ESMs7T##WMpXO2lrOM3PX7Bf2vpQew^^((K@01jVhD3=~ ztAv~i&b@D3oYZse)*_7_!{e5F*RnAf9Gi6Ee&ghS8@#ROt=(#+Ripk8=mQ2%S3j3^ HP6m@#9+rcG8B7H8&Ietvp-`u~lL zCAiqcsfuEGgMFxhuOxIrB$W!XxkdnzGjl`X8(onlgj2Rc^^>h7cDsXMu+vJ7RRAd4VLUnQydol zFZ+JK{5XF*BSY-Px0k-WZxCoI)_Y#_;Go}S6I0)20U@U~ucLOFCahI$$$32`$n-4nJ@ErkR#;MwT(m=tL zo-U3d6?5K(7;+sk;3@w7e|qbgmlrghx#k+Bc;~!kI~?e9duzdU9;HdWENsE3 z3-U5_6D(Ysd)rIXFXXDk<4rniO@-5yHifc%_-nC8$lp6$?OYebmwT=)Gppab^=Diz tUc~!<%lw)7YeKHR_!76y{KxYq`+KXsUb^Ho#seMA;OXk;vd$@?2>=e>UmO4c literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/dottedLine.png b/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/dottedLine.png new file mode 100644 index 0000000000000000000000000000000000000000..aaa49a7ae040efe5bc90deaa2d9c9b4902ed9759 GIT binary patch literal 414 zcmV;P0b%}$P)$R%-00009a7bBm000ie z000ie0hKEb8vpBF>Su~|$elS#q<&SWxKY!=hX3{Fr) zK}F6ml^uhda$|TLI~gaZhuh>{dpzt9;jv%%)=&H8lv3I!mj8&F!5RFQ`)W3uLI?nW zQffY*>$*M~jY_4`a5$_~D*b-HR;zWp-A1F)Zns;l*6(&YoqE0A>-DPD>R>P^m&=A> z6pO{lWKt*;R;$(X`Lu2OdcAs{hcTv3jv6ON;opR0>iv?qBywKqxr@!{9T*k6mw@CIDBb{NGe~(6Hj4~G z27^ot1}Rw>ERw;h6w~wE;oR<@bKKKCb?biS@26j%r{@A8e0he~r`CTY002DCYnlc^ z==*+ERgZ*y-xWm}#}UVIP1CxrBT4ex0)Al}N1o@CB$?+~5QHd-;2obrmSr5r4a1P< zIm@zr-`}qxgqQ2Hx~}UuP8f!1no5#H(=>{rr_t}ix~`UG9mk=ns%_iTG#Q40Vc3cB zaSH%Y6a~XDaU7Rr$+Bz^1OR{^8?J2Irt7*a%hNQOrYVZzvMeVJH`H~FAP7MaZQB9> jD2lpm_&xvfmmc#5R*CM8(24QO00000NkvXXu0mjf-)W76 literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/doubleArrowTarget.png b/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/doubleArrowTarget.png new file mode 100644 index 0000000000000000000000000000000000000000..d9b6bd66847b1729bdd261f2d89d552cc1eff3ce GIT binary patch literal 343 zcmV-d0jU0oP)82 zzRjHHIS2xVVSL}Oswz!W$8lJeeRSWhe;`ScqNsh}34)+$8e@E(=S_ykN_n0G0KzbA z+g6rk*L9a=xzB(Q(skW1jK1$}+g20>Lil6ovMdEbD9aK;$Z=d0Mf<*A=`RC9Xxlc7 p@ia~2INqWkSGtD&)u;c^@D7X?BGU8f;r{>t002ovPDHLkV1fx4k(B@d literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/noneSource.png b/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/noneSource.png new file mode 100644 index 0000000000000000000000000000000000000000..2ef91c2f400a471dee9983b033aba75c6b9bbbfb GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9F5M?jcysy3fAP|)7f z#WAE}PV%4s|LvJI8#-04HU~3v&-wc2=Vw*#X#&?i%Cmj?^vR?6QaiuAM{$s|Gcz|g kx7<>J0~SKcecz-Q-1Q_QpH@Df2{ekq)78&qol`;+00vkpqyPW_ literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/noneTarget.png b/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/noneTarget.png new file mode 100644 index 0000000000000000000000000000000000000000..0505eb12da748f2327f16b87cff861f34f7423f7 GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9F5M?jcysy3fAP|(HG z#WAE}PV%4s|LvJI8#-04Du*&JUb99=&$6!W-`(Bi-X0zT*%I8`r+TyaKeg>My;OXk;vd$@?2>>hvF1P>y literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/plainLine.png b/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/plainLine.png new file mode 100644 index 0000000000000000000000000000000000000000..b4c4c6b1eec5f7bd3abc9ad7d3ecd03a079961f9 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^8bB<-!2~24nJ@ErkR#;MwT(m+95 zPZ!6KiaE)D{{Oc>?7*;$abxL~q$;Lq@9*#D?>O4y=jX?qWO#bAxFVdQ&MBb@0Dt-{uK)l5 literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/simpleArrowSource.png b/org.eclipse.winery.repository/src/main/webapp/images/relationshiptype/simpleArrowSource.png new file mode 100644 index 0000000000000000000000000000000000000000..c8a03239f4553923e75071a752ceb245ed39985b GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9F5M?jcysy3fAP;j@W zi(^Q|oTHNr`I-%QT)l$}+t)~11RV3>;G4i*z#Vqv&>Urhl;;eRg6tXn9nP$s|_tlzDL)kS`ua~ZSJuP+Ty4Qd8QzOON6qC@KVzhzJjx01`|>2;}vJ^3|zy{I5H+ zoSFOP-1E-wchCLZbMPK~5WJtL79R&7Ie9nO2$l`Ef`EhqVV(v+z=sHn0Kf;yv=d6D zj19w51zjLQk0Ep+DuLAk8O)?JV6dO7mI;J;h>~&)$rVdE)QKiDl_C~#s2Pzw22U1` zoDl!4P>viaOi33O<_TFMDmR9*U(HraWD-Ovpr|D$r3$v1L!BpQ6TUYLQz`Q)$~+D= z)_W@DC@+l?kIE5BB%Ki^WJED3Q4w@z1cMd9`j`^VU@~B4ILwF+V=~y0(QF2jvS3u= zG`Z+F`*6a6g|mnqhq`bnl}bfd?V+RcT$ssXv0z3x93CD>wP1!B3&ax z;KPUlEszTlB7LV9EMv#Z5rGnwr=#e}MHSOdph{G60+mtXk3`a$lnk*{gsK$t`8*yw zS*lP9q(US)fkP!2=wh*m9l!TLEHj+NN{9-NWik_)v59esv3sMUq9UW?n2E8BMQj2p zERY~lum*zj5s*~k&90uq62bNLYcoZTfBNL(W~+;U`4CfvUgQ1OcVoq zA9lqE+^U=9|wN(%?d;<#P~pXFE|aLw>Q$Vk(X=%PJ$rf zFR_+>ysd+`fPjr)mro)Y3IL=4h#UancR>*`O5v^MvuwloKm>Xla3aIk@hTGwBU!@26 z2K*Nl{se3$LqsLy0Kf(A@p7IRykS8W%}~>Tt892;rmm0cZi%0*x^8$@M6P&0>C|BJ z6+-JVeqyGo+6{MXeIM=brfX8_s%?sn`~v5w18etG(5naZExzgA3qeI# zrD@1o?|;g2XIf(^PW^&5(EikB`o(N z0<8ts^jMw{(oflv?FX*=cAfZVWa(#abC0LSZocN?%A7iGt9>AAlFpmhbAM{0x>w(D zzI7=7avyEB9Nl+8ZO)(v_nBPwDOw}_qQ2$bEjXA$$GNqf3zqnqjC0t{K5pLYdZDAY z-#oPc&b|Hq%&{vqBh8<-7lo2LWqrm%>Q+(iSzCy~?!20h2EjdZcfK?Bp7ZQ%lNob=r3kEk@I1>Fd{5yo zZQ55puI0jTrlFXo%bMHQUc!H^`!?jv2wbeuXWBzQXq)n@Gv4xG+d6FYY|NFit)_eP zc#NVIv-PtLg%i*19jB3L=wc1;>L0%)XUDXSWaGeE?}Mmu5YpV{n$=Y}wCU^RuV#DO zZp--%9(or1Y!oV}jw-);)aT`w1wU^2$P0y5Xqs{<>CiQj@(KI%oWMUk{yGn=C9kQm zFmK<}-hj4V+RdXu&z&FR;K-aV+T?Gi-76gHYMz|lX-rg)pVzylxn)2(jK!3D{*D7Q zW_T((#%6vnW3j;TQ$~I8(7jjhj^Q8>mW>bGvOEr!*JT+nmnY+lcGzh`e>?s`mS(z% znD+kd{}}LO*pp_khp!*`jut=qi*XYUHdxx!vqGn$&p*d-zesuRLT8E9v!|-n;gKPU86rfRYf<_ zs?gA&YHLXR{r*X3XV;CJs+)I5Ci`5sj*C>L_?XVhU6rLg@8`D3BF6#Es@w9q%+*(5 zF^2DUyU%Dksv2YbT>VtI7kgnYi_3ZWO^-^K za_|CNf!TF9I9Iy$Kj=4Ron`S)f;cPdfjfuvmNl(`79M9!h##g9r**UQV>6u0p3|WY f4;Qn$=5}aOd$A$H!@(yr+JPb0G!B04kAL?sYAF)f literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/sort_asc.png b/org.eclipse.winery.repository/src/main/webapp/images/sort_asc.png new file mode 100644 index 0000000000000000000000000000000000000000..a88d7975fe9017e4e5f2289a94bd1ed66a5f59dc GIT binary patch literal 1118 zcmbVLO=#0l98awuV{uMt6P_}u4rcI3idKFP2SpU%ZJIE?RL`X zK?Oyo=*5GG2SxDYK=7akJqV&hrl{aWJa`y*5xh+1%i2y4V}gO?edPc9{r;a9vjc}) zn|Cxb4AYwFmvVG%_ui)U^y_4!ujsO!qzYuv8YUIR!Aw%KiWp=JrG#@>(I!s4#N7H->?w+cxsH2#GA};A>g8lyFDGPKh!5)vuP_{)}*83+N zJUBU!S0_i+E{*Lu1iGsNB``2iK-CyCU7?y_mv{xb_pUh>ESZqe1Y2{eAZLMSIT%EO zFrdOH1W^=3p>Qk~I{J+k#s5zQ@j{%aIA!l^GQjJ zqA1Uc2%!{8qBKfMNh#9DCnKS_*uZ8?mnf!+8@f8xtz#prVg=E`3bCBLWsNmDAX~PG z<(4fQh=UOzE2?gKXRkc9XeI3Er?HlHECVd%SI}3`hy1_du3@$R$r(qT;k@Sft63UX zv;)2Ea_iH>^6+4jPK-lGM{Zw37Tz>~~zlHzO61x51(V4jcaKrcIVDG$-d>)z}S|7f!xxYhfUE}Kj zug_h&HZN}go22$5Ym1}P8~vYNx7-~$TWFJ;_nh!wFYSAQJF{CCo=xpK8^7?iY1^!H haOA^1D_`VC7fU=jcT literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/sort_asc_disabled.png b/org.eclipse.winery.repository/src/main/webapp/images/sort_asc_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..4e144cf0b1f786a9248a2998311e8109998d8a2d GIT binary patch literal 1050 zcmaJ=O-K|`93R^(@goeAz6hRU)S-61)?IaU({*Myml|8vh4x}JJM&z}b>>Yo&vx~s z*1>{0Sk$FMM28~iln?~vp$ zL+z1TilQ3g{c@7*P2Q^6L;g-8^nq-LaWstw(J;=d4x}PF%0Lh|)htXxRiC)>9(Gfd zk2X?ioL0_@8ZsHx!!QNYCTxo8?kU)+mV+2%VAin0^v_psXkh4J`eIPw6kCELM*pM( z2PX$o+GI}a)ajlxpt~Rv0TW^s6wEQp6$@dys4J4Qcg@nE2*J59y%|(mNdO5s5Cj>{ zuW=y`gm{Jzw6(Xlp9TWQb1WyYyx`~C#eg7k94LJ>@#g5mVp5Kkd=V>5k6>(zESt~g znS6jjPL}06J3BoMLGTlV-<`0qTJT$LYgs{tuI3mvHjo88MKy!QahN8NZl++`Te6m0 zDibLfTTpG5XE-mVGEhip#w2PB)JKi0I-PD8)*(7w)xTBHA4Yzu(Y*BKcijk8- zXslet#0bL39YHpb27^FRHN*1kB3@C%xaDHi(qLQ;(?o$W3|;IHBC-_Xc|nkPo{#bo zKE_Anh#c$_BEdk1ROZS^8#kea%Upe%D^%oqqhQ*^vkV>MD%4{RGC?tA(byrDwm?jZ z#$wTmdL^!2ITo%WmnFflUSt1hboq)*k9XV}TViYtKD5ZRJ7lb1H!ZJ`CviJ2M^c5A z%=*Sgk8hr8@-S*Kr`Ol~RJX(fddmmK4eR}O=#0l98WD1Hz^GK+C=e@fhgE~b#2$Ux^~T`1v5)mw1NlIe}zC z+ge9alrMQeN|SYi`>tC{zIG}!O_oO7k;UC8kBf>8sknx65F`zy2d1H-4fel=trX>@ z^-LCL<%6P%3`TJ=Ov$hao1$9VN|vJbLJV@SM>nJN{L>dS(6uOiBq(#Tm4F5Pz>p2Q zhq^NAP_G)%=(c^JwImV&17Zb~j6Ty5OHq1RS0sD)n5Dro1ouYi-$7;N6i6T&f*`~B zRW8JV5YO;|=5RQ?2M8R`v7Es2f}anI0YT(Au=3Evo2})=wA8uci&#;*fUzaAY_V8m ziU9`MJuDxIL|hF)@DqgJ88op{@|#XmML~j&YU>u(kqKNyC5HxZlqQk>PQkENWld+L zOr&6JNwHX-;oOueKw17j)G$`j4o<^A@%~fT$qZVMO+yC_*eYpUzR7iEi3uAj7}*(w z`YKgS6%a;F0a+l?9R#wX>ZWTi<7HV)nhsV>6(*%9O%xbi*F?TK!383rh#(|*p6}q} zd?z25;!?0(hzA2Li3(Rj>VN@FT;Xbexbdo7cN7eZc$T28pMYAYjSR4yvZz;&C0tc+ zg{xJMrKKvDCBd+6WB+P&<%mp=yImbyVyq56G|9BvWUP^I>ms=lb4e+lDSgg;Us`JO zKB6{wH+j~F#-A4FY3K3qm~Z6m@V6}oQ%8?p-E$dw`#0C$PJfmCV8)v}3>Ydha%`fZ zJk~G*M^A3LGk$Td;R`icF67R~`sBOHv)Hlqlc%$jy~9_oZJcNyWxkbb_O9u#|7hLF z-<-NMLzh3S0YA@8gd1Pt(Df|3@16Y-n=aSvsF@AkI`ioeFg>&H3bXU&vBnE6gIChkL+(Ey+0iB4Z$Eze7t_CX>Hq)$ literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/sort_desc.png b/org.eclipse.winery.repository/src/main/webapp/images/sort_desc.png new file mode 100644 index 0000000000000000000000000000000000000000..def071ed5afd264a036f6d9e75856366fd6ad153 GIT binary patch literal 1127 zcmbVMOK8+U7*1U&zKRu5sR)h{1;yRWWV^4}ShvZpU2*HWU2!iy(qy)cZ89;Lb+`3m zMbruv!GjkO!3qksP*5)lD)k}=Dp*ht-n@8G5m8XoN!zU+ih_Y;=AZe$?|)|~*Ri8v z(dtDU$2DZy)jV65`|pB!_H}d7Cv0h=sUqzpC0fy3%q0!dg+a#Bx^W(BM*oq=xP{{a zC9_bZ#q2IgCss)FbwX9kVQ7wPX{|b%-is;d!ri7V^Y8E8=YeU+{JuyQW*r6hnC$~D z?i}bS=mWia!r)uCftISo2rNuBP__DOPpZoN6tBeg{;|M=DHYl)^V3chvpJv;7lTL$ z26Y&PAc{gL+#HL=wg3?#C_qs_Vi3iouqZ(YW*(kdbB&UeSJN}Lm?ZN(lsb|iR4SEF zB^)Adw}29fgwG+0L8cM(`faLJgSNN6#-L(PcTI+l@K3y+Xf(g*^61+0|J+O6zN2mb?UNGh6GU@A{1+eF%d@N2(^XdVmhis(y25|iAr;gV=io5OsYy0 zB}Gv|2&GUGrBPB%s*yG^841Ug8a88lRI_zlvuiTDGuXsmv6A9qjS{y&NMEf3ay^6+ zuZK85>5PD^rkl1e`{kLAR>iJ)6dP%mSYRr@k~xQcDE=$%X{_--ITM&Og5Ml}G)wJ> zb)dhUZG9%p4iC23#JFrUCcmwHz{cugMoku~ue-kg{Mj0~%`FeCcz9jAdg}QET-kSG za`+2B_+lRTaeAVz>E`F1pN7h>B=BbGqcz13d%ywZR&4OjkNNrF_U}#EcXDGa@V52B z>JnIW7#s%CHi literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/sort_desc_disabled.png b/org.eclipse.winery.repository/src/main/webapp/images/sort_desc_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..7824973cc60fc1841b16f2cb39323cefcdc3f942 GIT binary patch literal 1045 zcmaJ=&rj1(9IuWjVlWt@h#q(rlc~7%$2P_q>KN??ODrK{#&I!}_Kh{rzS=%m2N%F- zAW={L0VZBJnRrkSCK{q1NKA||(ZmA>6Hgw9o;Z-;>)3_|u*vIt-(X0AeGY5Bm`Mgoq{>2>Xkbiu%Ds= zw2?31f^tL9kQr8eOxQDR!ltPHq-U$zG{j&MP8pU+Z@qp?149?-TQP-IYzdZ(;duv+ z&5z`@`Drbo)5+_g-xG*{39$-1bH;K7Po%550y+EF3=OIfJT20DK^2ryARz~WSeOlI zY%dFXxiA-r#^dp8fM+?DVR?q*LtI>l@B+(%+D8*_j$RaUa;D~sSR!4**cKS3TrP*p zkuY+m7%q`W_!>MPB8ZS%v9RieEVsL^AVXJk3>zEB0=}X;iDt1#lSubcFztq{<<`nX z3dVS<&2VAXPpJ-6l>b9bvw?PT4(`W$ps<^-*pSIV7tJ~vX67YQ8ELa7v~ZoP?{i~^a{W;-ZQ@ymjxh)IjDt*2O<6Dwh=q$vY$VY; zc&J{Ds~-?cjVm3>Wk@iL-`IZ|UB4pJ;~yJiON_?gLyJtiL&kbxZhV_OiPfx}%6s1@ zcXoG^ffrPJ;LQ4(`t<(ickJ1j|E0&fC8lSh8sUh5lwUg=l~QoqsK t`nTanN|e2@a&yVMdhyYhN3?KM^!+t}`s zR=_l^urXB7BqSctR9HdmVGo=3GQq>fC_I1=e^j9km{>a@@lY{_1S+DM`I04R5!JLI zPO^00efPWH-TChG7Q999uvF3a0npdC3$%hY@s>eI99N1H00S+^tODRI`ptstS^`BG z4k@cehL%c2oVzbqK!jPD$bD>j$s25c(m&tO3 zH0@Ce@;pz`48<^EZR%+#zi(jSan>;R#ElhBU_;i!5JIkp@8RMRCdP>o7DkvxjE%5dhL%z>IwL}kgHVDT zL@=I>FdP)Qm_#?QeTL)8hN3lib;Mi8O1H!cXvBm`KDVVP56if?G=b|LU zM|49q%TD$8+^kmAY<<6`W^A*B*ZM2y8}N%#EXHKw97l^Na|rneAC-DiDUMEOIEiJ6 zI#&HJJ)=-ERCPGk4NJp>Ca|hDM;{%U%cB`+V{Eh<-Y;NtZQy}=0j(hBeGjGpcKhO6 z6Ms|ca36-DTl6(AZddUxfKV&g1`IzI0=^LD4`JRM7)9@dA6t7rkQTVR_1+rWKddcx z1%d$c1^nx+U;D6QCvwU|vn@M9|GJdhvB7uF`0mf|c+C3_Y(gx)kUs>H;M$e-F_0d- zJk!4N)qAIUfBbC!*6y9x-!2Akn&mTcOxHSFIn~U8S+lXz0=a|)<3#oV0N8^EKr~YbX zk35&T^7*eba^TqJ$A8%JV*4`w&GtJDHS$c?{9BhFA`PYuV{(m~;yi0!rnGW)N literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/styledTabMenuButtonLeft.jpg b/org.eclipse.winery.repository/src/main/webapp/images/styledTabMenuButtonLeft.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fa0c98971c2b906bfdc22b0da0c43a111c0858b5 GIT binary patch literal 1549 zcmbVMe{2(V6#rhYU56T28JiOjkJ}cap}qU|*RGYiw7qsr?MB-zm<%-C-Lc)a-gS3Z z+f9YUAZjEci;~4(2>WMoKmv<@DErFrY_j9)QdQF1Ko0!c9?< zYKif3vtZ%mIF*hiC}^Q6u&z3th;i+LMl=g8qU0g39{q|WMBYPgbcE$?>p z+FjScb+>aao~(X?SeJIE z5Kn|cbAcD^Ry>}qE9b3h5n(=!1-;dVu7p5E1XWHdoPgZR^I+7wyAx#{Q8w;+MMRGh z>tJOr85bn2mi3UxV&O&J?Xy9!mV!e08y8Vg}(`2PVmOJtju%T7f zWVKaJ5dNsc0*Q^H#LFo)`#iU+Wd%iiUf_d@94B)9b&Ct|vjL~m8mwX%nnjsI=(4#S z0iV~)(EcD3u-nO5EdPIcMxkV=>~P#MEO`~0!0d5u^wDK*c?1bZvE^ZyS3 zj0J`FVE{*bcWU(pU4gL(ITz@RhDCXc4g;p8xS^m}zZ!ad%Sw&mAFL6sbNAu>(Y}h3 zMianr9d6X)d4GWE@M68`_)_Q%$Mz}94ma;FsW4P#&VdJT3?+q|KsC7Pyfl11I@#Mp zepGt;%*C5!y5fDGzA|#|ot?+YM@POmG&SH=+x6k ze)06b_T6H9eAQ>Kn#HsHf!|A3T)Es>^Zn>Rr1xn5<%2KOIm0vWA9;MqSp9g)42)q^$0(z4$7c5^4E xQk(vzq@lAXZ%lps+dy4g*U0s~*NaEL{_wzC!JAamh4|Jbw(8R}*QzsP{{i%X)9?TQ literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/images/styledTabMenuButtonRight.jpg b/org.eclipse.winery.repository/src/main/webapp/images/styledTabMenuButtonRight.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3329d7056494e5610cdfcd8019ffd8af80dff3dd GIT binary patch literal 1799 zcmbVMeM}Q)7=N#&rHK0|3SuJjJaC!L_U_u!UQer*_Udq{Qm8AU(_PyGDzsPI11b!4 z&JQ%Y4OcY_n&Iarn=@|NhlqkfWsI;4nOb#0F`FA~eoQx=3$D9j3;sdOvM0IR`@YZb z_k6w2^M*s=UXV%!T!jE+XHNwZFf8HUfYey#C|Lm@5XT=o0SNaB*GR>ITYha39FID=Oyvli2 zM`eja>qKVFgl7cEfZOY4I2sPPOFe!vphE_Yll(ezj3V$Lge%b@`iNIJ-<$&*SRVst z$}yP(Q{%8&CC62mR;8T=D=-{GaRrKLWH?4e9l5L*Jz6R;&(bEnp8za zg}g#3XMIH|uGMN$Oo1vCG9DrGukdhmK<4qM$1E5bzr*M9axT^bM=a8Iwv5vue58+3 zaC^<>A;Tk9%k7TjHHh|exy*1FBclD*6B*DD;Y(n&kcUZyQZNhL`Zk~5nWDY+R&huD-k^APhPBY5vMgEGx~5>+ zQ={GtwTs8CUR3?z!o~+H=?Ob_1t+n`x)bKULaWwy2P7>8LC1pLf`)VH#XoHnPezu! zFlP6l?%zUgx3!_qJRp3FPi|X#q0wA_J#8r^wjN#8)Z6^snaa%>Nm~>8 z`oZpl`x_1f`}+H)9{kbe;(vBx|K?grh9JpkU2MHaYEsBHQNxt+Dtmrses9jEOKtN$ zNGa-^IY5~W{}lZ-=V5hzcjL0Q=JM+7HvfTrRL!~McZq=$AIrM)$O?%5GW5}*o~H5( z+QWaSp0}L6nfTo09tQl9di9fIX+0eUQb84*8UKZ;{-W;S&+lyeew%k-cF1v}q+n%t z;hN+bC+4&B^0}JC850 z)$Tl8b%$EK>s&%L@itZ{xz_Ym|AIR?3x|eSc%&EF}W$%*X y3pwR$w&^F=PZ+O$7+R;Yq=vziYcHM-Y_gx}oM&Xu-(0$-?uXLG+faF8_~O5SsY_k} literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/main/webapp/js/.gitignore b/org.eclipse.winery.repository/src/main/webapp/js/.gitignore new file mode 100644 index 0000000000..23c1477206 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/js/.gitignore @@ -0,0 +1,3 @@ +# copied from topology modeler at mvn generate-sources +winery-common-topologyrendering.js +winery-support-common.js \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/js/boundaryDefinitionsXSelection.js b/org.eclipse.winery.repository/src/main/webapp/js/boundaryDefinitionsXSelection.js new file mode 100644 index 0000000000..afefc8c201 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/js/boundaryDefinitionsXSelection.js @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + * Tobias Binz - communication with the parent window + *******************************************************************************/ + + /** + * Called from the renderer as soon as the whole topology is loaded + */ + function wineryViewExternalScriptOnLoad() { + + function getIdOfNodeTemplateShape(element) { + var nodeTemplate = element.closest("div.NodeTemplateShape"); + var id = nodeTemplate.children("div.headerContainer").children("div.id").text(); + return id; + } + + jsPlumb.bind("ready", function() { + jsPlumb.bind("click", function(conn, originalEvent) { + var id = winery.connections[conn.id].id; + var message = { + targetRelationshipTemplateRef: id + } + sendMessage(message); + }); + }); + + + $("div.NodeTemplateShape").on("click", function(e) { + var id = getIdOfNodeTemplateShape($(e.target)); + // send id and empty property as no property has been clicked + var message = { + targetObjectRef: id, + targetPropertyRef: "" + }; + sendMessage(message); + + return false; + }); + + $("tr.KVProperty").on("click", function(e) { + var trKVProperty = $(e.target).closest("tr.KVProperty"); + var key = trKVProperty.children("td").children("span.KVPropertyKey").text(); + + var content = trKVProperty.closest("div.content"); + var elementName = content.children("span.elementName").text(); + + // form namespace-unaware XPath + var xpath = "/*[local-name()='" + elementName + "']/*[local-name()='" + key + "']"; + + var message = { + targetPropertyRef: xpath, + targetObjectRef: getIdOfNodeTemplateShape(trKVProperty) + }; + sendMessage(message); + + // do not trigger click on NodeTemplateShape -> we included both values in the message + return false; + }); + + $("div.requirements").on("click", function(e) { + var reqorcap = $(e.target).closest("div.requirements"); + var id = reqorcap.children("div.id").text(); + + var message = { + reqRef: id + }; + sendMessage(message); + + return false; + }); + + $("div.capabilities").on("click", function(e) { + var reqorcap = $(e.target).closest("div.capabilities"); + var id = reqorcap.children("div.id").text(); + + var message = { + capRef: id + }; + sendMessage(message); + + return false; + }); + + } + +function sendMessage(message) { + window.parent.postMessage(message, "*"); +} diff --git a/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-audio.js b/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-audio.js new file mode 100644 index 0000000000..9b683499a6 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-audio.js @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +// dummy as we don't need the functionality, but jquery.fileupload-ui.js requires it \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-image.js b/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-image.js new file mode 100644 index 0000000000..9b683499a6 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-image.js @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +// dummy as we don't need the functionality, but jquery.fileupload-ui.js requires it \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-validate.js b/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-validate.js new file mode 100644 index 0000000000..9b683499a6 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-validate.js @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +// dummy as we don't need the functionality, but jquery.fileupload-ui.js requires it \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-video.js b/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-video.js new file mode 100644 index 0000000000..9b683499a6 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/js/jquery.fileupload-video.js @@ -0,0 +1,12 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +// dummy as we don't need the functionality, but jquery.fileupload-ui.js requires it \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/js/nextselect.js b/org.eclipse.winery.repository/src/main/webapp/js/nextselect.js new file mode 100644 index 0000000000..050fcb16e8 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/js/nextselect.js @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +/* + +Script for dependent selection boxes. + +One object for stating a map from value to content. The value is globally unique. + +Verbose example: + + + + + + + + + */ + +/** + * + * @param value the current selected value + * @param targetElement the select to update + * @param dependendSelects the data structure for subsequently dependent select elements + * @param completeData the data structure with the complete data + */ +function updateListContent(value, targetElement, dependendSelects, completeData) { + jQuery(targetElement).empty(); + var listData = completeData[value]; + if (listData !== undefined) { + for (var i=0; i < listData.options.length; i++) { + var optionName = listData.options[i]; + var label = completeData[optionName].label; + var selected; + if (i == 0) { + selected = ' selected="selected"'; + } else { + selected = ''; + } + var toAppend = ''; + jQuery(targetElement).append(toAppend); + } + nextSelect = dependendSelects[targetElement]; + if (nextSelect !== undefined) { + // We assume listData is not empty + updateListContent(listData.options[0], nextSelect, dependendSelects, completeData); + } + } + jQuery(targetElement).trigger("change"); +} diff --git a/org.eclipse.winery.repository/src/main/webapp/js/winery-support-non-AMD.js b/org.eclipse.winery.repository/src/main/webapp/js/winery-support-non-AMD.js new file mode 100644 index 0000000000..1c4d7df45f --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/js/winery-support-non-AMD.js @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ + +function addResourceInstance() { + if (highlightRequiredFields()) { + vShowError("Please fill in all required fields"); + return; + } + + var dataToSend = $('#createResourceForm').serialize(); + var cr = $('#createResource'); + $.ajax({ + type: "POST", + async: false, + "data": dataToSend, + "url": cr.data("url"), + dataType: "text", + error: function(jqXHR, textStatus, errorThrown) { + vShowAJAXError("Could not create resource", jqXHR, errorThrown); + cr.modal("hide"); + }, + success: function(resData, textStatus, jqXHR) { + cr.data("onSuccess")($('#createResourceForm').serializeArray(), resData, textStatus, jqXHR); + cr.modal('hide'); + } + }); +} + +/** + * This function creates a dialog, where the user can add key/value pairs. + * These pairs are then sent to the given URL via POST. + * + * REQUIRES + + + +
    +
    + + + +
    + + + + + + + + + + + + + + + +
    PrefixNamespace
    ${w:getPrefix(ns.decoded)}${ns.decoded}
    +
    + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/admin/repository.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/admin/repository.jsp new file mode 100644 index 0000000000..202fc49e6d --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/admin/repository.jsp @@ -0,0 +1,101 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + +

    General Repository Commands

    +
    + +<% +org.eclipse.winery.repository.backend.IRepository rep; +rep = org.eclipse.winery.repository.Prefs.INSTANCE.getRepository(); +boolean isGitBasedRepo = (rep instanceof org.eclipse.winery.repository.backend.filebased.GitBasedRepository); + +org.eclipse.winery.repository.backend.filebased.GitBasedRepository repo = null; +if (isGitBasedRepo) { + repo = (org.eclipse.winery.repository.backend.filebased.GitBasedRepository) rep; +} + +// We only support the commit and reset buttons if we can authenticate at the repository +// This is a hack to offer different versionf of winery at dev.winery.opentosca.org and winery.opentosca.org +isGitBasedRepo = isGitBasedRepo && (repo.authenticationInfoAvailable()); + +if (isGitBasedRepo) { +%> +

    Versioning

    +
    + + +
    + + +<% +} +%> + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/admin/types/types.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/admin/types/types.jsp new file mode 100644 index 0000000000..25b2e0f312 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/admin/types/types.jsp @@ -0,0 +1,105 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +
    + + +
    + + + + + + + + + + + + + + + + + + + +
    Short nameLong Name
    ${type.shortName}${type.type}
    + + + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/artifacts/artifacts.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/artifacts/artifacts.jsp new file mode 100644 index 0000000000..40884311ec --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/artifacts/artifacts.jsp @@ -0,0 +1,141 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> +<%@taglib prefix="v" uri="http://www.eclipse.org/winery/repository/functions"%> +<%@taglib prefix="ct" tagdir="/WEB-INF/tags/common" %> + +<%-- +Parameter +isDeploymentArtifact: true/false +--%> + + + + + +
    +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameInterface NameOperation NameArtifact TemplateArtifact TypeSpecific Content
    ${a.a.name}${a.a.interfaceName}${a.a.operationName}${a.a.artifactRef.localPart}${a.a.artifactType.localPart} + + (exists) +
    +
    diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/componentnaming.jspf b/org.eclipse.winery.repository/src/main/webapp/jsp/componentnaming.jspf new file mode 100644 index 0000000000..877e60c318 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/componentnaming.jspf @@ -0,0 +1,28 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%-- + +Heading for a selected component (service template, node type, relationship type) + +Displays name + namespace + +--%> +
    +
    + ${it.name} +
    +
    + ${it.namespace} +
    +
    diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/documentation.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/documentation.jsp new file mode 100644 index 0000000000..55946a13ad --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/documentation.jsp @@ -0,0 +1,87 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions" %> + +<%-- TODO: source (external documentation) and lang attributes not yet supported --%> + + +
    +
    +
    + +
    + + + + + +
    + <%-- we only print a heading if we have multiple documentations. Otherwise, the documentation itself should be displayed --%> + +
    + ${content} +
    +
    + + "> + +
    +
    diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/artifacttemplates/artifacttemplate.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/artifacttemplates/artifacttemplate.jsp new file mode 100644 index 0000000000..60f95f2052 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/artifacttemplates/artifacttemplate.jsp @@ -0,0 +1,32 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions" %> + +<%@page import="org.eclipse.winery.repository.resources.SubMenuData"%> + +<% +java.util.List subMenus = new java.util.ArrayList(); + +SubMenuData data; + +data = new SubMenuData("#files", "Files"); +subMenus.add(data); + +data = new SubMenuData("#properties", "Properties"); +subMenus.add(data); +%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/artifacttemplates/files.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/artifacttemplates/files.jsp new file mode 100644 index 0000000000..1c06254238 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/artifacttemplates/files.jsp @@ -0,0 +1,18 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> + +<%@taglib prefix="fup" tagdir="/WEB-INF/tags/common"%> + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/policytemplates/policytemplate.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/policytemplates/policytemplate.jsp new file mode 100644 index 0000000000..e0e340c05c --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/policytemplates/policytemplate.jsp @@ -0,0 +1,29 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions" %> + +<%@page import="org.eclipse.winery.repository.resources.SubMenuData"%> + +<% +java.util.List subMenus = new java.util.ArrayList(); + +SubMenuData data; + +data = new SubMenuData("#properties", "Properties"); +subMenus.add(data); +%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/properties.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/properties.jsp new file mode 100644 index 0000000000..61134f214e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytemplates/properties.jsp @@ -0,0 +1,92 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> + +<%@page import="org.eclipse.winery.model.tosca.TEntityTemplate"%> +<%@page import="org.eclipse.winery.model.tosca.TEntityType"%> +<%@page import="org.eclipse.winery.common.ModelUtilities"%> +<%@page import="org.eclipse.winery.repository.Utils"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="props" tagdir="/WEB-INF/tags/common/templates" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions"%> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions" %> + + + + + + + + + +
    +
    <%-- This div is required by props:properties to be consistent with a node template. This mirrors div class="content" --%> + + +
    +
    + + + + + + + The type does not have a “properties definition”. + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypeimplementations/nodetypeimplementations/nodetypeimplementation.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypeimplementations/nodetypeimplementations/nodetypeimplementation.jsp new file mode 100644 index 0000000000..eec30c259e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypeimplementations/nodetypeimplementations/nodetypeimplementation.jsp @@ -0,0 +1,33 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions" %> + +<%@page import="org.eclipse.winery.repository.resources.SubMenuData"%> + +<% +java.util.List subMenus = new java.util.ArrayList(); + +SubMenuData data; + +data = new SubMenuData("#implementationartifacts", "Implementation Artifacts"); +subMenus.add(data); + +data = new SubMenuData("#deploymentartifacts", "Deployment Artifacts"); +subMenus.add(data); + +%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypeimplementations/relationshiptypeimplementations/relationshiptypeimplementation.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypeimplementations/relationshiptypeimplementations/relationshiptypeimplementation.jsp new file mode 100644 index 0000000000..97a9ad50dd --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypeimplementations/relationshiptypeimplementations/relationshiptypeimplementation.jsp @@ -0,0 +1,29 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> +<%@ taglib uri="http://www.eclipse.org/winery/repository/functions" prefix="w" %> + +<%@page import="org.eclipse.winery.repository.resources.SubMenuData"%> + +<% +java.util.List subMenus = new java.util.ArrayList(); + +SubMenuData data; + +data = new SubMenuData("#implementationartifacts", "Implementation Artifacts"); +subMenus.add(data); +%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/artifacttypes/artifacttype.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/artifacttypes/artifacttype.jsp new file mode 100644 index 0000000000..c51630af50 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/artifacttypes/artifacttype.jsp @@ -0,0 +1,26 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + +<%-- +TODO: implement update / subresource "file extension" +
    Associated File Extension
    + +
    + value="${it.associatedFileExtension}" /> +
    +--%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/capabilitytypes/capabilitytype.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/capabilitytypes/capabilitytype.jsp new file mode 100644 index 0000000000..2e2b2f0601 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/capabilitytypes/capabilitytype.jsp @@ -0,0 +1,17 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/implementations.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/implementations.jsp new file mode 100644 index 0000000000..46ef5a8cba --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/implementations.jsp @@ -0,0 +1,63 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + + + + + +

    +This page shows implementations available for this type. +Go to Other Elements to get an overview on all implementations stored in this repository. +

    + +
    + + + + + +
    +
    diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/instancestates.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/instancestates.jsp new file mode 100644 index 0000000000..059ae55f30 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/instancestates.jsp @@ -0,0 +1,86 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + +
    + + + + + + + + + + + + + + + + +
    State
    ${t}
    +
    + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/nodetype.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/nodetype.jsp new file mode 100644 index 0000000000..f9d52d795a --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/nodetype.jsp @@ -0,0 +1,44 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + +<%@page import="org.eclipse.winery.repository.resources.SubMenuData"%> + +<% +java.util.List subMenus = new java.util.ArrayList(); + +SubMenuData data; + +data = new SubMenuData("#visualappearance", "Visual Appearance"); +subMenus.add(data); + +data = new SubMenuData("#instancestates", "Instance States"); +subMenus.add(data); + +data = new SubMenuData("#interfaces", "Interfaces"); +subMenus.add(data); + +data = new SubMenuData("#implementations", "Implementations"); +subMenus.add(data); + +data = new SubMenuData("#requirementdefinitions", "Requirement Definitions"); +subMenus.add(data); + +data = new SubMenuData("#capabilitydefinitions", "Capability Definitions"); +subMenus.add(data); + +%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/reqandcapdefs/capdefs.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/reqandcapdefs/capdefs.jsp new file mode 100644 index 0000000000..3faf901671 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/reqandcapdefs/capdefs.jsp @@ -0,0 +1,17 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags/entitytypes/nodetypes/reqandcapdefs" %> + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/reqandcapdefs/reqdefs.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/reqandcapdefs/reqdefs.jsp new file mode 100644 index 0000000000..08657a135c --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/reqandcapdefs/reqdefs.jsp @@ -0,0 +1,17 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags/entitytypes/nodetypes/reqandcapdefs" %> + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/visualappearance.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/visualappearance.jsp new file mode 100644 index 0000000000..d12501e8e0 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/nodetypes/visualappearance.jsp @@ -0,0 +1,85 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + + + + + + + + +
    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/appliesto.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/appliesto.jsp new file mode 100644 index 0000000000..ff15a393bc --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/appliesto.jsp @@ -0,0 +1,25 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + +
      + +
    • ${nodeTypeReference.typeRef}
    • +
      +
    + + +Update not yet implemented. diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/language.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/language.jsp new file mode 100644 index 0000000000..c1815bd718 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/language.jsp @@ -0,0 +1,21 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + ${it.language} + + +Update not yet implemented. diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/policytype.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/policytype.jsp new file mode 100644 index 0000000000..694abad19e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/policytypes/policytype.jsp @@ -0,0 +1,32 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + +<%@page import="org.eclipse.winery.repository.resources.SubMenuData"%> + +<% +java.util.List subMenus = new java.util.ArrayList(); + +SubMenuData data; + +data = new SubMenuData("#language", "Language"); +subMenus.add(data); + +data = new SubMenuData("#appliesto", "Applies To"); +subMenus.add(data); + +%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/properties/propertiesDefinition.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/properties/propertiesDefinition.jsp new file mode 100644 index 0000000000..a0e22df6d9 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/properties/propertiesDefinition.jsp @@ -0,0 +1,320 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags"%> +<%@taglib prefix="ct" tagdir="/WEB-INF/tags/common"%> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions"%> + +<%-- createResource of winery-support.js could be used. However, currently selects are not supported --%> + + + + +

    + <%-- TODO: if clicked on the "label" of the input field (i.e., the content of the input tag), the input should be selected. This is not the default at HTML5 - see http://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_input_type_radio --%> + + checked="checked">(none) +
    + + checked="checked">XML element + ${it.entityType.propertiesDefinition.element.localPart} +
    + + checked="checked">XML type + ${it.entityType.propertiesDefinition.type.localPart} +
    + + + checked="checked">Custom key/value pairs +

    + + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/relationshiptype.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/relationshiptype.jsp new file mode 100644 index 0000000000..ba2e6ccab7 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/relationshiptype.jsp @@ -0,0 +1,44 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + +<%@page import="org.eclipse.winery.repository.resources.SubMenuData"%> + +<% +java.util.List subMenus = new java.util.ArrayList(); + +SubMenuData data; + +data = new SubMenuData("#visualappearance", "Visual Appearance"); +subMenus.add(data); + +data = new SubMenuData("#instancestates", "Instance States"); +subMenus.add(data); + +data = new SubMenuData("#sourceinterfaces", "Source Interfaces"); +subMenus.add(data); + +data = new SubMenuData("#targetinterfaces", "Target Interfaces"); +subMenus.add(data); + +data = new SubMenuData("#validendings", "Valid Sources and Targets"); +subMenus.add(data); + +data = new SubMenuData("#implementations", "Implementations"); +subMenus.add(data); + +%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/validendings.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/validendings.jsp new file mode 100644 index 0000000000..4bf2145843 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/validendings.jsp @@ -0,0 +1,39 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="rt" tagdir="/WEB-INF/tags/relationshiptype" %> + +

    Valid Source

    +Node Type: + + +
    +Requirement Type: + + + +
    +
    +

    Valid Target

    +Node Type: + + +
    +Capability Type: + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/visualappearance.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/visualappearance.jsp new file mode 100644 index 0000000000..b8d9ceba10 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/relationshiptypes/visualappearance.jsp @@ -0,0 +1,207 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + + + + + + + + + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/requirementtypes/requiredcapabilitytype.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/requirementtypes/requiredcapabilitytype.jsp new file mode 100644 index 0000000000..0b1027718f --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/requirementtypes/requiredcapabilitytype.jsp @@ -0,0 +1,56 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="ct" tagdir="/WEB-INF/tags/common" %> + + + + + + + + + + + + + \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/requirementtypes/requirementtype.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/requirementtypes/requirementtype.jsp new file mode 100644 index 0000000000..a8b6f43168 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/entitytypes/requirementtypes/requirementtype.jsp @@ -0,0 +1,30 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + +<%@page import="org.eclipse.winery.repository.resources.SubMenuData"%> + +<% +java.util.List subMenus = new java.util.ArrayList(); + +SubMenuData data; + +data = new SubMenuData("#requiredcapabilitytype", "Required Capability Type"); +subMenus.add(data); + +%> + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/genericcomponentpage.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/genericcomponentpage.jsp new file mode 100644 index 0000000000..04399045ea --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/genericcomponentpage.jsp @@ -0,0 +1,209 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="v" uri="http://www.eclipse.org/winery/repository/functions" %> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions" %> + +<%-- In English, one can usually form a plural by adding an "s". Therefore, we resue the label to form the window title --%> + + + + + + + + + + + + + + +
    +
    + + + + + + + +
    + +
    + + + + + +
    + + + <%-- even though the id is an invalid XML, it is used for a simple implementation on a click on the graphical rendering to trigger opening the editor --%> +
    +
    + + + + + +
    +
    +
    +
    + ${wc:escapeHtml4(t.xmlId.decoded)} +
    +
    + ${wc:escapeHtml4(t.namespace.decoded)} +
    +
    +
    + + + <%-- we need double encoding of the URL as the passing to javascript: decodes the given string once --%> + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + +
    diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/hashloading.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/hashloading.jsp new file mode 100644 index 0000000000..eb5bbfa82e --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/hashloading.jsp @@ -0,0 +1,140 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/imports/xsdimports/xsdimport.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/imports/xsdimports/xsdimport.jsp new file mode 100644 index 0000000000..452e7adabf --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/imports/xsdimports/xsdimport.jsp @@ -0,0 +1,50 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +<%-- Quick hack without XML view --%> + +<%-- +FIXME: parameters cssClass and selected are somehow ignored, but replaced by the data provided by GenericComponentPageData or similar... +Symptom: in header.jsp "param.selected" is "XSDImport" instead of "xsdimport" +--%> + + +
    + <%@ include file="/jsp/componentnaming.jspf" %> + +
    + +
    + +Associated file: +none +${it.location} + +
    + +Modification not yet implemented + +
    + +
    + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/inheritance.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/inheritance.jsp new file mode 100644 index 0000000000..8d1d535503 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/inheritance.jsp @@ -0,0 +1,55 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> + +
    + + +
    + +
    + + +
    + +
    + +
    + + +
    +
    + + \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/interfaces/interfaces.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/interfaces/interfaces.jsp new file mode 100644 index 0000000000..07ed928fae --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/interfaces/interfaces.jsp @@ -0,0 +1,489 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - port to bootstrap 3 + *******************************************************************************/ +--%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> +<%@taglib prefix="ct" tagdir="/WEB-INF/tags/common" %> +<%@taglib prefix="p" tagdir="/WEB-INF/tags/parameters" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions"%> + +<%@page import="org.eclipse.winery.common.Util" %> +<%@page import="org.eclipse.winery.repository.Constants" %> + + + + +<%-- include basic parameters support --%> + + + + + + + +
    +
    +
    + + + +
    + + + +
    + +
    +
    + + + +
    + +
    + +
    + +

    + +
    +
    diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/otherElements.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/otherElements.jsp new file mode 100644 index 0000000000..15d3e7df03 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/otherElements.jsp @@ -0,0 +1,44 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + + + +

    +The following items list TOSCA elements contained in TOSCA's Definitions element, which are not listed as separate tabs. +

    + +

    Artifacts

    +Artifact Types +Artifact Templates + +

    Requirements and Capabilities

    +Requirement Types +Capability Types + +

    Implementations

    +Node Type Implementations +Relationship Type Implementations + +

    Policies

    +Policy Types +Policy Templates + +

    Imports

    +XML Schema Definitions +WSDLs + +
    diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/boundarydefinitions/boundarydefinitions.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/boundarydefinitions/boundarydefinitions.jsp new file mode 100644 index 0000000000..aadec72053 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/boundarydefinitions/boundarydefinitions.jsp @@ -0,0 +1,1080 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Tobias Binz - communication with the nested iframe + *******************************************************************************/ +--%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="w" tagdir="/WEB-INF/tags"%> +<%@taglib prefix="o" tagdir="/WEB-INF/tags/common/orioneditor"%> +<%@taglib prefix="b" tagdir="/WEB-INF/tags/servicetemplates/boundarydefinitions"%> +<%@taglib prefix="pol" tagdir="/WEB-INF/tags/common/policies" %> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions"%> +<%@taglib prefix="wr" uri="http://www.eclipse.org/winery/repository/functions"%> + +<%@page import="org.eclipse.winery.common.ModelUtilities"%> + + + + + + + + + + + +
    + + +
    + +
    + <%-- reloadAfterSuccess is necessary as the XMLtree has to be changed --%> + ${it.definedPropertiesAsEscapedHTML} +
    + +
    + + +

    No properties available. Thus, no properties can be mapped. Please define properties.

    +
    + + + + + + + + + + + + + + + + + + <%-- .name cannot be used as it is not an Id. Future work: Store the id in a seperate field and show the name to the user --%> + + + + + +
    Service Template PropertyTargetTarget Property
    ${propertyMapping.serviceTemplatePropertyRef}${propertyMapping.targetObjectRef.id}${propertyMapping.targetPropertyRef}
    +
    +
    +
    + + <%-- TODO: provide this as .tag. The property constraint resource should also be provided as tag --%> +
    + + + + + + + + + + + + + + + + + + + + +
    (internal id)Service Template PropertyConstraint TypeConstraint
    example/demohttp://www.example.com/accessrestrictions(not yet implemented)
    +
    + +
    + + + + + + + <%-- of the boundary requirement, also used as the id of this element--%> + + + + + + + + + + + + + +
    (Id)NameReference
    ${wr:determineIdUsingHashCode(item)}${item.name}${item.ref.id}
    +
    + +
    + <%-- mirrored from requirements --%> + + + + + + + <%-- of the boundary requirement, also used as the id of this element--%> + + + + + + + + + + + + + +
    (Id)NameReference
    ${wr:determineIdUsingHashCode(item)}${item.name}${item.ref.id}
    +
    + +
    + +
    + +
    + + + + + + + + + + +
    +

    Provided Interface and Operation

    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +

    Target

    + +
    + + + +
    + +
    +
    + +
    + +
    + +
    + + + + +
    + +

    Target Interface and Operation

    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    +
    + + + +
    + + + +
    + ${it.boundaryDefinitionsAsXMLStringEncoded} +
    +
    +
    + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/plans/plans.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/plans/plans.jsp new file mode 100644 index 0000000000..c5a6dc7be6 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/plans/plans.jsp @@ -0,0 +1,199 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="p" tagdir="/WEB-INF/tags/parameters" %> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + + + + + + + + + +
    +

    Embedded Plans

    + + + + +
    + +

    +

    Linked Plans

    +
    +
    diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/selfservicemetadata/selfservicemetadata.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/selfservicemetadata/selfservicemetadata.jsp new file mode 100644 index 0000000000..d4d92336f4 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/selfservicemetadata/selfservicemetadata.jsp @@ -0,0 +1,256 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="o" tagdir="/WEB-INF/tags/common/orioneditor"%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions"%> + +<%-- Upload functionality inspired by plans.jsp. That code could be generalized somehow in a .tag file --%> + + + +
    + +
    + + +
    + +
    ${it.application.description}
    +
    +
    + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    IdNameIconPlan Service Name
    ${option.id}${option.name}${option.planServiceName}
    +
    + +
    + ${it.applicationAsXMLStringEncoded} +
    + +
    + + + + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/servicetemplate.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/servicetemplate.jsp new file mode 100644 index 0000000000..535dc12ddb --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/servicetemplate.jsp @@ -0,0 +1,43 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@page import="org.eclipse.winery.repository.resources.SubMenuData"%> + +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + + +<% +java.util.List subMenus = new java.util.ArrayList(5); + +SubMenuData data; + +data = new SubMenuData("#topologytemplate", "Topology Template"); +subMenus.add(data); + +data = new SubMenuData("#plans", "Plans"); +subMenus.add(data); + +data = new SubMenuData("#selfserviceportal", "Self-service Portal"); +subMenus.add(data); + +data = new SubMenuData("#boundarydefinitions", "Boundary Definitions"); +subMenus.add(data); + +//Tags are currently not implemented -> Don't confuse users by showing the tab +//has to be enabled again, when tags are implemented +//data = new SubMenuData("#tags", "Tags"); +//subMenus.add(data); +%> + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/topologytemplates/topologytemplate.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/topologytemplates/topologytemplate.jsp new file mode 100644 index 0000000000..86392f31b1 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/topologytemplates/topologytemplate.jsp @@ -0,0 +1,23 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> + +
    + Open Editor + Open View +
    +
    +
    Loading preview...
    + +
    diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/topologytemplates/topologytemplateview.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/topologytemplates/topologytemplateview.jsp new file mode 100644 index 0000000000..25955b84d3 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/servicetemplates/topologytemplates/topologytemplateview.jsp @@ -0,0 +1,67 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> +<%@page buffer="none" %> + +<%@page import="org.eclipse.winery.common.interfaces.IWineryRepository"%> +<%@page import="org.eclipse.winery.repository.Prefs" %> +<%@page import="org.eclipse.winery.repository.client.WineryRepositoryClientFactory"%> +<%@page import="org.eclipse.winery.repository.client.IWineryRepositoryClient"%> +<%@page import="org.eclipse.winery.repository.client.WineryRepositoryClient"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> +<%@taglib prefix="w" uri="http://www.eclipse.org/winery/repository/functions"%> + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/setupTriggerRemoveByDELKey.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/setupTriggerRemoveByDELKey.jsp new file mode 100644 index 0000000000..ea478325c7 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/setupTriggerRemoveByDELKey.jsp @@ -0,0 +1,28 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%-- +JavaScript snippet binding the delete button to a trigger of the "Remove" button in case there is only one such button and that no input field is selected +--%> + + var removeButtons = $("button:contains('Remove')"); + if (removeButtons.length == 1) { + requirejs(["keyboardjs"], function(KeyboardJS) { + KeyboardJS.on("del", function() { + if ($(document.activeElement).is("body")) { + // we are not in an input field etc. + removeButtons.trigger("click"); + } + }); + }); + } diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/shared/.gitignore b/org.eclipse.winery.repository/src/main/webapp/jsp/shared/.gitignore new file mode 100644 index 0000000000..6e112edf18 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/shared/.gitignore @@ -0,0 +1,3 @@ +#This directory is generated via mvn generate-sources +#The content is copied from org.eclipse.winery.topologymodeler +* \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/tags/tags.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/tags/tags.jsp new file mode 100644 index 0000000000..c47271d964 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/tags/tags.jsp @@ -0,0 +1,14 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +Not yet implemented diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/test.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/test.jsp new file mode 100644 index 0000000000..2fbfb993a7 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/test.jsp @@ -0,0 +1,33 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + + + + + + + + + diff --git a/org.eclipse.winery.repository/src/main/webapp/jsp/xmlSource.jsp b/org.eclipse.winery.repository/src/main/webapp/jsp/xmlSource.jsp new file mode 100644 index 0000000000..bec5e111a4 --- /dev/null +++ b/org.eclipse.winery.repository/src/main/webapp/jsp/xmlSource.jsp @@ -0,0 +1,20 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> + +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions" %> +<%@taglib prefix="o" tagdir="/WEB-INF/tags/common/orioneditor"%> + +${wc:escapeHtml4(it.definitionsAsXMLString)} + +

    Save leads to a synchronization with the other tabs

    \ No newline at end of file diff --git a/org.eclipse.winery.repository/src/psd/Sorting icons.psd b/org.eclipse.winery.repository/src/psd/Sorting icons.psd new file mode 100644 index 0000000000000000000000000000000000000000..53b2e06850767cb57c52b316f0b845b1a8e0ca0e GIT binary patch literal 27490 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 Y16@Zf7?Q8!JB-NJ(KYBs*Ff|C0Zg4MIsgCw literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.repository/src/psd/header_background_plain.png b/org.eclipse.winery.repository/src/psd/header_background_plain.png new file mode 100644 index 0000000000000000000000000000000000000000..41015fe71cd1c7f5a03db7a6972c7a8d2bbfe0aa GIT binary patch literal 36026 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

    Wj_5&uhA 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
    <@4^kC?W>8+wUKt8VB^ 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%0Drul{tX*DM(`C) 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 conf = new HashMap<>(); + try { + exporter.exportTOSCA(TestToscaExporter.serviceTemplateId, output, conf); + } catch (JAXBException e) { + throw new WebApplicationException(e); + } + } + }; + + // TODO: check output contained in SO + } + + @Test + public void checkCSARExport() throws Exception { + NullOutputStream out = new NullOutputStream(); + TestToscaExporter.csarExporter.writeCSAR(TestToscaExporter.serviceTemplateId, out); + } +} diff --git a/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/importing/TestCSARImporter.java b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/importing/TestCSARImporter.java new file mode 100644 index 0000000000..ea8beb193d --- /dev/null +++ b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/importing/TestCSARImporter.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.importing; + +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.eclipse.winery.repository.PrefsTestEnabledUsingConfiguredRepository; + +public class TestCSARImporter { + + /** + * Ensure that Repository.INSTANCE exists + */ + @BeforeClass + public static void setupPrefs() throws Exception { + // Initialize preferences + // We do not need them directly, but constructing them has the side effect that Repository.INSTANCE is != null + new PrefsTestEnabledUsingConfiguredRepository(); + } + + /** + * Quick hack to test Moodle Import + * + * Currently, no CSARs are put into the test resources, we rely on local + * CSARs + */ + @Test + public void testMoodleImport() throws Exception { + CSARImporter i = new CSARImporter(); + Path p = FileSystems.getDefault().getPath("C:\\Users\\Oliver\\BTSync\\TOSCA\\CSARs\\Moodle"); + List errors = new ArrayList(); + i.importFromDir(p, errors); + } +} diff --git a/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/TestAbstractComponentInstanceResourceDefinitionsBacked.java b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/TestAbstractComponentInstanceResourceDefinitionsBacked.java new file mode 100644 index 0000000000..1e6595467d --- /dev/null +++ b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/TestAbstractComponentInstanceResourceDefinitionsBacked.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import java.io.IOException; + +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.CapabilityTypeId; +import org.eclipse.winery.repository.backend.MockXMLElement; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.resources.entitytypes.capabilitytypes.CapabilityTypeResource; +import org.junit.Assert; +import org.junit.Test; + +public class TestAbstractComponentInstanceResourceDefinitionsBacked extends TestResource { + + private static final CapabilityTypeId id = new CapabilityTypeId(TestResource.NS, new XMLId("testCapabilityType", false)); + + + @Test + public void testPlainPersist() throws IOException { + // ensure that no test object exists + Repository.INSTANCE.forceDelete(TestAbstractComponentInstanceResourceDefinitionsBacked.id); + + CapabilityTypeResource res = new CapabilityTypeResource(TestAbstractComponentInstanceResourceDefinitionsBacked.id); + res.persist(); + Assert.assertTrue("Element has to exist", Repository.INSTANCE.exists(TestAbstractComponentInstanceResourceDefinitionsBacked.id)); + } + + @Test + public void testPersistWithData() throws IOException { + // ensure that no test object exists + Repository.INSTANCE.forceDelete(TestAbstractComponentInstanceResourceDefinitionsBacked.id); + + CapabilityTypeResource res = new CapabilityTypeResource(TestAbstractComponentInstanceResourceDefinitionsBacked.id); + res.getElement().getAny().add(new MockXMLElement()); + res.persist(); + Assert.assertTrue("Element has to exist", Repository.INSTANCE.exists(TestAbstractComponentInstanceResourceDefinitionsBacked.id)); + + // reload data + res = new CapabilityTypeResource(TestAbstractComponentInstanceResourceDefinitionsBacked.id); + + Assert.assertEquals(1, res.getElement().getAny().size()); + } +} diff --git a/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/TestResource.java b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/TestResource.java new file mode 100644 index 0000000000..2841942bca --- /dev/null +++ b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/TestResource.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources; + +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.repository.TestWithRepositoryConnection; + +public abstract class TestResource extends TestWithRepositoryConnection { + + protected static final String TESTNS = "http://www.example.org/winery/test/resources"; + protected static final Namespace NS = new Namespace(TestResource.TESTNS, false); + +} diff --git a/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/TestArtifactTemplateResource.java b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/TestArtifactTemplateResource.java new file mode 100644 index 0000000000..e7e3e5a570 --- /dev/null +++ b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytemplates/artifacttemplates/TestArtifactTemplateResource.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytemplates.artifacttemplates; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId; +import org.eclipse.winery.repository.PrefsTestEnabledGitBackedRepository; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.backend.filebased.GitBasedRepository; +import org.eclipse.winery.repository.resources.AbstractComponentsResource; + +public class TestArtifactTemplateResource { + + @BeforeClass + public static void init() throws Exception { + // enable git-backed repository + new PrefsTestEnabledGitBackedRepository(); + } + + @Before + public void setRevision() throws Exception { + ((GitBasedRepository) Repository.INSTANCE).setRevisionTo("97fa997b92965d8bc84e86274b0203f1db7495c5"); + } + + @Test + public void countMatches() { + ArtifactTemplateId id = new ArtifactTemplateId("http%3A%2F%2Fdocs.oasis-open.org%2Ftosca%2Fns%2F2011%2F12%2FToscaSpecificTypes", "at-0cd9ab5d-6c2e-4fc2-9cb0-3fee1e431f9f", true); + ArtifactTemplateResource res = (ArtifactTemplateResource) AbstractComponentsResource.getComponentInstaceResource(id); + Assert.assertEquals(1, res.getReferenceCount()); + } +} diff --git a/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/TestCapabilityTypeResource.java b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/TestCapabilityTypeResource.java new file mode 100644 index 0000000000..098d59a946 --- /dev/null +++ b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytypes/capabilitytypes/TestCapabilityTypeResource.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.capabilitytypes; + +import java.io.IOException; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.eclipse.winery.common.ids.Namespace; +import org.eclipse.winery.common.ids.XMLId; +import org.eclipse.winery.common.ids.definitions.CapabilityTypeId; +import org.eclipse.winery.repository.PrefsTestEnabledGitBackedRepository; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.backend.filebased.GitBasedRepository; +import org.eclipse.winery.repository.resources.TestResource; + +public class TestCapabilityTypeResource extends TestResource { + + private static final CapabilityTypeId id = new CapabilityTypeId(new Namespace("http://docs.oasis-open.org/tosca/ns/2011/12/ToscaBaseTypes", false), new XMLId("ContainerCapability", false)); + + + @BeforeClass + public static void init() throws Exception { + // enable git-backed repository + new PrefsTestEnabledGitBackedRepository(); + } + + @Before + public void setRevision() throws Exception { + ((GitBasedRepository) Repository.INSTANCE).setRevisionTo("97fa997b92965d8bc84e86274b0203f1db7495c5"); + } + + @Test + public void getElementAsXMLString() throws IOException { + // ensure that no test object exists + Repository.INSTANCE.forceDelete(TestCapabilityTypeResource.id); + + CapabilityTypeResource res = new CapabilityTypeResource(TestCapabilityTypeResource.id); + String s = res.getDefinitionsAsXMLString(); + Assert.assertNotNull(s); + } +} diff --git a/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/TestRequirementDefinitions.java b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/TestRequirementDefinitions.java new file mode 100644 index 0000000000..47ee3d05d0 --- /dev/null +++ b/org.eclipse.winery.repository/src/test/java/org/eclipse/winery/repository/resources/entitytypes/nodetypes/reqandcapdefs/TestRequirementDefinitions.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.repository.resources.entitytypes.nodetypes.reqandcapdefs; + +import javax.ws.rs.core.MediaType; + +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.eclipse.winery.repository.PrefsTestEnabledGitBackedRepository; +import org.eclipse.winery.repository.backend.Repository; +import org.eclipse.winery.repository.backend.filebased.GitBasedRepository; + +import com.jayway.restassured.RestAssured; +import com.jayway.restassured.http.ContentType; +import com.jayway.restassured.path.json.JsonPath; +import com.jayway.restassured.response.Response; + +//@formatter:off + +/* + * import static com.jayway.restassured.RestAssured.*; import static + * com.jayway.restassured.matcher.RestAssuredMatchers.*; import static + * org.hamcrest.Matchers.*; import static + * com.jayway.restassured.path.json.JsonPath.*; + */ + + +/** + * REST-based testing of requirement definitions + * + * We use a fixed method sort order as we create resources in one test and work + * with them in the next step + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestRequirementDefinitions { + + @BeforeClass + public static void init() throws Exception { + // enable git-backed repository + new PrefsTestEnabledGitBackedRepository(); + + // we use a half-filled repository + ((GitBasedRepository) Repository.INSTANCE).setRevisionTo("97fa997b92965d8bc84e86274b0203f1db7495c5"); + + // we test on the Amazon EC2 node type + // could be any other node type without requirement definitions + // + // the following URI is already encoded (copied from the browser URL field) + RestAssured.urlEncodingEnabled = false; + RestAssured.basePath = "/org.eclipse.winery.repository/nodetypes/http%253A%252F%252Fwww.example.org%252Ftosca%252Fnodetypes/Amazon_EC2/requirementdefinitions"; + } + + @Test + public void test01_NoRequirementDefinitions() throws Exception { + RestAssured.given() + .header("Accept", MediaType.APPLICATION_JSON) + .expect() + .body(Matchers.equalTo("[]")) + .when() + .get(""); + } + + @Test + public void test02_CreateRequirementDefinition() throws Exception { + RestAssured.given() + .parameter("name", "test") + .expect() + .statusCode(204) + .when() + .post("/"); + } + + @Test + public void test03_NoConstraints() throws Exception { + RestAssured.given() + .header("Accept", MediaType.APPLICATION_JSON) + .expect() + .body(Matchers.equalTo("[]")) + .when() + .get("test/constraints/"); + } + + @Test + public void test04_CreateConstraint() throws Exception { + RestAssured.given() + .body("") + .contentType(ContentType.XML) + .expect() + .statusCode(200) + .body(Matchers.notNullValue()) + .when() + .post("test/constraints/"); + } + + @Test + public void test05_GetConstraint() throws Exception { + Response response = RestAssured + .given() + .header("Accept", MediaType.APPLICATION_JSON) + .expect() + .statusCode(200) + .when() + .get("test/constraints/"); + + // extract answer + JsonPath jsonPath = JsonPath.from(response.asString()); + + Assert.assertEquals("One id", jsonPath.getList("").size(), 1); + + String id = jsonPath.getString("[0]"); + + // TODO: check content + RestAssured + .given() + .header("Accept", MediaType.TEXT_XML) + .expect() + .statusCode(200) + .when() + .get("test/constraints/{id}/", id); + + // we also test the sub resource here + // otherwise we had to transport the id throught the code via a global variable + RestAssured + .expect() + .statusCode(200) + .body(Matchers.is("http://www.example.org/constrainttype")) + .when() + .get("test/constraints/{id}/type", id); + } + +} diff --git a/org.eclipse.winery.repository/src/test/resources/.gitignore b/org.eclipse.winery.repository/src/test/resources/.gitignore new file mode 100644 index 0000000000..124957750e --- /dev/null +++ b/org.eclipse.winery.repository/src/test/resources/.gitignore @@ -0,0 +1 @@ +/winery.properties diff --git a/org.eclipse.winery.repository/src/test/resources/logback-test.xml b/org.eclipse.winery.repository/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..396bad71cf --- /dev/null +++ b/org.eclipse.winery.repository/src/test/resources/logback-test.xml @@ -0,0 +1,15 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}:%line %method - %msg%n + + + + + + + + + \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/.bowerrc b/org.eclipse.winery.topologymodeler/.bowerrc new file mode 100644 index 0000000000..eb92b22ed1 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory" : "src/main/webapp/components" +} \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/.gitattributes b/org.eclipse.winery.topologymodeler/.gitattributes new file mode 100644 index 0000000000..03b24943e2 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/.gitattributes @@ -0,0 +1 @@ +bower.json eol=lf diff --git a/org.eclipse.winery.topologymodeler/.gitignore b/org.eclipse.winery.topologymodeler/.gitignore new file mode 100644 index 0000000000..166eaf4def --- /dev/null +++ b/org.eclipse.winery.topologymodeler/.gitignore @@ -0,0 +1,23 @@ +.classpath +/.gradle +.project +.settings/.jsdtscope +.settings/org.eclipse.core.resources.prefs +.settings/org.eclipse.jdt.core.prefs +.settings/org.eclipse.m2e.core.prefs +.settings/org.eclipse.wst.common.component +.settings/org.eclipse.wst.common.project.facet.core.xml +.settings/org.eclipse.wst.common.project.facet.core.prefs.xml +.settings/org.eclipse.wst.jsdt.ui.superType.container +.settings/org.eclipse.wst.jsdt.ui.superType.name +.settings/org.eclipse.wst.validation.prefs +/.sonar +/bin +/build +sonar-project.properties +/src/main/java/rebel.xml +/src/main/resources/rebel.xml +/target + +#Generated by "bower install" +src/main/webapp/components/ diff --git a/org.eclipse.winery.topologymodeler/.settings/de.loskutov.anyedit.AnyEditTools.prefs b/org.eclipse.winery.topologymodeler/.settings/de.loskutov.anyedit.AnyEditTools.prefs new file mode 100644 index 0000000000..a8ddcc62b8 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/.settings/de.loskutov.anyedit.AnyEditTools.prefs @@ -0,0 +1,16 @@ +activeContentFilterList=*.makefile,makefile,*.Makefile,Makefile,Makefile.*,*.mk,MANIFEST.MF,*.java +addNewLine=true +convertActionOnSaave=AnyEdit.CnvrtSpacesToTabs +eclipse.preferences.version=1 +ignoreBlankLinesWhenTrimming=false +inActiveContentFilterList= +javaTabWidthForJava=true +org.eclipse.jdt.ui.editor.tab.width=4 +projectPropsEnabled=false +removeTrailingSpaces=true +replaceAllSpaces=false +replaceAllTabs=false +saveAndAddLine=true +saveAndConvert=true +saveAndTrim=true +useModulo4Tabs=true diff --git a/org.eclipse.winery.topologymodeler/README.md b/org.eclipse.winery.topologymodeler/README.md new file mode 100644 index 0000000000..f455e420e0 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/README.md @@ -0,0 +1,44 @@ +# Winery Topoloy Modeler + +This is the topology modeler component of Winery. + +## Installation + +See [README.md of Winery](../README.md). + +## Implementation hints + +* use `div.NodeTemplateShape` as selector for node templates + +## About the Code + +This code is in a prototypcial status. These are the main issues: +* Instead of using EL, it directly uses Java code in the JSPs. +* Instead of including the libraries using AMD, they are directly included via `script` tags. +* Instead of using [AngularJS] (or a similar framework), we manually do the life update from the properties section to the node +* Saving generates the XML manually (in index.jsp:save()). Therefore the extensibility of TOSCA is not supported here. +* We depend on both bootstrap and jquery UI as jsPlumb does not support a bootstrap binding. + +### Trouble shooting +When the topology modeler does not fully load (i.e., a white background is still there), look at the TOMCAT log file (of the repository). +You'll see something like `TOSCA component id class org.eclipse.winery.common.ids.definitions.NodeTypeId / {http://www.example.org/tosca/nodetypes}VirtualMachine not found`. +This is in indicator that you manually edited a `.definitions` file and did not change the location in the repository. +The directory structure and the namespace and id/name settings in the `.definitions` file have to be in sync. +As quick solution, you can open the type, switch to the XML tab and press "Save". +Then, the namespace and id/name setting in the `.definitions` is changed according to the storage. + +## License +Copyright (c) 2012-2014 University of Stuttgart. + +All rights reserved. This program and the accompanying materials +are made available under the terms of the [Eclipse Public License v1.0] +and the [Apache License v2.0] which both accompany this distribution, +and are available at http://www.eclipse.org/legal/epl-v10.html +and http://www.apache.org/licenses/LICENSE-2.0 + +Contributors: +* Oliver Kopp - initial API and implementation + + [AngularJS]: http://angularjs.org/ + [Apache License v2.0]: http://www.apache.org/licenses/LICENSE-2.0.html + [Eclipse Public License v1.0]: http://www.eclipse.org/legal/epl-v10.html diff --git a/org.eclipse.winery.topologymodeler/about.html b/org.eclipse.winery.topologymodeler/about.html new file mode 100644 index 0000000000..5a8fe80e75 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about.html @@ -0,0 +1,604 @@ + + + + +About + + +

    About This Content

    + +

    January 24, 2014

    +

    License

    + +

    The Eclipse Foundation makes available all content in this plug-in (“Content”). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 (“EPL”) +and Apache License Version 2.0. +A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html +and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php. +You may elect to redistribute this code under either of these licenses. +For purposes of the EPL, “Program” will mean the Content. +

    + +

    +If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party (“Redistributor”) and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor’s license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL and Apache License 2.0 still apply to any source code +in the Content and such source code may be obtained at http://www.eclipse.org. +

    + +

    Third Party Content

    + +

    JavaScript libraries

    + +
    biltong – Version 0.1
    + + + + + + + + + + + + + +
    FilesThe library is completly included in jsPlumb as “jsPlumbGeom v0.1”
    URLhttps://github.com/jsplumb/biltong
    LicenseMIT. A copy of the license is contained in the file LICENSE-biltong.txt and is also available at github
    + +
    Bootstrap – Version 3.1.1
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/bootstrap
    URLhttp://getbootstrap.com/
    LicenseMIT. A copy of the license is contained in the file LICENSE-bootstrap.txt and is also available at github
    + +
    bootstrap-spinedit – Version 1.0.0
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/bootstrap-spinedit
    URLhttps://github.com/scyv/bootstrap-spinedit
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at github
    + +
    JavaScript Canvas to Blob – Version 2.1.0
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/blueimp-canvas-to-blob
    URLhttps://github.com/blueimp/JavaScript-Canvas-to-Blob
    LicenseMIT. The authors did not provide a separate variant of the MIT license. The generic MIT license is available at http://opensource.org/licenses/MIT
    + +
    JavaScript Load Image – Version 1.11.0
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/blueimp-load-image
    URLhttps://github.com/blueimp/JavaScript-Load-Image
    LicenseMIT. The authors did not provide a separate variant of the MIT license. The generic MIT license is available at http://opensource.org/licenses/MIT
    + +
    JavaScript Templates – Version 2.5.3
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/blueimp-tmpl
    URLhttps://github.com/blueimp/JavaScript-Templates
    LicenseMIT. The authors did not provide a separate variant of the MIT license. The generic MIT license is available at http://opensource.org/licenses/MIT
    + +
    jQuery – Version 2.0.3
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/jquery
    URLhttp://jquery.com/
    LicenseMIT. A copy of the license is contained in the file LICENSE-jQuery.txt and is also available at https://jquery.org/license/
    + +
    jQuery Typing – v0.3.2-2
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/jquery-typing
    URLhttps://github.com/tnajdek/jquery-typing
    LicensePublic domain. An explicit license is not provided, only a link to unlicense.org is provided.
    + +
    jQuery File Upload Plugin – Version 9.5.3
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/blueimp-file-upload
    URLhttps://github.com/blueimp/jQuery-File-Upload
    LicenseMIT. The authors did not provide a separate variant of the MIT license. The generic MIT license is available at http://opensource.org/licenses/MIT
    + +
    jQuery UI – Version 1.10.3
    +This library is required by jsPlumb only + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/jquery-ui
    URLhttp://jqueryui.com/
    LicenseMIT. A copy of the license is contained in the file LICENSE-jQuery-UI.txt and is also available at https://github.com/jquery/jquery-ui/blob/master/MIT-LICENSE.txt
    + +
    jsBezier – Version 0.6
    + + + + + + + + + + + + + +
    FilesThe library is completly included in jsPlumb
    URLhttps://github.com/jsplumb/jsBezier
    LicenseMIT. An explicit license is not provided, only an entry in the header of jsBezier-0.6.js.
    + + +
    jsPlumb – Version 1.5.4
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/jsPlumb
    URLhttp://jsplumb.org/
    LicenseAll 1.x.x versions of jsPlumb are dual-licensed under both MIT and GPLv2 (http://www.gnu.org/licenses/old-licenses/gpl-2.0). + The Eclipse Foundation elects to include this software in this distribution under the MIT license. + A copy of the license is contained in the file LICENSE-jsPlumb-MIT and is also available at github
    + +
    KeyboardJS – Version 0.4.2
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/KeyboardJS
    URLhttps://github.com/RobertWHurst/KeyboardJS/tree/v0.4.2
    LicenseBSD (2 clauses). A copy of the license is contained in the file LICENSE-KeyboardJS.txt and is also available at https://github.com/RobertWHurst/KeyboardJS/blob/v0.4.2/license.txt
    + +
    Orion – Version 4.0
    + + + + + + + + + + + + + +
    URLhttp://eclipse.org/orion/editor/releases/latest/built-editor.js
    URLhttp://www.eclipse.org/orion/
    LicenseEclipse Public License v1.0 and Eclipse Distribution License v1.0. + A copy of the licenses is contained in the files LICENSE-EPL.txt and EDL.txt. + A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the EDL is available at http://www.eclipse.org/org/documents/edl-v10.html.
    + +
    PNotify – Version 1.2.2-koppor-2
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/pnotify
    URLhttp://sciactive.com/pnotify/ and https://github.com/koppor/pnotify
    LicensePines Notify is distributed under the GPL (http://www.gnu.org/licenses/gpl.html), + LGPL (http://www.gnu.org/licenses/lgpl.html), and + MPL (http://www.mozilla.org/MPL/MPL-1.1.html). + The Eclipse Foundation elects to include this software in this distribution under the MPL license. + A copy of the license is contained in the file MPL-v1.1.txt.
    + +
    RequireJS – Version 2.1.5
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/requirejs
    URLhttp://requirejs.org/
    LicenseBSD and MIT (see https://github.com/jrburke/requirejs/blob/master/LICENSE). + The Eclipse Foundation elects to include this software in this distribution under the MIT license. + A copy of the license is contained in the file LICENSE-requirejs.txt.
    + +
    Select2 – Version 3.4.5
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/select2
    URLhttp://ivaynberg.github.io/select2/
    LicenseApache 2.0 (http://www.apache.org/licenses/LICENSE-2.0) and GPL2 (http://www.gnu.org/licenses/gpl-2.0.html). + The Eclipse Foundation elects to include this software in this distribution under the Apache 2.0 license. + A copy of the license is contained in the file Apache-LICENSE-2.0.txt.
    + +
    X-editable – Version 1.5.1
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/x-editable
    URLhttp://vitalets.github.io/x-editable/
    LicenseMIT. A copy of the license is contained in the file LICENSE-x-editable.txt and is also available at github
    + +
    XMLWriter – Version v1.0.2
    + + + + + + + + + + + + + +
    Filessrc/main/webapp/components/XMLWriter
    URLhttps://github.com/flesler/XMLWriter
    LicenseBSD. A copy of the license is contained in the file LICENSE-XMLWriter.txt and is also available at github
    + +

    Java Libraries

    + +
    Apache Commons Configuration – Version 1.9
    + + + + + + + + + +
    URLhttp://commons.apache.org/proper/commons-configuration/
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
    + +
    Apache Commons IO – Version 2.1
    + + + + + + + + + +
    URLhttp://commons.apache.org/proper/commons-io/
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
    + +
    Apache Commons Lang – Version 2.6
    + + + + + + + + + +
    URLhttp://commons.apache.org/proper/commons-lang/
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
    + +
    Apache Commons Lang3 – Version 3.1
    + + + + + + + + + +
    URLhttp://commons.apache.org/proper/commons-lang/
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
    + +
    jackson-annotations – Version 2.2.2
    + + + + + + + + + + + + + +
    URLhttps://github.com/FasterXML/jackson-annotations
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
    NoteThe license was explictily added in version 2.2.3 and 2.3.0. See Issue #14 and LICENSE in the source repository.
    + +
    jackson-core – Version 2.2.2
    + + + + + + + + + +
    URLhttps://github.com/FasterXML/jackson-core and http://wiki.fasterxml.com/JacksonHome
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
    + +
    jackson-databind – Version 2.2.2
    + + + + + + + + + +
    URLhttps://github.com/FasterXML/jackson-databind
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
    + +
    jackson-jaxrs-base – Version 2.2.2
    + + + + + + + + + +
    URLhttps://github.com/FasterXML/jackson-jaxrs-providers/tree/master/base
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
    + +
    jackson-jaxrs-json-provider – Version 2.2.2
    + + + + + + + + + +
    URLhttps://github.com/FasterXML/jackson-jaxrs-providers/tree/master/json
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
    + +
    jackson-module-jaxb-annotations – Version 2.3.0
    + + + + + + + + + +
    URLhttps://github.com/FasterXML/jackson-module-jaxb-annotations
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0. + The license is added via the oss-parent project.
    + +
    Jersey Client – Version 1.17
    + + + + + + + + + +
    URLjersey.java.net/
    LicenseCDDL and GPL with classpath exception (https://jersey.java.net/license.html). + The Eclipse Foundation elects to include this software in this distribution under the CDDL license. + A copy of the license is available at CDDL-v1.1.txt.
    + +
    Jersey Core – Version 1.17
    + + + + + + + + + +
    URLjersey.java.net/
    LicenseCDDL and GPL with classpath exception (https://jersey.java.net/license.html). + The Eclipse Foundation elects to include this software in this distribution under the CDDL license. + A copy of the license is available at CDDL-v1.1.txt.
    + +
    JSP Standard Tag Library – Version 1.2
    + + + + + + + + + +
    URLhttps://jstl.java.net/
    LicenseCDDL and GPL with classpath exception (https://jersey.java.net/license.html). + The Eclipse Foundation elects to include this software in this distribution under the CDDL license. + A copy of the license is available at CDDL-v1.1.txt.
    + +
    Logback Classic – Version 1.1.1
    + + + + + + + + + +
    URLhttp://logback.qos.ch/
    LicenseEPL/LGPL dual license. + EPL: http://www.eclipse.org/legal/epl-v10.html. + LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1. + A copy of the license is contained in the file LICENSE-logback.txt and is also available at http://logback.qos.ch/license.html. + The Eclipse Foundation elects to include this software in this distribution under the EPL license.
    + +
    Logback Core – Version 1.1.1
    + + + + + + + + + +
    URLhttp://logback.qos.ch/
    LicenseEPL/LGPL dual license. + EPL: http://www.eclipse.org/legal/epl-v10.html. + LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1. + A copy of the license is contained in the file LICENSE-logback.txt and is also available at http://logback.qos.ch/license.html. + The Eclipse Foundation elects to include this software in this distribution under the EPL license.
    + +
    SLF4J: slf4j-api – Version 1.7.6
    + + + + + + + + + +
    URLhttp://www.slf4j.org/
    LicenseMIT. A copy of the license is contained in the file LICENSE-slf4j-api.txt and is also available at http://www.slf4j.org/license.html
    + +
    SLF4J: jcl-over-slf4j – Version 1.7.6
    + + + + + + + + + +
    URLhttp://www.slf4j.org/legacy.html
    LicenseApache 2.0. A copy of the license is contained in the file Apache-LICENSE-2.0.txt and is also available at http://www.apache.org/licenses/LICENSE-2.0
    + +
    Winery: org.eclipse.winery.common – ${project.version}
    + + + + + + + + + +
    URLhttp://eclipse.org/winery/
    LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
    + +
    Winery: org.eclipse.winery.model.tosca – Version 0.1.20
    + + + + + + + + + +
    URLhttp://eclipse.org/winery/
    LicenseEPL/Apache 2.0. A copy of the licenses is contained in the files LICENSE-ASL.txt and LICENSE-EPL.txt. A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the Apache License Version 2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
    + + + \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/about_files/Apache-LICENSE-2.0.txt b/org.eclipse.winery.topologymodeler/about_files/Apache-LICENSE-2.0.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/Apache-LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/org.eclipse.winery.topologymodeler/about_files/CDDL-v1.1.txt b/org.eclipse.winery.topologymodeler/about_files/CDDL-v1.1.txt new file mode 100644 index 0000000000..7cc8719b3b --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/CDDL-v1.1.txt @@ -0,0 +1,129 @@ +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL - Version 1.1) +1. Definitions. + + 1.1. “Contributor” means each individual or entity that creates or contributes to the creation of Modifications. + + 1.2. “Contributor Version” means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor. + + 1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof. + + 1.4. “Executable” means the Covered Software in any form other than Source Code. + + 1.5. “Initial Developer” means the individual or entity that first makes Original Software available under this License. + + 1.6. “Larger Work” means a work which combines Covered Software or portions thereof with code not governed by the terms of this License. + + 1.7. “License” means this document. + + 1.8. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. + + 1.9. “Modifications” means the Source Code and Executable form of any of the following: + + A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications; + + B. Any new file that contains any part of the Original Software or previous Modification; or + + C. Any new file that is contributed or otherwise made available under the terms of this License. + + 1.10. “Original Software” means the Source Code and Executable form of computer software code that is originally released under this License. + + 1.11. “Patent Claims” means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. + + 1.12. “Source Code” means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code. + + 1.13. “You” (or “Your”) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, “You” includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: + + (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients’ rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient’s rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software. + +4. Versions of the License. + + 4.1. New Versions. + + Oracle is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License. + +5. DISCLAIMER OF WARRANTY. + +COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as “Participant”) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant. + + 6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. + + 6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY’S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. +8. U.S. GOVERNMENT END USERS. + +The Covered Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer software” (as that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software documentation” as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License. +9. MISCELLANEOUS. + +This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction’s conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys’ fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software. +10. RESPONSIBILITY FOR CLAIMS. + +As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) + +The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/about_files/LICENSE-KeyboardJS.txt b/org.eclipse.winery.topologymodeler/about_files/LICENSE-KeyboardJS.txt new file mode 100644 index 0000000000..e71620bb20 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/LICENSE-KeyboardJS.txt @@ -0,0 +1,25 @@ +Copyright 2011 Robert Hurst. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY ROBERT HURST ''AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ROBERT HURST OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of Robert Hurst. \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/about_files/LICENSE-XMLWriter.txt b/org.eclipse.winery.topologymodeler/about_files/LICENSE-XMLWriter.txt new file mode 100644 index 0000000000..2676da367e --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/LICENSE-XMLWriter.txt @@ -0,0 +1,27 @@ +Copyright (c) 2014, Ariel Flesler +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +* Neither the name of the organization nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/org.eclipse.winery.topologymodeler/about_files/LICENSE-biltong.txt b/org.eclipse.winery.topologymodeler/about_files/LICENSE-biltong.txt new file mode 100644 index 0000000000..11cb2154ed --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/LICENSE-biltong.txt @@ -0,0 +1,22 @@ +Copyright (c) 2013 Simon Porritt + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/about_files/LICENSE-boostrap.txt b/org.eclipse.winery.topologymodeler/about_files/LICENSE-boostrap.txt new file mode 100644 index 0000000000..8d94aa9ac9 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/LICENSE-boostrap.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2011-2014 Twitter, Inc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/org.eclipse.winery.topologymodeler/about_files/LICENSE-jQuery-UI.txt b/org.eclipse.winery.topologymodeler/about_files/LICENSE-jQuery-UI.txt new file mode 100644 index 0000000000..1c693e3d44 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/LICENSE-jQuery-UI.txt @@ -0,0 +1,26 @@ +Copyright 2013 jQuery Foundation and other contributors, +http://jqueryui.com/ + +This software consists of voluntary contributions made by many +individuals (AUTHORS.txt, http://jqueryui.com/about) For exact +contribution history, see the revision history and logs, available +at http://jquery-ui.googlecode.com/svn/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.topologymodeler/about_files/LICENSE-jQuery.txt b/org.eclipse.winery.topologymodeler/about_files/LICENSE-jQuery.txt new file mode 100644 index 0000000000..957f26d3e3 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/LICENSE-jQuery.txt @@ -0,0 +1,21 @@ +Copyright 2013 jQuery Foundation and other contributors +http://jquery.com/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.topologymodeler/about_files/LICENSE-jsPlumb-MIT.txt b/org.eclipse.winery.topologymodeler/about_files/LICENSE-jsPlumb-MIT.txt new file mode 100644 index 0000000000..b5bc6504fc --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/LICENSE-jsPlumb-MIT.txt @@ -0,0 +1,20 @@ +Copyright (c) 2013 Simon Porritt, http://jsplumb.org/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.topologymodeler/about_files/LICENSE-logback.txt b/org.eclipse.winery.topologymodeler/about_files/LICENSE-logback.txt new file mode 100644 index 0000000000..b4fe24e02a --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/LICENSE-logback.txt @@ -0,0 +1,15 @@ +Logback LICENSE +--------------- + +Logback: the reliable, generic, fast and flexible logging framework. +Copyright (C) 1999-2012, QOS.ch. All rights reserved. + +This program and the accompanying materials are dual-licensed under +either the terms of the Eclipse Public License v1.0 as published by +the Eclipse Foundation + + or (per the licensee's choosing) + +under the terms of the GNU Lesser General Public License version 2.1 +as published by the Free Software Foundation. + diff --git a/org.eclipse.winery.topologymodeler/about_files/LICENSE-requirejs.txt b/org.eclipse.winery.topologymodeler/about_files/LICENSE-requirejs.txt new file mode 100644 index 0000000000..de4ee2963f --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/LICENSE-requirejs.txt @@ -0,0 +1,58 @@ +RequireJS is released under two licenses: new BSD, and MIT. You may pick the +license that best suits your development needs. The text of both licenses are +provided below. + + +The "New" BSD License: +---------------------- + +Copyright (c) 2010-2013, The Dojo Foundation +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Dojo Foundation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + +MIT License +----------- + +Copyright (c) 2010-2013, The Dojo Foundation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/org.eclipse.winery.topologymodeler/about_files/LICENSE-slf4j-api.txt b/org.eclipse.winery.topologymodeler/about_files/LICENSE-slf4j-api.txt new file mode 100644 index 0000000000..37050c9568 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/LICENSE-slf4j-api.txt @@ -0,0 +1,21 @@ + Copyright (c) 2004-2013 QOS.ch + All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.topologymodeler/about_files/LICENSE-x-editable.txt b/org.eclipse.winery.topologymodeler/about_files/LICENSE-x-editable.txt new file mode 100644 index 0000000000..eeb9357e72 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/LICENSE-x-editable.txt @@ -0,0 +1,22 @@ +Copyright (c) 2012 Vitaliy Potapov + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/org.eclipse.winery.topologymodeler/about_files/MPL-v1.1.txt b/org.eclipse.winery.topologymodeler/about_files/MPL-v1.1.txt new file mode 100644 index 0000000000..a8cd934df1 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/about_files/MPL-v1.1.txt @@ -0,0 +1,470 @@ + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the MPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + diff --git a/org.eclipse.winery.topologymodeler/bower.json b/org.eclipse.winery.topologymodeler/bower.json new file mode 100644 index 0000000000..72162d806a --- /dev/null +++ b/org.eclipse.winery.topologymodeler/bower.json @@ -0,0 +1,45 @@ +{ + "name": "Winery topology modeler", + "version": "0.1.37-SNAPSHOT", + "author": "Oliver Kopp ", + "contributors": [ + { + "name": "Uwe Breitenbücher" + }, + { + "name": "Kálmán Képes" + }, + { + "name": "Yves Schubert" + } + ], + "licenses": [ + { + "type": "EPL", + "url": "http://www.eclipse.org/legal/epl-v10.html" + }, + { + "type": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + } + ], + "dependencies": { + "blueimp-file-upload": "9.5.3", + "blueimp-tmpl": "2.5.3", + "bootstrap": "3.1.1", + "bootstrap-spinedit": "https://github.com/scyv/bootstrap-spinedit.git#1.0.0", + "jquery": "2.0.3", + "jquery-typing": "https://github.com/tnajdek/jquery-typing.git#0.3.2-2", + "jquery-ui": "1.10.3", + "jsPlumb": "1.5.4", + "KeyboardJS": "git://github.com/RobertWHurst/KeyboardJS.git#v0.4.2", + "pnotify": "https://github.com/koppor/pnotify.git#1.2.2-koppor-2", + "requirejs": "2.1.5", + "select2": "https://github.com/ivaynberg/select2/archive/3.4.5.zip", + "x-editable": "1.5.1", + "XMLWriter": "1.0.2" + }, + "keywords": [ + "TOSCA" + ] +} diff --git a/org.eclipse.winery.topologymodeler/pom.xml b/org.eclipse.winery.topologymodeler/pom.xml new file mode 100644 index 0000000000..5de22a76be --- /dev/null +++ b/org.eclipse.winery.topologymodeler/pom.xml @@ -0,0 +1,193 @@ + + + + 4.0.0 + + org.eclipse.winery + winery + 0.1.37-SNAPSHOT + + org.eclipse.winery.topologymodeler + war + + UTF-8 + + + + org.eclipse.winery + org.eclipse.winery.repository.client + 0.1.31 + compile + + + commons-logging + commons-logging + + + + + org.apache.commons + commons-lang3 + 3.1 + compile + + + commons-logging + commons-logging + + + + + ch.qos.logback + logback-classic + 1.1.1 + compile + + + org.slf4j + jcl-over-slf4j + 1.7.6 + compile + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.4 + + + + ${basedir}/src/main/webapp/WEB-INF + true + WEB-INF + + tags/about.tag + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + + + + maven-antrun-plugin + 1.7 + + + + org.codehaus.groovy + groovy-all + 2.1.7 + + + + + + generate-sources + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + run + + + + + + winery-topologymodeler + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.maven.plugins + maven-antrun-plugin + [1.0.0,) + + run + + + + + + + + + + + + + + diff --git a/org.eclipse.winery.topologymodeler/sonar-project.js.properties b/org.eclipse.winery.topologymodeler/sonar-project.js.properties new file mode 100644 index 0000000000..253705e39d --- /dev/null +++ b/org.eclipse.winery.topologymodeler/sonar-project.js.properties @@ -0,0 +1,13 @@ +# required metadata +sonar.projectKey=org.eclipse.winery.topologymodeler-js +sonar.projectName=org.eclipse.winery.topologymodeler-js +sonar.projectVersion=0.1.2 + +# path to source directories (required) +sonar.sources=WebContent/ +sonar.exclusions=components/** + +# The value of the property must be the key of the language. +sonar.language=js + +sonar.sourceEncoding=UTF-8 diff --git a/org.eclipse.winery.topologymodeler/sonar-project.web.properties b/org.eclipse.winery.topologymodeler/sonar-project.web.properties new file mode 100644 index 0000000000..b15e63d6e4 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/sonar-project.web.properties @@ -0,0 +1,13 @@ +# required metadata +sonar.projectKey=org.eclipse.winery.topologymodeler-web +sonar.projectName=org.eclipse.winery.topologymodeler-web +sonar.projectVersion=0.1.2 + +# path to source directories (required) +sonar.sources=src/main/webapp/ +sonar.exclusions=components/** + +# The value of the property must be the key of the language. +sonar.language=web + +sonar.sourceEncoding=UTF-8 diff --git a/org.eclipse.winery.topologymodeler/src/main/java/org/eclipse/winery/topologymodeler/WineryUtil.java b/org.eclipse.winery.topologymodeler/src/main/java/org/eclipse/winery/topologymodeler/WineryUtil.java new file mode 100644 index 0000000000..2dc7e27222 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/java/org/eclipse/winery/topologymodeler/WineryUtil.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation + *******************************************************************************/ +package org.eclipse.winery.topologymodeler; + +import java.util.List; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; + +import org.eclipse.winery.common.interfaces.QNameWithName; + +public class WineryUtil { + + /** + * LocalName is the ID of the element, whereas Name is the speaking name + */ + public static class LocalNameNamePair implements Comparable { + + String localName; + String name; + + + public LocalNameNamePair(String localName, String name) { + this.localName = localName; + this.name = name; + } + + public String getLocalName() { + return this.localName; + } + + public String getName() { + return this.name; + } + + /** + * Ordering according to name + */ + @Override + public int compareTo(LocalNameNamePair otherPair) { + return this.name.compareTo(otherPair.name); + } + + @Override + public int hashCode() { + return this.localName.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof LocalNameNamePair) { + return this.localName.equals(((LocalNameNamePair) o).getLocalName()); + } else { + return false; + } + } + } + + + public static SortedMap> convertQNameWithNameListToNamespaceToLocalNameNamePairList(List list) { + if (list == null) { + throw new IllegalArgumentException("list may not be null"); + } + SortedMap> res = new TreeMap<>(); + for (QNameWithName qnameWithName : list) { + SortedSet localNameNamePairSet = res.get(qnameWithName.qname.getNamespaceURI()); + if (localNameNamePairSet == null) { + localNameNamePairSet = new TreeSet<>(); + res.put(qnameWithName.qname.getNamespaceURI(), localNameNamePairSet); + } + LocalNameNamePair pair = new LocalNameNamePair(qnameWithName.qname.getLocalPart(), qnameWithName.name); + localNameNamePairSet.add(pair); + } + return res; + } + +} diff --git a/org.eclipse.winery.topologymodeler/src/main/resources/.gitignore b/org.eclipse.winery.topologymodeler/src/main/resources/.gitignore new file mode 100644 index 0000000000..17ae84b127 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/resources/.gitignore @@ -0,0 +1 @@ +rebel.xml diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/common-functions.tld b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/common-functions.tld new file mode 100644 index 0000000000..ffe076ddc2 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/common-functions.tld @@ -0,0 +1,70 @@ + + + + + 1.0 + Winery_Common_Functions + http://www.eclipse.org/winery/functions + + + + winerysPropertiesDefinition + org.eclipse.winery.common.ModelUtilities + org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition getWinerysPropertiesDefinition(org.eclipse.winery.model.tosca.TEntityType) + + + + + convertQNameListToNamespaceToLocalNameList + org.eclipse.winery.common.Util + java.util.SortedMap convertQNameListToNamespaceToLocalNameList(java.util.List) + + + getType + org.eclipse.winery.common.Util + org.eclipse.winery.model.tosca.TEntityType getType(org.eclipse.winery.common.interfaces.IWineryRepository, javax.xml.namespace.QName, java.lang.Class) + + + makeCSSName + org.eclipse.winery.common.Util + java.lang.String makeCSSName(java.lang.String, java.lang.String) + + + XMLAsString + org.eclipse.winery.common.Util + java.lang.String getXMLAsString(java.lang.Class, java.lang.Object) + + + DOMElementAsString + org.eclipse.winery.common.Util + java.lang.String getXMLAsString(org.w3c.dom.Element) + + + qname2href + org.eclipse.winery.common.Util + java.lang.String qname2href(java.lang.String, java.lang.Class, javax.xml.namespace.QName) + + + + + escapeHtml4 + org.apache.commons.lang3.StringEscapeUtils + java.lang.String escapeHtml4(java.lang.String) + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/functions.tld b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/functions.tld new file mode 100644 index 0000000000..4157f96fc4 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/functions.tld @@ -0,0 +1,36 @@ + + + + + 1.0 + Winery_TopologyModeler_Functions + http://www.eclipse.org/winery/topologymodeler/functions + + + convertQNameWithNameListToNamespaceToLocalNameNamePairList + org.eclipse.winery.topologymodeler.WineryUtil + java.util.SortedMap convertQNameWithNameListToNamespaceToLocalNameNamePairList(java.util.List) + + + + escapeHtml4 + org.apache.commons.lang3.StringEscapeUtils + java.lang.String escapeHtml4(java.lang.String) + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/about.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/about.tag new file mode 100644 index 0000000000..7cb73b23ba --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/about.tag @@ -0,0 +1,58 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> + +<%@tag description="About for the repository" pageEncoding="UTF-8"%> + + + + \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/QNameChooser.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/QNameChooser.tag new file mode 100644 index 0000000000..d37c722b5d --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/QNameChooser.tag @@ -0,0 +1,50 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Dialog parts for choosing a QName" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions"%> + +<%@attribute name="allQNames" required="true" type="java.util.Collection" description="Collection<QName> of all available QNames" %> +<%@attribute name="includeNONE" required="false" type="java.lang.Boolean" description="Should (none) be included as option?"%> +<%@attribute name="selected" required="false" description="The initial value to select"%> +<%@attribute name="labelOfSelectField" required="true"%> +<%@attribute name="idOfSelectField" required="true"%> + +
    + + +
    + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/artifactcreationdialog.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/artifactcreationdialog.tag new file mode 100644 index 0000000000..5e49b0427f --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/artifactcreationdialog.tag @@ -0,0 +1,443 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Dialog for adding an implementation / deployment artifact" pageEncoding="UTF-8"%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="fup" tagdir="/WEB-INF/tags/common"%> + +<%@attribute name="name" required="true" description="Implementation | Deployment"%> +<%@attribute name="repositoryURL" required="true" description="the URL of Winery's repository"%> +<%@attribute name="onSuccessfulArtifactCreationFunction" required="true" description="javascript code to be executed when the artifact has been successfully created. Parameter: artifactInfo"%> +<%@attribute name="allArtifactTypes" required="true" type="java.util.Collection" description="All available artifact types"%> +<%@attribute name="allNamespaces" required="true" type="java.util.Collection" description="All known namespaces"%> +<%@attribute name="defaultNSForArtifactTemplate" required="true" description="the default namespace of the artifact template"%> + +<%-- either URL or a function to be called for addition --%> +<%@attribute name="URL" required="true" description="the URL of the artifact collection. May also be a function returning the correct URL (used at the topology modeler). I.e., it is an expression being evaluated"%> + +<%@attribute name="isDeploymentArtifact" required="true" type="java.lang.Boolean" description="Is this dialog used to create deployment artifacts?"%> +<%-- required if implementation artifact --%> +<%@attribute name="interfacesOfAssociatedType" type="java.util.List" %> + + + + + + + + + + + + + + +<%-- file uploading part --%> + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/artifacttemplateselection.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/artifacttemplateselection.tag new file mode 100644 index 0000000000..05c6138fa9 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/artifacttemplateselection.tag @@ -0,0 +1,41 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="dialog for selecting one artifacttemplate" pageEncoding="UTF-8"%> + +<%@attribute name="allNamespaces" required="true" type="java.util.Collection" description="All known namespaces"%> +<%@attribute name="repositoryURL" required="true" description="the URL of Winery's repository"%> +<%@attribute name="defaultNSForArtifactTemplate" required="true" description="the default namespace of the artifact template"%> + +<%@taglib prefix="t" tagdir="/WEB-INF/tags"%> + +
    + +
    + + + +
    + +
    +
    + + +
    + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/id_name_type.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/id_name_type.tag new file mode 100644 index 0000000000..b88a9a9994 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/id_name_type.tag @@ -0,0 +1,36 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Dialog parts for name and type choosing" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions"%> +<%@taglib prefix="w" tagdir="/WEB-INF/tags/common"%> + + +<%@attribute name="allTypes" required="true" type="java.util.Collection" description="Collection<QName> of all available types" %> +<%@attribute name="idPrefix" required="true" description="prefix used for name and type field. E.g., 'Req' becomes 'ReqType'."%> +<%@attribute name="hideIdField" required="false" description="if given, id field is not displayed. Quick hack to have this dialog reusable. Future versions might always show the id dialog and provide sync between name and id"%> + + +
    + + +
    +
    +
    + + +
    + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/orioneditor/orioneditorarea.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/orioneditor/orioneditorarea.tag new file mode 100644 index 0000000000..6aeb95fca6 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/orioneditor/orioneditorarea.tag @@ -0,0 +1,110 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Wrapper for an orion editing area" pageEncoding="UTF-8"%> + +<%@attribute name="areaid" required="true" description="The id of the editing area."%> +<%@attribute name="withoutsavebutton" required="false"%> +<%@attribute name="initialtext" required="false" description="The value to put in the editor. Can be also passed as body of this tag"%> +<%@attribute name="url" required="false"%> +<%@attribute name="hidden" required="false" description="if not empty, the form is hidden"%> +<%@attribute name="method" required="false" description="the method to use. Defaults to PUT"%> + +<%-- QUICK HACK to change the method from POST to PUT after saving an empty documentation the first time --%> +<%@attribute name="reloadAfterSuccess" required="false" description="Trigger a page reload after success (if true)"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions" %> + +
    +
    style="display: none;">
    ${wc:escapeHtml4(initialtext)}
    + + + +
    + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/policies/policies.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/policies/policies.tag new file mode 100644 index 0000000000..5bd7bd91dc --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/policies/policies.tag @@ -0,0 +1,54 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> + +<%-- This is mostly inspired by the reqscaps handling. Future work: Generalize the dialogs somehow to avoid copy'n'paste of code --%> + +<%@tag import="org.apache.taglibs.standard.lang.jstl.test.PageContextImpl"%> +<%@tag description="Renders the list of policies of a node template" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions"%> + +<%@attribute name="list" required="true" type="java.util.List"%> +<%@attribute name="repositoryURL" required="true" type="java.lang.String" %> + +
    +
    Policies
    +
    +
    +
    Name
    +
    Type
    +
    Template
    +
    + <%-- this HTML has to be kept consistent with the tmpl-policy HTML at policydiag.tag --%> +
    +
    ${item.name}
    + + +
    ${wc:qname2href(repositoryURL, clazz, item.policyType)}
    + ${item.policyType} + + +
    ${wc:qname2href(repositoryURL, clazz, item.policyRef)}
    + ${item.policyRef} + + + +
    +
    + +
    +
    diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/policies/policydiag.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/policies/policydiag.tag new file mode 100644 index 0000000000..2554b8c16d --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/policies/policydiag.tag @@ -0,0 +1,205 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> + +<%@tag import="org.eclipse.winery.model.tosca.TPolicyTemplate"%> +<%@tag description="Dialog to add or update a policy. Offers function showUpdateDiagForPolicy(policyElement) / showAddDiagForPolicy(nodeTemplateElement)" pageEncoding="UTF-8"%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +<%@taglib prefix="o" tagdir="/WEB-INF/tags/common/orioneditor"%> +<%@taglib prefix="w" tagdir="/WEB-INF/tags"%> +<%@taglib prefix="ct" tagdir="/WEB-INF/tags/common"%> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions"%> + +<%@attribute name="allPolicyTypes" required="true" type="java.util.Collection" description="Collection<QName> of all available policy types" %> +<%@attribute name="repositoryURL" required="true" type="java.lang.String" description="The URL of winery's repository"%> + + + + + + + + +<%-- parameters: o.id, o.name, o.policyType, o.policyRef, o.xml. Has to be consistent with the HTML generated by policies.tag --%> + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/spinnerwithinphty.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/spinnerwithinphty.tag new file mode 100644 index 0000000000..a77c9d9eb3 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/spinnerwithinphty.tag @@ -0,0 +1,92 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Yves Schubert - initial API and implementation and/or initial documentation + * Oliver Kopp - minor improvements + *******************************************************************************/ +--%> +<%@tag description="A spinner with the possibility to set to inphty via button" pageEncoding="UTF-8"%> +<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + +<%-- Code copied between repository and topology-modeler --%> + +<%-- +Could also be realized as + * HTML5 Web Component (http://www.ibm.com/developerworks/library/wa-html5components1/) or + * x-tags (http://www.x-tags.org/) +We decided to use JSP tags to avoid an additional JavaScript library +--%> + +<%@attribute name="label" required="true"%> +<%@attribute name="id" required="true"%> +<%@attribute name="min"%> +<%@attribute name="max" required="false" description="Maximum value. Default is 1000. The underlying library does not allow arbitrary high values."%> +<%@attribute name="name" required="false" description="The name of the input field. Defaults to the id"%> +<%@attribute name="withinphty" required="false" description="If set, then an inphty button is provded"%> +<%@attribute name="value"%> +<%@attribute name="width" required="false" description="The Column with according to bootstrap rules. Default is 3 (should not be smaller)."%> +<%@attribute name="changedfunction" required="false" description="Called if value changed"%> + +<%-- Set default name value if required --%> + + + + + + + + +
    + +
    +
    +
    + onblur="${changedfunction}();"/> + + , ${changedfunction});">∞ + +
    +
    +
    +
    + + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/CSSForTypes.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/CSSForTypes.tag new file mode 100644 index 0000000000..1df2d82b5b --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/CSSForTypes.tag @@ -0,0 +1,50 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Generates style element for node types and relationship types" pageEncoding="UTF-8" %> + +<%@attribute name="nodeTypes" required="true" type="java.util.Collection" %> +<%@attribute name="relationshipTypes" required="true" type="java.util.Collection" %> + +<%@tag import="java.util.Collection"%> +<%@tag import="javax.xml.namespace.QName"%> +<%@tag import="org.eclipse.winery.common.ModelUtilities"%> +<%@tag import="org.eclipse.winery.common.Util"%> +<%@tag import="org.eclipse.winery.model.tosca.TNodeType"%> +<%@tag import="org.eclipse.winery.model.tosca.TRelationshipType"%> + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/defineCreateConnectorEndpointsFunction.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/defineCreateConnectorEndpointsFunction.tag new file mode 100644 index 0000000000..26f139a056 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/defineCreateConnectorEndpointsFunction.tag @@ -0,0 +1,42 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Defines the javascript function createConnectorEndpoints globally. Quick hack to avoid huge hacking at the repository" pageEncoding="UTF-8"%> + +<%@tag import="java.util.Collection"%> +<%@tag import="org.eclipse.winery.model.tosca.TRelationshipType"%> +<%@tag import="org.eclipse.winery.common.Util"%> + +<%@attribute name="relationshipTypes" type="java.util.Collection" required="true" %> + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/nodeTemplateRenderer.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/nodeTemplateRenderer.tag new file mode 100644 index 0000000000..f4587fc65c --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/nodeTemplateRenderer.tag @@ -0,0 +1,266 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - skeletton for node template shapes + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag language="java" pageEncoding="UTF-8" description="This tag is used for both real nodeTemplate node rendering and rendering of a 'template' used to create a nodeTemplateShape. The latter is called by palette.jsp. Therefore, this tag has to be more general."%> +<%-- Parameters --%> + +<%-- template and palette --%> +<%@attribute name="client" required="true" description="IWineryRepository" type="org.eclipse.winery.common.interfaces.IWineryRepository"%> +<%@attribute name="repositoryURL" required="true" type="java.lang.String" description="The URL of winery's repository"%> +<%@attribute name="topologyModelerURI" required="false" type="java.lang.String" description="The URL of winery topology modeler's URI - required for images/. Has to end with '/'. Can be left blank."%> +<%@attribute name="relationshipTypes" description="the known relationship types" required="true" type="java.util.Collection"%> + +<%-- only for topology modeler --%> +<%@attribute name="nodeTemplate" type="org.eclipse.winery.model.tosca.TNodeTemplate"%> +<%@attribute name="top"%> +<%@attribute name="left"%> + +<%-- only for palette.jsp --%> +<%@attribute name="nodeType" type="org.eclipse.winery.model.tosca.TNodeType" %> +<%@attribute name="nodeTypeQName" type="javax.xml.namespace.QName"%> + +<%@tag import="org.eclipse.winery.model.tosca.TArtifactTemplate"%> +<%@tag import="org.eclipse.winery.model.tosca.TArtifactType"%> +<%@tag import="org.eclipse.winery.model.tosca.TCapability"%> +<%@tag import="org.eclipse.winery.model.tosca.TDeploymentArtifact"%> +<%@tag import="org.eclipse.winery.model.tosca.TDeploymentArtifacts"%> +<%@tag import="org.eclipse.winery.model.tosca.TEntityType.PropertiesDefinition"%> +<%@tag import="org.eclipse.winery.model.tosca.TNodeTemplate"%> +<%@tag import="org.eclipse.winery.model.tosca.TNodeTemplate.Capabilities"%> +<%@tag import="org.eclipse.winery.model.tosca.TNodeTemplate.Requirements"%> +<%@tag import="org.eclipse.winery.model.tosca.TNodeTemplate.Policies"%> +<%@tag import="org.eclipse.winery.model.tosca.TNodeType"%> +<%@tag import="org.eclipse.winery.model.tosca.TPolicy"%> +<%@tag import="org.eclipse.winery.model.tosca.TRelationshipType"%> +<%@tag import="org.eclipse.winery.model.tosca.TRequirement"%> +<%@tag import="org.eclipse.winery.common.ModelUtilities"%> +<%@tag import="org.eclipse.winery.common.Util"%> +<%@tag import="org.eclipse.winery.common.ids.definitions.ArtifactTemplateId"%> +<%@tag import="org.eclipse.winery.common.ids.definitions.ArtifactTypeId"%> +<%@tag import="org.eclipse.winery.common.interfaces.IWineryRepository"%> +<%@tag import="org.w3c.dom.Element" %> +<%@tag import="org.apache.commons.configuration.Configuration"%> +<%@tag import="org.apache.commons.lang3.StringUtils"%> +<%@tag import="org.apache.commons.lang3.StringEscapeUtils"%> +<%@tag import="java.io.StringWriter" %> +<%@tag import="java.util.Collections"%> +<%@tag import="java.util.Collection"%> +<%@tag import="java.util.Iterator"%> +<%@tag import="java.util.List"%> +<%@tag import="java.util.Map"%> +<%@tag import="java.util.UUID"%> +<%@tag import="javax.xml.namespace.QName"%> +<%@tag import="javax.xml.transform.OutputKeys"%> +<%@tag import="javax.xml.transform.Transformer"%> +<%@tag import="javax.xml.transform.TransformerFactory"%> +<%@tag import="javax.xml.transform.dom.DOMSource"%> +<%@tag import="javax.xml.transform.stream.StreamResult"%> + +<%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates" %> +<%@taglib prefix="ntrq" tagdir="/WEB-INF/tags/common/templates/nodetemplates/reqscaps" %> +<%@taglib prefix="pol" tagdir="/WEB-INF/tags/common/policies" %> +<%@taglib prefix="props" tagdir="/WEB-INF/tags/common/templates" %> + +<% + String visualElementId; + + boolean paletteMode; + if (nodeTemplate == null) { + // we are in palette mode + // --> we render a template to be inserted in the drawing area by drag'n'drop + paletteMode = true; + assert(nodeType != null); + assert(nodeTypeQName != null); + + // these values are only pseudo values, they get all overwritten in drop function of palette.jsp + visualElementId = UUID.randomUUID().toString(); + left = "0"; + top = "0"; + } else { + // we render a real node template + paletteMode = false; + nodeTypeQName = nodeTemplate.getType(); + nodeType = client.getType(nodeTypeQName, TNodeType.class); + if (nodeType == null) { +%> + +<% + return; + } + + visualElementId = nodeTemplate.getId(); + } + + String nodeTypeCSSName = Util.makeCSSName(nodeTypeQName); +%> + +
    +
    + + <% + String name; + if (paletteMode) { + name = ""; // will be changed on drop + } else { + name = nodeTemplate.getName(); + if (StringUtils.isEmpty(name)) { + name = visualElementId; + } + } + %> +
    + <% + if (!paletteMode) { + %><%=Util.renderMinInstances(nodeTemplate.getMinInstances())%><% + } + %> + <% + if (!paletteMode) { + %><%=Util.renderMaxInstances(nodeTemplate.getMaxInstances())%><% + } + %> +
    +
    <%=visualElementId%>
    +
    <%=name%>
    +
    <%=(nodeType.getName() == null)?nodeTypeQName.getLocalPart():nodeType.getName()%>
    + + +
    +
    + <% + for (TRelationshipType relationshipType: (Collection) relationshipTypes) { + %> +
    +
    +
    <%=relationshipType.getName()%>
    +
    + <% + } + %> +
    + + <%-- Properties --%> + + + <%-- Deployment Artifacts --%> + + <% + List deploymentArtifacts; + if (paletteMode) { + deploymentArtifacts = Collections.emptyList(); + } else { + TDeploymentArtifacts tDeploymentArtifacts = nodeTemplate.getDeploymentArtifacts(); + if (tDeploymentArtifacts == null) { + deploymentArtifacts = Collections.emptyList(); + } else { + deploymentArtifacts = tDeploymentArtifacts.getDeploymentArtifact(); + } + } + // Render even if (deploymentArtifacts.isEmpty()), because user could add some with drag'n'drop + + // following is required to render artifact specific content + TransformerFactory transFactory = TransformerFactory.newInstance(); + Transformer transformer = transFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + %> + +
    + +
    Deployment Artifacts
    +
    + <% + if (!paletteMode) { + for (TDeploymentArtifact deploymentArtifact : deploymentArtifacts) { + %> +
    + +
    <%=deploymentArtifact.getName()%>
    +
    <% + QName artifactRef; + if ((artifactRef = deploymentArtifact.getArtifactRef()) != null) { + ArtifactTemplateId atId = new ArtifactTemplateId(artifactRef); + %><%=client.getName(atId)%><% + } + %>
    +
    <% + ArtifactTypeId atyId = new ArtifactTypeId(deploymentArtifact.getArtifactType()); + %><%=client.getName(atyId)%>
    +
    + <% + } + } + %> + +
    + +
    + +
    +
    Drop to add new deployment artifact. Not yet implemented.
    +
    +
    +
    + + <%-- Requirements and Capabilities --%> + <% + List reqList; + if (paletteMode) { + reqList = null; + } else { + Requirements reqs = nodeTemplate.getRequirements(); + if (reqs == null) { + reqList = null; + } else { + reqList = reqs.getRequirement(); + } + } + %> + + + <% + List capList; + if (paletteMode) { + capList = null; + } else { + Capabilities caps = nodeTemplate.getCapabilities(); + if (caps == null) { + capList = null; + } else { + capList = caps.getCapability(); + } + } + %> + + + <%-- Policies --%> + <% + List policyList; + if (paletteMode) { + policyList = null; + } else { + Policies policies = nodeTemplate.getPolicies(); + if (policies == null) { + policyList = null; + } else { + policyList = policies.getPolicy(); + } + } + %> + +
    diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/caps.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/caps.tag new file mode 100644 index 0000000000..af70ff639e --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/caps.tag @@ -0,0 +1,33 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Renders the list of requirements or capabilties" pageEncoding="UTF-8"%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates/reqscaps" %> + +<%@attribute name="client" required="true" description="IWineryRepository" type="org.eclipse.winery.common.interfaces.IWineryRepository"%> +<%@attribute name="list" required="false" type="java.util.List"%> +<%@attribute name="repositoryURL" required="true" %> +<%@attribute name="pathToImages" required="true" description="The path (URI path) to the image/ url, where xml.png is available. Has to end with '/'"%> + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/reqs.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/reqs.tag new file mode 100644 index 0000000000..473443e2e4 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/reqs.tag @@ -0,0 +1,33 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Renders the list of requirements or capabilties" pageEncoding="UTF-8"%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates/reqscaps" %> + +<%@attribute name="client" required="true" description="IWineryRepository" type="org.eclipse.winery.common.interfaces.IWineryRepository"%> +<%@attribute name="list" required="false" type="java.util.List"%> +<%@attribute name="repositoryURL" required="true" %> +<%@attribute name="pathToImages" required="true" description="The path (URI path) to the image/ url, where xml.png is available. Has to end with '/'"%> + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/reqsorcaps.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/reqsorcaps.tag new file mode 100644 index 0000000000..60467302fe --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/nodetemplates/reqscaps/reqsorcaps.tag @@ -0,0 +1,63 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Renders the list of requirements or capabilties" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions"%> +<%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates/reqscaps" %> +<%@taglib prefix="props" tagdir="/WEB-INF/tags/common/templates" %> + +<%@attribute name="list" required="false" type="java.util.List" %> +<%@attribute name="headerLabel" required="true" description="Used for the heading" %> +<%@attribute name="cssClassPrefix" required="true" %> +<%@attribute name="TReqOrCapTypeClass" required="true" type="java.lang.Class" %> +<%@attribute name="repositoryURL" required="true" %> +<%@attribute name="typeURLFragment" required="true" description="requirementtypes|capabilitytypes"%> +<%@attribute name="shortName" required="true" description="Used for diag id, function name suffix, Req|Cap"%> +<%@attribute name="client" required="true" description="IWineryRepository" type="org.eclipse.winery.common.interfaces.IWineryRepository"%> +<%@attribute name="pathToImages" required="true" description="The path (URI path) to the image/ url, where xml.png is available. Has to end with '/'"%> + +<%@tag import="org.eclipse.winery.common.ModelUtilities"%> + +
    +
    ${headerLabel}
    +
    + +
    +
    ${item.id}
    +
    ${item.name}
    +
    ${wc:qname2href(repositoryURL, TReqOrCapTypeClass, item.type)}
    + + +
    +
    + +
    +
    + +<%-- parameters: o.id, o.name, o.type, o.xml. Has to be consistent with above HTML --%> + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/properties.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/properties.tag new file mode 100644 index 0000000000..afbae66c1f --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/properties.tag @@ -0,0 +1,103 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Rendering for properties. A separate CSS has to be provided to style the content. Thus, this tag is reusable both in the topology modeler and in the management UI. Requires global javaScript function editPropertiesXML(visualElementId)" pageEncoding="UTF-8"%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> + +<%@attribute name="propertiesDefinition" required="true" type="org.eclipse.winery.model.tosca.TEntityType.PropertiesDefinition" description="The TOSCA-conforming properties definition"%> +<%@attribute name="wpd" required="true" type="org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition" description="Winery's K/V properties definition"%> +<%@attribute name="template" required="true" type="org.eclipse.winery.model.tosca.TEntityTemplate" description="The template to display properties. Has to be null in case of the palette mode of the topology modeler"%> +<%@attribute name="pathToImages" required="true" description="The path (URI path) to the image/ url, where xml.png is available. Has to end with '/'"%> + +<%@tag import="org.eclipse.winery.common.ModelUtilities"%> +<%@tag import="org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition"%> +<%@tag import="org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKV"%> +<%@tag import="org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKVList"%> + +<% +if ((propertiesDefinition != null) || (wpd != null)) { +// properties exist +%> +
    +
    Properties
    +
    + <% + if (wpd == null) { + // no winery's special properties definition, but "normal" TOSCA properties definition + + if (propertiesDefinition.getType() != null) { + %> + XSD Type: <%=propertiesDefinition.getType()%> + <% + } else { + %> + XSD Element: <%=propertiesDefinition.getElement()%> + <% + } + %> + + <%-- We have to do use $(this).parent().parent().parent().attr('id') instead of <%=visualElementId%> as on drag'n'drop from the palette, this binding is NOT changed, but the Id changes --> the user does NOT want to edit the properties from the palette entry, but from the node template --%> + + <% + } else { + // Winery special mode + java.util.Properties props; + if (template == null) { + // setting null only because of dump compiler. + // We never read props if in paletteMode + props = null; + } else { + props = ModelUtilities.getPropertiesKV(template); + } + %> + <%-- stores wrapper element name and namespace to ease serialization--%> + <%=wpd.getElementName()%> + <%=wpd.getNamespace()%> + + <% + PropertyDefinitionKVList list = wpd.getPropertyDefinitionKVList(); + if (list != null) { + // iterate on all defined properties + for (PropertyDefinitionKV propdef: list) { + String key = propdef.getKey(); + String value; + if (template == null) { + value = ""; + } else { + // assign value, but change "null" to "" if no property is defined + if ((value = props.getProperty(key)) == null) { + value = ""; + } + } + %> + + + + + <% + } + } + %> +
    <%= key %><%=value %>
    + <% + } + %> +
    +
    +<% +} +%> diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/propertiesBasic.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/propertiesBasic.tag new file mode 100644 index 0000000000..cdc176c11f --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/propertiesBasic.tag @@ -0,0 +1,110 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Has to be included once before ussage of properties.tag. Used in topology modeler and in properties.jsp of entitytemplates" pageEncoding="UTF-8"%> + +<%@tag import="org.eclipse.winery.common.constants.Namespaces" %> + +<%@taglib prefix="o" tagdir="/WEB-INF/tags/common/orioneditor"%> + + + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/registerConnectionTypesAndConnectNodeTemplates.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/registerConnectionTypesAndConnectNodeTemplates.tag new file mode 100644 index 0000000000..5f9d66542f --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/registerConnectionTypesAndConnectNodeTemplates.tag @@ -0,0 +1,204 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Registers the connection types to jsPlumb" pageEncoding="UTF-8"%> + +<%@attribute name="relationshipTypes" description="the known relationship types" required="true" type="java.util.Collection"%> +<%@attribute name="relationshipTemplates" description="the relationship templates to render" required="true" type="java.util.Collection"%> +<%@attribute name="ondone" description="JavaScript code executed when everything has been done" required="false"%> +<%@attribute name="repositoryURL" required="true" %> +<%@attribute name="readOnly" required="false" type="java.lang.Boolean"%> + +<%@tag import="java.util.Collection"%> +<%@tag import="org.eclipse.winery.model.tosca.TRequirement"%> +<%@tag import="org.eclipse.winery.model.tosca.TCapability"%> +<%@tag import="org.eclipse.winery.model.tosca.TNodeTemplate"%> +<%@tag import="org.eclipse.winery.model.tosca.TRelationshipType"%> +<%@tag import="org.eclipse.winery.model.tosca.TRelationshipTemplate"%> +<%@tag import="org.eclipse.winery.model.tosca.TRelationshipTemplate.SourceElement"%> +<%@tag import="org.eclipse.winery.model.tosca.TRelationshipTemplate.TargetElement"%> +<%@tag import="org.eclipse.winery.common.Util"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> + +<% +Collection relationshipTypesCasted = (Collection) relationshipTypes; +Collection relationshipTemplatesCasted = (Collection) relationshipTemplates; +%> + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/toggleButtons.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/toggleButtons.tag new file mode 100644 index 0000000000..05ed289140 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/common/templates/toggleButtons.tag @@ -0,0 +1,131 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Toggle buttons for visual appearance" pageEncoding="UTF-8"%> + + +
    + + + + + + +
    + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/idInput.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/idInput.tag new file mode 100644 index 0000000000..86dae1cbe9 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/idInput.tag @@ -0,0 +1,43 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="input field for an id unique in the target namespace. Current implementation: Unique in the topology modeler" pageEncoding="UTF-8"%> + +<%@attribute name="inputFieldId" required="true" description="The name and id of the input field"%> + +
    + + +
    + + \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/namespaceChooser.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/namespaceChooser.tag new file mode 100644 index 0000000000..25a19e3a6c --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/namespaceChooser.tag @@ -0,0 +1,52 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="places a bootstrap form control to chooose a namespace. A new namespace can be created" pageEncoding="UTF-8"%> + + + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +<%@attribute name="allNamespaces" required="true" type="java.util.Collection" description="All known namespaces as strings (because the topology modeler currently doesn't provide that as list of winery namespace objects)"%> +<%@attribute name="idOfInput" required="true" description="The id if the input field storing the namespace. Also used as name"%> +<%@attribute name="nameOfInput" required="false" description="The name if the input field storing the namespace. If not provided, ifOfInput is used"%> +<%@attribute name="selected" description="The currently selected namespace (optional)"%> + + + + +
    + + +
    + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/palette.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/palette.tag new file mode 100644 index 0000000000..4697ac3271 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/palette.tag @@ -0,0 +1,207 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - initial API and implementation and/or initial documentation + * Oliver Kopp - improvements + *******************************************************************************/ +--%> +<%@tag language="java" pageEncoding="UTF-8" description="Renders the palette on the left"%> + +<%@attribute name="repositoryURL" required="true" type="java.lang.String"%> +<%@attribute name="client" required="true" description="IWineryRepository" type="org.eclipse.winery.common.interfaces.IWineryRepository"%> +<%@attribute name="relationshipTypes" description="the known relationship types" required="true" type="java.util.Collection"%> + +<%@tag import="javax.xml.namespace.QName" %> +<%@tag import="java.util.Collection"%> +<%@tag import="java.util.UUID"%> +<%@tag import="java.util.List"%> +<%@tag import="org.eclipse.winery.common.interfaces.IWineryRepository" %> +<%@tag import="org.eclipse.winery.model.tosca.TNodeType"%> +<%@tag import="org.eclipse.winery.common.Util" %> + +<%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates" %> + + + +
    + +
    +Palette +
    + +<% + Collection allNodeTypes = client.getAllTypes(TNodeType.class); + if (allNodeTypes.isEmpty()) { +%> + + <% + } + for (TNodeType nodeType: allNodeTypes) { + if (nodeType.getName() == null) { + System.err.println("Invalid nodetype in ns " + nodeType.getTargetNamespace()); + continue; + } +%> +
    +
    + +
    +
    +
    +
    + <%= nodeType.getName() %> +
    +
    +
    + + +
    + +<% + } +%> + +
    + + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/propertiesOfOneNodeTemplate.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/propertiesOfOneNodeTemplate.tag new file mode 100644 index 0000000000..238e34aebf --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/propertiesOfOneNodeTemplate.tag @@ -0,0 +1,147 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - initial API and implementation and/or initial documentation + * Oliver Kopp - improvements to fit updated index.jsp + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> + +<%@tag language="java" pageEncoding="UTF-8" description="Renders the properies of one node tempate on the right"%> + +<%@attribute name="repositoryURL" required="true" type="java.lang.String" description="The repository URL"%> + +<%@taglib prefix="ct" tagdir="/WEB-INF/tags/common" %> + + + + + + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/reqscaps/addorupdatereqorcap.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/reqscaps/addorupdatereqorcap.tag new file mode 100644 index 0000000000..0ec6f5d2f0 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/nodetemplates/reqscaps/addorupdatereqorcap.tag @@ -0,0 +1,248 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag description="Dialog to change a req or cap. Offers function showEditDiagFor${shortName}(id)" pageEncoding="UTF-8"%> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates" %> +<%@taglib prefix="o" tagdir="/WEB-INF/tags/common/orioneditor"%> +<%@taglib prefix="w" tagdir="/WEB-INF/tags"%> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions"%> + +<%@attribute name="headerLabel" required="true"%> +<%@attribute name="shortName" required="true" description="Used for diag id, function name suffix, Req|Cap"%> +<%@attribute name="requirementOrCapability" required="true" description="requirement|capability"%> +<%@attribute name="cssClassPrefix" required="true"%> +<%@attribute name="allTypes" required="true" type="java.util.Collection" description="Collection<QName> of all available types" %> +<%@attribute name="clazz" required="true" type="java.lang.Class" description="TRequirement.class or TCapability.class" %> +<%@attribute name="repositoryURL" required="true" %> + + + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/relationshiptemplates/propertiesOfOneRelationshipTemplate.tag b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/relationshiptemplates/propertiesOfOneRelationshipTemplate.tag new file mode 100644 index 0000000000..8c63dcac81 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/tags/templates/relationshiptemplates/propertiesOfOneRelationshipTemplate.tag @@ -0,0 +1,179 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +--%> +<%@tag language="java" pageEncoding="UTF-8" description="Renders the properies of one relationship tempate on the right"%> + +<%@attribute name="relationshipTypes" required="true" type="java.util.Collection" %> +<%@attribute name="repositoryURL" required="true" type="java.lang.String" description="The repository URL"%> + + + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="props" tagdir="/WEB-INF/tags/common/templates" %> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions" %> + + + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/web.xml b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..37b6dc93e4 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,21 @@ + + + + Winery Topology Modeler + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/css/palette.css b/org.eclipse.winery.topologymodeler/src/main/webapp/css/palette.css new file mode 100644 index 0000000000..8e957d7b52 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/css/palette.css @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - initial API and implementation and/or initial documentation + * Oliver Kopp - improvements + *******************************************************************************/ + +#palette { + min-height: 180px; + background: rgb(248, 248, 248); + width: 230px; + box-shadow: 2px 2px 7px rgb(156, 156, 156); + padding: 10px; + border: 1px solid #aeaeae; + position: fixed; + top: 50px; + left: 0px; + z-index: 100; + cursor: default; + border-radius: 0px 9px 9px 0px; + background-image: -ms-linear-gradient(left, #FFFFFF 0%, rgb(237, 242, 247) 100%); + background-image: -moz-linear-gradient(left, #FFFFFF 0%, rgb(237, 242, 247) 100%); + background-image: -o-linear-gradient(left, #FFFFFF 0%, rgb(237, 242, 247) 100%); + background-image: -webkit-gradient(linear, left, right, color-stop(0, #FFFFFF), color-stop(1, rgb(237, 242, 247))); + background-image: -webkit-linear-gradient(left, #FFFFFF 0%, rgb(237, 242, 247) 100%); + background-image: linear-gradient(to right, #FFFFFF 0%, rgb(237, 242, 247) 100%); + + overflow-x: hidden; + overflow-y: visible; + max-height: 90%; + + /* fix for bootstrap.css, which sets that to "border-box" */ + box-sizing: content-box; + -webkit-box-sizing: content-box; +} + +#paletteLabel { + width: 0px; + background-color: blue; + top: 95px; + position: relative; + transform: rotate(270deg); + -o-transform: rotate(270deg); + -moz-transform: rotate(270deg); + -ms-transform: rotate(270deg); + -webkit-transform: rotate(270deg); + display: none; + left: 8px; + font-size: 12px; + color: rgb(143, 151, 170); +} + +div.iconContainer { + width: 45px; + margin-left: 5px; + float: left; + height: 20px; + margin-top: 4px; +} + + +div.paletteEntry { + height: 28px; + border-bottom: 1px solid rgb(200, 214, 228); + margin: 0px; + float: left; + width: 230px; +} + +div.paletteEntry:hover { + background: rgb(237, 242, 247); +} + + +div.paletteEntry > div.iconContainer > img.icon { + height: 20px; + vertical-align: top; +} + + +div.paletteEntry > div.typeContainer { + margin: 4px 0px; + height: 20px; + display: table; + width: 180px; + font-size: 11px; + line-height: 20px; +} + +div.paletteEntry > div.typeContainer > div.typeContainerMiddle { + display: table-cell; + vertical-align: middle; + width: 100%; + position: static; +} + +div.paletteEntry > div.typeContainer > div.typeContainerMiddle > div.typeContainerInner { +} + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/css/propertiesview.css b/org.eclipse.winery.topologymodeler/src/main/webapp/css/propertiesview.css new file mode 100644 index 0000000000..3ff0d3bde7 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/css/propertiesview.css @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - initial API and implementation and/or initial documentation + * Oliver Kopp - improvements + *******************************************************************************/ + +div.propertiesView { + width: 200px; + position: fixed; + top: 57px; + right: -1px; + background: #eaeaea; + z-index: 600; + background-image: linear-gradient(to left, #FFFFFF 0%, rgb(237, 243, 247) 100%); + border-radius: 9px 0px 0px 9px; + border: 1px solid #aeaeae; + padding: 14px; + box-shadow: -1px 2px 7px rgb(156, 156, 156); + font-size: 80%; +} + +#propertiesSection { + padding: 10px; +} + +#propertiesSection div.content { + background: rgb(244, 247, 250); +} + +#daSection { + background: #eaeaea; + padding: 10px; +} + +#daSection div.content { + background: rgb(244, 247, 250); +} + +#nodeTemplateInformationSection > div.control-group > label.control-label { + width: 37px; +} + +#nodeTemplateInformationSection > div.control-group > input { + width: 100px; +} + + +/* relationship templates only; adapted from topologytemplatecontent.css */ + +#RTPropertiesView > div.propertiesContainer > div.header { + font-weight: bold +} + +#RTPropertiesView > div.propertiesContainer > div.header > a { + float: right; + height: 6px; +} + +#RTPropertiesView > div.propertiesContainer > div.content > span.namespace { + display: none; +} + +#RTPropertiesView > div.propertiesContainer > div.content > span.elementName { + display: none; +} + +#RTPropertiesView > div.propertiesContainer > div.content table { + float: left; +} diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/css/topologymodeler.css b/org.eclipse.winery.topologymodeler/src/main/webapp/css/topologymodeler.css new file mode 100644 index 0000000000..18f83ead0b --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/css/topologymodeler.css @@ -0,0 +1,286 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - initial API and implementation and/or initial documentation + * Oliver Kopp - improvements + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ + +/* used if elements should be hidden forever. Cannot be undone with $(...).show() */ +.hidden { + display: none; +} + +.fileupload { + display: none; +} + +.overflowhidden { + overflow: hidden; + text-overflow: ellipsis; +} + + +body { + background-color: white; + margin: 0px; +} + +#loading { + position: absolute; + top: 0px; + left: 0px; + height: 100%; + width: 100%; z-index: 200; + background-color: white; + z-index: 2000; +} + +#topbar { + padding: 5px; + width: 100%; + position: fixed; + top: 0px; + z-index: 600; + background-color: white; +} + +/* override jquery-ui.css */ +.ui-widget { + font-size: 1.0em; + font-family: Arial, Helvetica, sans-serif; +} + +a:hover { + color:#1b911b; + background-color:#f0f0f0; +} + +#drawingarea { + height: 80em; + position: relative; +} + +#drawingarea.editview { + background: rgb(240, 246, 255); + background-image: -ms-linear-gradient(top, #FFFFFF 0%, rgb(243, 243, 243) 100%); + background-image: -moz-linear-gradient(top, #FFFFFF 0%, rgb(243, 243, 243) 100%); + background-image: -o-linear-gradient(top, #FFFFFF 0%, rgb(243, 243, 243) 100%); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #FFFFFF), color-stop(1, rgb(243, 243, 243))); + background-image: -webkit-linear-gradient(top, #FFFFFF 0%, rgb(243, 243, 243) 100%); + background-image: linear-gradient(to bottom, #FFFFFF 0%, rgb(243, 243, 243) 100%); +} + +#drawingarea.printview { +} + +/* currently not used */ +div.focusedElement { + border: 3px dotted rgb(0, 152, 255); + + /* IE10 Consumer Preview */ + background-image: -ms-linear-gradient(top, #FFFFFF 0%, rgb(153, 243, 255) 100%); + + /* Mozilla Firefox */ + background-image: -moz-linear-gradient(top, #FFFFFF 0%, rgb(153, 243, 255) 100%); + + /* Opera */ + background-image: -o-linear-gradient(top, #FFFFFF 0%, rgb(153, 243, 255) 100%); + + /* Webkit (Safari/Chrome 10) */ + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #FFFFFF), color-stop(1, rgb(153, 243, 255))); + + /* Webkit (Chrome 11+) */ + background-image: -webkit-linear-gradient(top, #FFFFFF 0%, rgb(153, 243, 255) 100%); + + /* W3C Markup, IE10 Release Preview */ + background-image: linear-gradient(to bottom, #FFFFFF 0%, rgb(153, 243, 255) 100%); +} + + +div.NodeTemplateShape.selected { + background: rgb(216, 238, 255); + border: 2px solid rgb(255, 127, 26); + + + /* IE10 Consumer Preview */ + background-image: -ms-linear-gradient(top, #FFFFFF 0%, #FFD391 100%); + + /* Mozilla Firefox */ + background-image: -moz-linear-gradient(top, #FFFFFF 0%, #FFD391 100%); + + /* Opera */ + background-image: -o-linear-gradient(top, #FFFFFF 0%, #FFD391 100%); + + /* Webkit (Safari/Chrome 10) */ + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #FFFFFF), color-stop(1, #FFD391)); + + /* Webkit (Chrome 11+) */ + background-image: -webkit-linear-gradient(top, #FFFFFF 0%, #FFD391 100%); + + /* W3C Markup, IE10 Release Preview */ + background-image: linear-gradient(to bottom, #FFFFFF 0%, #FFD391 100%); +} + +div.content { + overflow: hidden; + width: 100%; +} + +.renderMode.ui-draggable { + display:none; +} + +div.menu { + display:none; +} + +._jsPlumb_overlay { + z-index: 5000; +} + +/* overriding dimensions.css to overcome problems with non-standard fonts and breaking cells */ +.u-size3of5, +.u-size6of10 { + width: 59%; +} +.u-size4of5 { + width: 79%; +} + +.breakword { + overflow-wrap: break-word; +} + +a.topbutton { + margin-right: 10px; +} + +#selectionbox { + position: absolute; + border-style: dashed; + border-width: 3px; + border-color: black; + background-color: cyan; + opacity: 0.15; + z-index: 30; + display: none; +} + +#editorArea { + width: 100%; + height: 100%; + margin-top: 45px; +} + +#nodeTemplateInformationSection > label { + display: inline-block; + width: 47px; +} + +.form-horizontal .controls > span { + margin-top: 5px; + display: inline-block; +} + +/* reset editable style */ +.editable-click { + border-bottom: none; +} + +a.editable-click { + border-bottom: none; +} + +a.editable-click:hover { + border-bottom: none; +} + + +/* adding a req/cap */ + +div.modal-body > form.addReqForm > div.propertiesContainer { + border: 1px solid #aeaeae; + background: #ffffff; + margin: 7px; + width: 198px; + border-radius: 7px; + padding: 5px; + float: left; + overflow-x: hidden; + display: none; +} + +div.modal-body > form.addReqForm > div.propertiesContainer > div.header { + background: rgb(241, 241, 241); + border-bottom: 1px solid #aeaeae; + float: left; + width: 198px; + padding: 5px; + margin-top: -5px; + margin-left: -5px; + margin-bottom: 6px; +} + +div.modal-body > form.addReqForm > div.propertiesContainer > div.header > a { + float: right; + height: 6px; +} + +div.modal-body > form.addReqForm > div.propertiesContainer > div.content > span.namespace { + display: none; +} + +div.modal-body > form.addReqForm > div.propertiesContainer > div.content > span.elementName { + display: none; +} + +div.modal-body > form.addReqForm > div.propertiesContainer > div.content table { + float: left; +} + +div.modal-body > form.addCapForm > div.propertiesContainer { + border: 1px solid #aeaeae; + background: #ffffff; + margin: 7px; + width: 198px; + border-radius: 7px; + padding: 5px; + float: left; + overflow-x: hidden; + display: none; +} + +div.modal-body > form.addCapForm > div.propertiesContainer > div.header { + background: rgb(241, 241, 241); + border-bottom: 1px solid #aeaeae; + float: left; + width: 198px; + padding: 5px; + margin-top: -5px; + margin-left: -5px; + margin-bottom: 6px; +} + +div.modal-body > form.addCapForm > div.propertiesContainer > div.header > a { + float: right; + height: 6px; +} + +div.modal-body > form.addCapForm > div.propertiesContainer > div.content > span.namespace { + display: none; +} + +div.modal-body > form.addCapForm > div.propertiesContainer > div.content > span.elementName { + display: none; +} + +div.modal-body > form.addCapForm > div.propertiesContainer > div.content table { + float: left; +} diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/css/topologytemplatecontent.css b/org.eclipse.winery.topologymodeler/src/main/webapp/css/topologytemplatecontent.css new file mode 100644 index 0000000000..0c7eea46be --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/css/topologytemplatecontent.css @@ -0,0 +1,421 @@ +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - initial API and implementation and/or initial documentation + * Oliver Kopp - improvements + *******************************************************************************/ + +/** This CSS is shared between the Winery Repository and the Winery Topology Modeler **/ + +div.NodeTemplateShape { + font-family: arial, verdana; + font-size: 12px; + + border: 1px solid black; + border: 2px solid rgb(112, 152, 179); + border-radius: 12px; + width: 225px; + z-index:20; + position:absolute; + box-shadow: 5px 5px 17px #aaa; + background: #ffffff; + cursor: move; + + /* IE10 Consumer Preview */ + background-image: -ms-linear-gradient(top, #FFFFFF 0%, #EBF2F7 100%); + + /* Mozilla Firefox */ + background-image: -moz-linear-gradient(top, #FFFFFF 0%, #EBF2F7 100%); + + /* Opera */ + background-image: -o-linear-gradient(top, #FFFFFF 0%, #EBF2F7 100%); + + /* Webkit (Safari/Chrome 10) */ + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #FFFFFF), color-stop(1, #EBF2F7)); + + /* Webkit (Chrome 11+) */ + background-image: -webkit-linear-gradient(top, #FFFFFF 0%, #EBF2F7 100%); + + /* W3C Markup, IE10 Release Preview */ + background-image: linear-gradient(to bottom, #FFFFFF 0%, #EBF2F7 100%); +} + +div.NodeTemplateShape > div.headerContainer { + height: 65px; +} + +div.NodeTemplateShape div.minMaxInstances { +} + +div.NodeTemplateShape div.minMaxInstances span.minInstances { + +} + +div.NodeTemplateShape div.minMaxInstances span.maxInstances { + +} + +div.NodeTemplateShape > .headerContainer > img.icon { + float: left; + height: 55px; + margin: 10px 0px 10px 10px; +} +div.NodeTemplateShape > .headerContainer > div.id { + position: absolute; + left: 90px; + top: 0px; + height: 16px; + width: 130px; + text-overflow: ellipsis; + overflow: hidden; + text-decoration: underline; + display: none; +} +div.NodeTemplateShape > .headerContainer > div.name { + position: absolute; + left: 90px; + top: 20px; + height: 16px; + width: 130px; + text-overflow: ellipsis; + overflow: hidden; +} +div.NodeTemplateShape > .headerContainer > div.type { + position: absolute; + left: 90px; + top: 40px; + height: 16px; + width: 130px; + text-overflow: ellipsis; + overflow: hidden; +} +div.NodeTemplateShape > .headerContainer > div.type:before { + content: "("; +} +div.NodeTemplateShape > .headerContainer > div.type:after { + content: ")"; +} + +img.createAnnotation { + width: 20px; + position: absolute; + top: 5px; + right: 5px; +} + +a.KVPropertyValue { + overflow: hidden; + text-overflow: ellipsis; +} + +div.NodeTemplateShape > div.deploymentArtifactsContainer { + border: 1px solid #aeaeae; + background: #ffffff; + margin: 7px; + width: 198px; + border-radius: 7px; + padding: 5px; + float: left; + overflow-x: hidden; + display: none; +} + +div.NodeTemplateShape > div.deploymentArtifactsContainer > div.header { + border-bottom: 1px solid #aeaeae; + float: left; + width: 198px; + padding: 5px; + margin-top: -5px; + margin-left: -5px; + margin-bottom: 6px; + background-image: -ms-linear-gradient(top, #FFFFFF 0%, rgb(209, 209, 209) 100%); + background-image: -moz-linear-gradient(top, #FFFFFF 0%, rgb(209, 209, 209) 100%); + background-image: -o-linear-gradient(top, #FFFFFF 0%, rgb(209, 209, 209) 100%); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #FFFFFF), color-stop(1, rgb(209, 209, 209))); + background-image: -webkit-linear-gradient(top, #FFFFFF 0%, rgb(209, 209, 209) 100%); + background-image: linear-gradient(to bottom, #FFFFFF 0%, rgb(209, 209, 209) 100%); +} + +div.NodeTemplateShape > div.deploymentArtifactsContainer > div.content > div.deploymentArtifact { + background-color: #FFDADA; + height: 20px; +} + +/* indicates editing possibility */ +div.NodeTemplateShape > div.deploymentArtifactsContainer > div.content > div.deploymentArtifact:hover { + background-color: lightblue; + cursor: pointer; +} + +div.NodeTemplateShape > div.deploymentArtifactsContainer > div.content > div.deploymentArtifact > div { + height: 20px; +} + +div.NodeTemplateShape > div.deploymentArtifactsContainer > div.content > div.deploymentArtifact:first-child { + border-top: 0px; +} + +div.NodeTemplateShape > div.deploymentArtifactsContainer > div.content > div.addDA { + display: none; +} + +div.NodeTemplateShape > div.deploymentArtifactsContainer > div.content > div.addnewartifacttemplate { + display: none; + background-color: Silver; + text-align: center; +} + +div.NodeTemplateShape > div.propertiesContainer { + border: 1px solid #aeaeae; + background: #ffffff; + margin: 7px; + width: 198px; + border-radius: 7px; + padding: 5px; + float: left; + overflow-x: hidden; + display: none; +} + +div.NodeTemplateShape > div.propertiesContainer > div.header { + background: rgb(241, 241, 241); + border-bottom: 1px solid #aeaeae; + float: left; + width: 198px; + padding: 5px; + margin-top: -5px; + margin-left: -5px; + margin-bottom: 6px; +} + +div.NodeTemplateShape > div.propertiesContainer > div.header > a { + float: right; + height: 6px; +} + +div.NodeTemplateShape > div.propertiesContainer > div.content > span.namespace { + display: none; +} + +div.NodeTemplateShape > div.propertiesContainer > div.content > span.elementName { + display: none; +} + +div.NodeTemplateShape > div.propertiesContainer > div.content table { + float: left; +} + +div.NodeTemplateShape div.reqorcap { + cursor: pointer; +} + +div.NodeTemplateShape div.reqorcap.id { +} + +div.NodeTemplateShape div.reqorcap.name { + overflow: hidden; + text-overflow: ellipsis; +} + +div.NodeTemplateShape div.reqorcap.type { + overflow: hidden; + text-overflow: ellipsis; +} + +/* indicates editing possibility */ +div.NodeTemplateShape div.reqorcap:hover { + background-color: lightgray; +} + +div.NodeTemplateShape > div.requirementsContainer { + border: 1px solid #aeaeae; + background: #ffffff; + margin: 7px; + width: 198px; + border-radius: 7px; + padding: 5px; + float: left; + overflow-x: hidden; + display: none; +} + +div.NodeTemplateShape > div.requirementsContainer > div.header { + background: rgb(241, 241, 241); + border-bottom: 1px solid #aeaeae; + float: left; + width: 198px; + padding: 5px; + margin-top: -5px; + margin-left: -5px; + margin-bottom: 6px; +} + +div.NodeTemplateShape > div.requirementsContainer > div.content > div.reqorcap > div.propertiesContainer { + display: none; +} + + +div.NodeTemplateShape > div.capabilitiesContainer { + border: 1px solid #aeaeae; + background: #ffffff; + margin: 7px; + width: 198px; + border-radius: 7px; + padding: 5px; + float: left; + overflow-x: hidden; + display: none; +} + +div.NodeTemplateShape > div.capabilitiesContainer > div.header { + background: rgb(241, 241, 241); + border-bottom: 1px solid #aeaeae; + float: left; + width: 198px; + padding: 5px; + margin-top: -5px; + margin-left: -5px; + margin-bottom: 6px; +} + +div.NodeTemplateShape > div.capabilitiesContainer > div.content > div.reqorcap > div.propertiesContainer { + display: none; +} + + +/** Policies **/ + +div.NodeTemplateShape > div.policiesContainer { + border: 1px solid #aeaeae; + background: #ffffff; + margin: 7px; + width: 198px; + border-radius: 7px; + padding: 5px; + float: left; + overflow-x: hidden; + display: none; +} + +div.NodeTemplateShape > div.policiesContainer > div.header { + background: rgb(241, 241, 241); + border-bottom: 1px solid #aeaeae; + float: left; + width: 198px; + padding: 5px; + margin-top: -5px; + margin-left: -5px; + margin-bottom: 6px; +} + +/* indicates editing possibility */ +div.NodeTemplateShape > div.policiesContainer > div.content > div.policy:hover { + background-color: lightgray; +} + +div.NodeTemplateShape > div.policiesContainer > div.content > div.policy > div { + overflow: hidden; + text-overflow: ellipsis; +} + +div.NodeTemplateShape > div.policiesContainer > div.content > div.policy > span { + display: none; +} + +div.NodeTemplateShape > div.policiesContainer > div.content > div.policy > textarea.policy_xml { + display: none; +} + + + +div.connectorBox { + height: 15px; + width: 15px; + float: left; +} + +div.connectorLabel { + height: 15px; + width: 125px; + overflow: hidden; + margin-left: 20px; + white-space: nowrap; + line-height: 16px; + overflow: hidden; + text-overflow: ellipsis; +} + +div.connectorEndpoint { + width: 140px; + cursor: pointer; +} + +div.connectorEndpoint:hover { + background: rgb(237, 242, 247); +} + +div.endpointContainer { + background: #ffffff; + box-shadow: 2px 2px 19px #aaa; + border: 1px solid #aeaeae; + width: 150px; + position: absolute; + left: 212px; + padding: 5px; + z-index: 20; + display: none; +} + +._jsPlumb_connector { + z-index: 15; +} + +div#patternArea { + position: absolute; + z-index: 10000; + right: 0px; + top: 0px; + height: 100%; + width: 500px; + background: rgb(250, 250, 250); + padding: 5px; +} + +div.patternSuggestionContainer { + border: 2px solid #aeaeae; + padding: 5px 3px; + margin-bottom: 5px; +} + +div.patternSuggestionContainer.focusedElement { + +} + +.pointer { + cursor: pointer; +} + +div.relationshipTypeLabel { + /* z-index of arrow is 14, therefore we use 15 */ + z-index: 15; + + cursor: default; + font-family: arial, verdana; + font-size: 12px; +} + +.unselectable { + /* disable text selection - source: http://stackoverflow.com/a/4407335/873282 */ + user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -webkit-touch-callout: none; + -webkit-user-select: none; +} diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/css/winery-common.css b/org.eclipse.winery.topologymodeler/src/main/webapp/css/winery-common.css new file mode 100644 index 0000000000..b6d225112e --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/css/winery-common.css @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - initial API and implementation and/or initial documentation + * Oliver Kopp - improvements + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ + +/** This CSS is shared between the Winery Repository and the Winery Topology Modeler **/ + +.informationbox { + position: absolute; + text-align: center; + top: 0; + left: 0; + width: 100%; + height: 0; + z-index: 99; +} + +.informationbox > .alert { + background: #fff1a8; + border: 1px solid #999; + border-top: 0; + border-radius: 0 0 3px 3px; + display: inline-block; + line-height: 21px; + padding: 0 12px; +} + +/* when hovering over the text, the cursor should stay as is */ +.ui-pnotify { + cursor: default; +} + +/* change pnotify's container to be always at the top of the window */ +div.ui-pnotify-history-container { + position: fixed; +} + +/* enable pnotify notifications to wrap correctly */ +.ui-pnotify-text { + overflow: hidden; + overflow-wrap: break-word; +} + +.button { + cursor: pointer; +} + +td.editable { + cursor: text; +} + +td { + cursor: default; +} + +.input-xxlarge { + width: 510px; +} + +.spinner { + text-align: right; +} + +/* enables stacked modal dialogs */ +div.z1051 { + z-index: 1051; +} + +/* used for showing the full notification at PNotify */ +div.z1060 { + z-index: 1060; +} + + +/* fixes bootstrap margin problem at horizontal form */ +.form-horizontal > div.control-group > label.control-label { + margin-right: 10px; +} + +/* used by artifactcreationdialog.tag */ +div.unknown { + color: gray; +} + +div.unknown:before { + content: '?'; +} + +div.invalid { + color: red; +} + +div#artifactTemplateNameIsValid { + height: 19px; +} + +div.valid { + color: green; +} + +#diagmessagemsg { + text-overflow: ellipsis; + overflow: hidden; +} + +textarea.properties_xml { + display: none +} + +/** properties **/ + +span.properties_element { + display: none; +} + +span.properties_type { + display: none +} + +div.form-group-grouping { + background: #F0F0F0; + padding: 15px; + margin-top: 10px; + margin-bottom: 10px; +} + +div.orionxmleditordiv { + height: 300px; +} \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/favicon.png b/org.eclipse.winery.topologymodeler/src/main/webapp/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..25484fe57eef6d98986a1fe9749861da00ba6fe9 GIT binary patch literal 674 zcmV;T0$u%yP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv0006JNkl``(Y??aXKi4JS0Cd3b_g^nZy3N@9VMSfC_SfQsko zo0E%w>fORi9X$j0{JrGJNTLt&a}w1`$ByuF&E_LbEGl!`1rsD3-a52 z;TqwBC#NX5vV7LpYwS7)kZi(EwbsLdU4+cS{5@+e2@pAhnF^5C_F&t}Qs0bzeG#?+ zz+wDE{Q`b&_ zVSq?MatFo>a`wJe>(z>?IoGMWk2{RFx4HXU6!zCfnmbKxE86lhY7{9dc)K=80mwAaXEF9de%z1X3chn|3Aw_3p8Wskja^xyiAJywm{;=?xjX; zM){G$%FghyMS|qFThy~QRs~p3kZ4DhjB8bae21TRS#tFRWRIJ!E$7NYm@slc@#3y4 z(2RU9bA^-~MpvipF|ZX)6+uclm*T07^^ZeQ2$G$6x+L&(p6>AFFRw6{!$fz;X%C9-mArnJ zx`LX#g`K{Lpumfw!i=KAkEO(sr^b?~#+9qcm#oQHqoiI+qbYoQxaC=z#GKJ6GyrV#Y%diC zV*nfN2mTPiDos?v_xb>q+V|WpfO*VS!gbmJEbTkj27sAq8k5nW*J(A2;s+OY8o;O9 Rz*PVM002ovPDHLkV1g7-^+Esu literal 0 HcmV?d00001 diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/index.jsp b/org.eclipse.winery.topologymodeler/src/main/webapp/index.jsp new file mode 100644 index 0000000000..f8898a7847 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/index.jsp @@ -0,0 +1,1469 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Uwe Breitenbücher - initial API and implementation and/or initial documentation + * Oliver Kopp - integration with the repository, adapted to TOSCA v1.0 + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> + +<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> +<%@page buffer="none" %> +<%@page import="java.util.Collection"%> +<%@page import="java.util.List"%> +<%@page import="java.util.LinkedList"%> +<%@page import="java.util.Map"%> +<%@page import="java.util.SortedSet"%> +<%@page import="javax.xml.namespace.QName"%> +<%@page import="org.apache.commons.lang3.StringUtils"%> +<%@page import="org.eclipse.winery.model.tosca.TArtifactTemplate"%> +<%@page import="org.eclipse.winery.model.tosca.TArtifactType"%> +<%@page import="org.eclipse.winery.model.tosca.TCapability"%> +<%@page import="org.eclipse.winery.model.tosca.TCapabilityType"%> +<%@page import="org.eclipse.winery.model.tosca.TEntityTemplate"%> +<%@page import="org.eclipse.winery.model.tosca.TTopologyTemplate"%> +<%@page import="org.eclipse.winery.model.tosca.TNodeTemplate"%> +<%@page import="org.eclipse.winery.model.tosca.TNodeType"%> +<%@page import="org.eclipse.winery.model.tosca.TPolicyType"%> +<%@page import="org.eclipse.winery.model.tosca.TRelationshipType"%> +<%@page import="org.eclipse.winery.model.tosca.TRelationshipTemplate"%> +<%@page import="org.eclipse.winery.model.tosca.TRelationshipTemplate.SourceElement"%> +<%@page import="org.eclipse.winery.model.tosca.TRelationshipTemplate.TargetElement"%> +<%@page import="org.eclipse.winery.model.tosca.TRequirement"%> +<%@page import="org.eclipse.winery.model.tosca.TRequirementType"%> +<%@page import="org.eclipse.winery.common.constants.Namespaces" %> +<%@page import="org.eclipse.winery.common.ids.definitions.ArtifactTemplateId"%> +<%@page import="org.eclipse.winery.common.ids.definitions.ServiceTemplateId" %> +<%@page import="org.eclipse.winery.common.interfaces.QNameWithName"%> +<%@page import="org.eclipse.winery.common.constants.QNames" %> +<%@page import="org.eclipse.winery.common.ModelUtilities"%> +<%@page import="org.eclipse.winery.common.Util"%> +<%@page import="org.eclipse.winery.repository.client.WineryRepositoryClientFactory"%> +<%@page import="org.eclipse.winery.repository.client.IWineryRepositoryClient"%> +<%@page import="org.eclipse.winery.repository.client.WineryRepositoryClient"%> +<%@page import="org.eclipse.winery.topologymodeler.WineryUtil"%> +<%@page import="com.sun.jersey.api.client.WebResource"%> +<%@page import="com.sun.jersey.api.client.Client"%> +<%@page import="com.sun.jersey.api.client.ClientResponse"%> +<%@page import="com.sun.jersey.api.client.config.ClientConfig"%> +<%@page import="com.sun.jersey.api.client.config.DefaultClientConfig"%> + +<%-- nc.. = non-common .. --%> +<%@taglib prefix="ncnt" tagdir="/WEB-INF/tags/templates/nodetemplates" %> +<%@taglib prefix="ncrt" tagdir="/WEB-INF/tags/templates/relationshiptemplates" %> +<%@taglib prefix="tntrq" tagdir="/WEB-INF/tags/templates/nodetemplates/reqscaps" %> + +<%@taglib prefix="ct" tagdir="/WEB-INF/tags/common" %> +<%@taglib prefix="tmpl" tagdir="/WEB-INF/tags/common/templates" %> +<%@taglib prefix="nt" tagdir="/WEB-INF/tags/common/templates/nodetemplates" %> +<%@taglib prefix="ntrq" tagdir="/WEB-INF/tags/common/templates/nodetemplates/reqscaps" %> +<%@taglib prefix="pol" tagdir="/WEB-INF/tags/common/policies" %> + +<%@taglib prefix="t" tagdir="/WEB-INF/tags" %> + +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="wc" uri="http://www.eclipse.org/winery/functions" %> + + +<% + String repositoryURL = request.getParameter("repositoryURL"); + if (StringUtils.isEmpty(repositoryURL)) { + repositoryURL = "http://localhost:8080/winery"; + } else if (repositoryURL.endsWith("/")) { + repositoryURL = repositoryURL.substring(0, repositoryURL.length()-1); + } + + String ns = request.getParameter("ns"); + if (StringUtils.isEmpty(ns)) { +%> + A namespace has to be provided by using the query parameter “ns.” Please start the modeler using the repository. +<% + return; + } + + String id = request.getParameter("id"); + if (StringUtils.isEmpty(id)) { +%> + An id has to be provided by using the query parameter “id.” Please start the modeler using the repository. +<% + return; + } + + // initialize client dependend on useproxy URL parameter + IWineryRepositoryClient client; + if (request.getParameterMap().containsKey("useproxy")) { + // debugging - using fiddler: + client = new WineryRepositoryClient(true); + System.out.println("Using a proxy..."); + } else { + // production: + client = WineryRepositoryClientFactory.getWineryRepositoryClient(); + } + + client.addRepository(repositoryURL); + + if (!client.primaryRepositoryAvailable()) { +%> + The repository is not available. +<% + return; + } + + QName serviceTemplateQName = new QName(ns, id); + TTopologyTemplate topologyTemplate = client.getTopologyTemplate(serviceTemplateQName); + if (topologyTemplate == null) { +%> + Something went wrong in the repository: topology template not found. +<% + return; + } + + String topologyTemplateURL = repositoryURL + "/servicetemplates/" + Util.DoubleURLencode(serviceTemplateQName) + "/topologytemplate/"; + + String serviceTemplateName = client.getName(new ServiceTemplateId(serviceTemplateQName)); + + Collection relationshipTypes = client.getAllTypes(TRelationshipType.class); +%> + + + + Winery Topologymodeler – <%= serviceTemplateName %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    loading...
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<% + // only required for generating the CSS for each node type + Collection allNodeTypes = client.getAllTypes(TNodeType.class); +%> + + + + + + + + + +<%-- Begin: Add&Edit Req/Cap --%> + +<%List allTypes = client.getQNameListOfAllTypes(TRequirementType.class);%> + + +<%allTypes = client.getQNameListOfAllTypes(TCapabilityType.class);%> + + +<%-- End: Add&Edit Req/Cap --%> + +<%allTypes = client.getQNameListOfAllTypes(TPolicyType.class);%> + + + + + + + + + + + + +<% +// we want to display the name of the artifact template, not the id +Collection artifactTemplateList = client.getListOfAllInstances(ArtifactTemplateId.class); +%> + +
    + + + +
    + + +
    + + + +
    + + + + <%-- confusing, because DELETE at this place in the management part deletes the whole entity, not just the selected one + + --%> + + + + CSAR + + + + + +
    + + + + +
    +
    + +
    +
    + +<% + List templateList = topologyTemplate.getNodeTemplateOrRelationshipTemplate(); + List relationshipTemplates = new LinkedList(); + for (TEntityTemplate template: templateList) { + if (template instanceof TRelationshipTemplate) { + relationshipTemplates.add((TRelationshipTemplate) template); + } else { + TNodeTemplate nodeTemplate = (TNodeTemplate) template; + + // Get saved position + // x and y are stored as attributes of other namespaces + String left = ModelUtilities.getLeft(nodeTemplate); + String top = ModelUtilities.getTop(nodeTemplate); + %> + + <% + } + } + %> +
    +
    + + + + + + + + + + + + + + + + + +<%-- ===== BEGIN: enable editing properties of requirements and capabilities ===== --%> + + + + +<%-- ===== END: enable editing properties of requirements and capabilities ===== --%> + + +<%-- ===== BEGIN: enable editing properties of relationship types ===== --%> +<%-- idea: + * create editor in skelettonContainerForRelationshipTemplates, + * move it to the properties for editing, + * and move it back to skelettonContainerForRelationshipTemplates after editing +--%> + + + + + + +<%-- ===== END: enable editing properties of relationship types ===== --%> + + + + + + + + +
    + + + + + +<%-- param: value, selected (optional), text --%> + + + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/js/artifacttemplateselection.js b/org.eclipse.winery.topologymodeler/src/main/webapp/js/artifacttemplateselection.js new file mode 100644 index 0000000000..7b7f20baa2 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/js/artifacttemplateselection.js @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ + + // also loaded from the repository + +// TODO: winery-common should be required -> encodeID; typing could be required (but that is no AMD module) +define([], function() { + $("#artifactTemplateName").typing({ + start: function(event, $elem) { + flagArtifactTemplateNameAsUpdating(); + }, + stop: function(event, $elem) { + checkArtifactTemplateName(); + } + }); + + $("#artifactTemplateNS").on("blur", checkArtifactTemplateName).on("change", checkArtifactTemplateName).on("focus", flagArtifactTemplateNameAsUpdating); + + var repositoryURL; + + return { + setRepositoryURL: function(url) { + repositoryURL = url; + }, + checkArtifactTemplateName: checkArtifactTemplateName, + flagArtifactTemplateNameAsUpdating: flagArtifactTemplateNameAsUpdating + }; + + function checkArtifactTemplateName() { + var ns = $("#artifactTemplateNS").val(); + var name = $("#artifactTemplateName").val(); + var url = repositoryURL + "/artifacttemplates/" + encodeID(ns) + "/" + encodeID(name) + "/"; + if (name == "") { + var valid = false; + var invalidReason = "No name provided"; + setValidityStatus(valid, invalidReason); + } else { + $.ajax(url, { + type: 'HEAD', + dataType: 'html', + error: function(jqXHR, textStatus, errorThrown) { + if (jqXHR.status == 404) { + // artifact template does not exist: everything is allright + setValidityStatus(true, null); + } else { + setValidityStatus(false, textStatus); + } + }, + success: function(data, textStatus, jqXHR) { + setValidityStatus(false, "artifact template already exists"); + } + }); + } + } + + function flagArtifactTemplateNameAsUpdating() { + $("#artifactTemplateNameIsValid").removeClass("invalid").removeClass("valid").addClass("unknown"); + $("#artifactTemplateNameIsInvalidReason").text(""); + } + + function setValidityStatus(valid, invalidReason) { + $("#artifactTemplateNameIsValid").removeClass("unknown"); + if (valid) { + $("#artifactTemplateNameIsValid").addClass("valid"); + $("#artifactTemplateNameIsInvalidReason").text("Ok"); + } else { + $("#artifactTemplateNameIsValid").addClass("invalid"); + $("#artifactTemplateNameIsInvalidReason").text(invalidReason); + } + } + + +}); \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-audio.js b/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-audio.js new file mode 100644 index 0000000000..20e2cde7e5 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-audio.js @@ -0,0 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ + +// dummy as we don't need the functionality, but jquery.fileupload-ui.js requires it \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-image.js b/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-image.js new file mode 100644 index 0000000000..20e2cde7e5 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-image.js @@ -0,0 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ + +// dummy as we don't need the functionality, but jquery.fileupload-ui.js requires it \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-validate.js b/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-validate.js new file mode 100644 index 0000000000..20e2cde7e5 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-validate.js @@ -0,0 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ + +// dummy as we don't need the functionality, but jquery.fileupload-ui.js requires it \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-video.js b/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-video.js new file mode 100644 index 0000000000..20e2cde7e5 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/js/jquery.fileupload-video.js @@ -0,0 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ + +// dummy as we don't need the functionality, but jquery.fileupload-ui.js requires it \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-common-topologyrendering.js b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-common-topologyrendering.js new file mode 100644 index 0000000000..fa37897464 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-common-topologyrendering.js @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ +/** + * This file contains supporting functions for the rendering a topology template + */ +define( + ["jsplumb", "winery-support-common"], + function (globdefa, wsc) { + var readOnly = false; + + var module = { + initNodeTemplate: initNodeTemplate, + handleConnectionCreated: handleConnectionCreated, + imageError: imageError, + setReadOnly: setReadOnly + }; + + return module; + + /** + * @param nodeTemplateShape the set of node template shapes to initialize + * @param makeDraggable true if the nodeTemplates should be made draggable + */ + function initNodeTemplate(nodeTemplateShapeSet, makeDraggable) { + if (makeDraggable) { + jsPlumb.draggable(nodeTemplateShapeSet); + } + jsPlumb.makeTarget(nodeTemplateShapeSet, { + anchor:"Continuous", + endpoint:"Blank" + }); + + // this function is defined in index.jsp via jsp functions + // as it depends on the available relationship types + createConnectorEndpoints(nodeTemplateShapeSet); + + nodeTemplateShapeSet.addClass("layoutableComponent"); + + nodeTemplateShapeSet.each(function(idx, s) { + var shape = $(s); + + var id = shape.attr("id"); + + // KV Properties + var props = shape.children(".propertiesContainer") + .children(".content") + .children("table") + .children("tbody"); + if (!readOnly) { + props.find(".KVPropertyValue").editable(); + } + + // Deployment Artifacts + var fu = shape.children(".deploymentArtifactsContainer") + .children(".content") + .children(".addnewartifacttemplate") + .children(".fileupload"); + fu.attr("data-url", "nodetemplates/" + wsc.encodeId(id) + "/deploymentartifacts/"); + }); + + // nodeTemplateShapeSet.children(".deploymentArtifactsContainer").children(".content").children(".deploymentArtifact").each(function(index, e) { + // addnewfileoverlay could be added here + // $(this). + // }); + } + + /** + * Handles the creation of connections by jsPlumb + * + * Also called if connection is created during loading + */ + function handleConnectionCreated(data) { + // might be called directly from here or by the event + // if called by jsPlumb infrastructure, we have to get rid of the surrounding element + var conn; + if (data.connection) { + conn = data.connection; + } else { + conn = data; + } + winery.debugConnData = conn; + + var id = conn.id; + winery.connections[id] = { + // we store the id to have a default for the id + id: id, + // and use it also as starting point of a name + name: id, + // we do NOT copy the plain type here + // type is stored in the connection + // type: .getType()[0] + // BUT: we copy the detailed ns and id + nsAndLocalName: wsc.getNamespaceAndLocalNameFromQName(conn.getType()[0]) + }; + putToolTipInfo(conn); + + // we have to manually show and hide the tooltips as Bootstrap's tooltip plugin does not work after a connection was highlighted. + conn.bind("mouseenter", function(conn,e) { + putToolTipInfo(conn); + }); + conn.bind("mouseexit", function(conn,e) { + $("div.tooltip").remove(); + // we have to replace the tooltip as + putToolTipInfo(conn); + }); + } + + function putToolTipInfo(conn) { + // add tooltip showing the relationship type + var svgElement = $(conn.canvas); + // the title attribute is shown in the tooltip + // set the relationship type as tooltip + // we show the localname only + var nsAndLocalName = winery.connections[conn.id].nsAndLocalName; + // Vino4TOSCA: type in brackets + var title = "(" + nsAndLocalName.localname + ")"; + svgElement.tooltip({title: title}); + } + + /** + * Removes the image from the display. Used at images which could not be loaded + * + * Used via {@code } + */ + function imageError(image) { + image.onError=""; + image.style.visibility = "hidden"; + } + + function setReadOnly() { + readOnly = true; + } + } +); \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-common.js b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-common.js new file mode 100644 index 0000000000..ae0f5b3c63 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-common.js @@ -0,0 +1,263 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ + +/** +This .js file is shared between the Winery Repository and the Winery Topology Modeler + +This should be rewritten as AMD module. A start is made in winery-support-common.js. + +vConfirmYesNo is defined in jsp/shared/dialogs.jsp +*/ + +/** + * Highlights fields, which are required but not filled out by the user. + * The check for required fields is done via the CSS class "required" + * + * @return true if a required field is not filled with a value + */ +function highlightRequiredFields() { + var requiredFieldMissing = false; + // includes check input field attribute "required" of HTML5: http://www.w3.org/TR/html-markup/input.radio.html#input.radio.attrs.required + $("input.required:visible:enabled, input[required]:visible").each(function(){ + if ($(this).val() == '') { + $(this).parent().addClass('has-warning'); + requiredFieldMissing = true; + } else { + $(this).parent().removeClass('has-warning'); + } + }); + return requiredFieldMissing; +} + +function vPnotify(text, title, type) { + var notice = $.pnotify({ + title: title, + text: text, + type: type + }); + notice.on("click", function(e) { + var target = $(e.target); + if (target.is(".ui-pnotify-closer *, .ui-pnotify-sticker *, a")) { + // buttons clicked - call their functionality + return true; + } else { + // click on text leads to display of a dialog showing the complete content + + var textDiv; + if (target.is("div.ui-pnotify-text")) { + textDiv = target; + } else { + textDiv = target.closest("div.ui-pnotify-container").find("div.ui-pnotify-text"); + } + + // put text into dialog and show it + $("#diagmessagetitle").text("Full notification"); + $("#diagmessagemsg").html(textDiv.html()); + $("#diagmessage").modal("show"); + + return false; + } + }); +} + +/** + * @param title optional title + */ +function vShowError(text, title) { + vPnotify(text, title, "error"); +} + +function vShowAJAXError(msg, jqXHR, errorThrown) { + vShowError(msg + "
    " + errorThrown + "
    " + jqXHR.responseText); +} + +/** + * @param title optional title + */ +function vShowNotification(text, title) { + vPnotify(text, title, "notification"); +} + + +/** + * @param title optional title + */ +function vShowSuccess(text, title) { + vPnotify(text, title, "success"); +} + +/** + * Deletes the given resource with confirmation. + * if deletion fails, an error message is shown + * + * @param onSuccess: function(data, textStatus, jqXHR) to call if deletion has been successful + * @param onError: function(jqXHR, textStatus, errorThrown) called if deletion lead to an error (optional) + * @param onStart: function() called if user has agreed to delete resource (optional) + * @param withoutConfirmation if given, the resource is deleted without any confirmation + */ +function deleteResource(nameOfResource, url, onSuccess, onError, onStart, withoutConfirmation) { + var f = function() { + $.ajax({ + url: url, + type: 'DELETE', + async: true, + error: function(jqXHR, textStatus, errorThrown) { + vShowAJAXError("Could not delete " + nameOfResource, jqXHR, errorThrown); + if (onError) onError(); + }, + success: function(data, textStatus, jqXHR) { + vShowSuccess("Successfully deleted " + nameOfResource); + onSuccess(data, textStatus, jqXHR); + } + }); + }; + if (withoutConfirmation) { + f(); + } else { + vConfirmYesNo("Do you really want to delete " + nameOfResource + "?", f); + } +} + +/** + * Function to create a td with two columns: one for a key and one for a value + * + * Has to be called from a td element: This function uses $(this) to determine the td + * It changes the content of the td to an input field. In case the input was updated, it is POSTed to the given URL + * + * TODO: The editing mode should use x-editable instead of a self-written input handling + * + * @param url the URL to post the key/value pair to + * @param keyName the keyname of the key - used at POST with = + * @param valueName the keyname of the value - used at POST with = + * + */ +function vCreateTdClickFunction(url, keyName, valueName) { + var inputId = "thingedit" + Math.floor((Math.random()*100)+1); ; + keyName = keyName || "key"; + valueName = valueName || "value"; + + var f = function(e) { + var input = $("#" + inputId); + if (input.length != 0) { + // input field already there + return; + } + + var td = $(this); + var oldPrefix = td.text(); + var html = ""; + td.html(html); + + // new field generated, has to be looked up + input = $("#" + inputId); + + input.keydown(function(e) { + if (e.keyCode == 27) { + // ESC key pressed + input.off("blur"); + td.html(oldPrefix); + } else if (e.keyCode == 13) { + // enter key pressed + input.trigger("blur"); + } + }); + + input.focus(); + + input.on("blur", function() { + var newPrefix = input.val(); + if (newPrefix == oldPrefix) { + td.html(newPrefix); + } else { + var namespace = td.next().text(); + newPrefixEscaped = escape(newPrefix); + namespaceEscaped = escape(namespace); + var data = keyName + "=" + newPrefixEscaped + "&" + valueName + "=" + namespaceEscaped; + $.ajax({ + url: url, + type: "POST", + async: false, + data: data, + error: function(jqXHR, textStatus, errorThrown) { + vShowAJAXError("Could not update data", jqXHR, errorThrown); + input.focus(); + }, + success: function(data, textSTatus, jqXHR) { + vShowSuccess("Successfully updated data"); + td.html(newPrefix); + } + }); + } + }); + }; + + return f; +} + +/** + * This function is also availble at winery-support-common.js + * This function here is due to legacy reasons and all callers should move to winery-support-common.js + * + * @param qname a QName in the form {namespace}localname + * @return { namespace: namespace, localname: localname } + */ +function getNamespaceAndLocalNameFromQName(qname) { + var i = qname.indexOf("}"); + var res = { + namespace : qname.substr(1,i-1), + localname : qname.substr(i+1) + }; + return res; +} + +/** + * Converts a QName of the form {namespace}id to the form prefix:id + * with a lookup of the prefix in the element + * + * returns wrong data if prefix wsa not found + */ +function getQNameOutOfFullQName(fullQname, element) { + var nsAndId = getNamespaceAndLocalNameFromQName(fullQname); + var prefix = element.lookupPrefix(nsAndId.namespace); + var qname = prefix + ":" + nsAndId.localname; + return qname; +} + +/** + * Converts a QName of the form prefix:id to the form {namespace}id + * with a lookup of the prefix in the element + * + * Currently not used anywhere + */ +function getFullQNameOutOfQName(qname, element) { + var i = qname.indexOf(":"); + var prefix = qname.substr(0,i-1); + var localname = qname.substr(i+1); + var namespace = element.lookupPrefix(prefix); + return "{" + namespace + "}" + localname; +} + +function encodeID(id) { + // the URL sent to the server should be the encoded id + id = encodeURIComponent(id); + // therefore, we have to encode it twice + id = encodeURIComponent(id); + return id; +} + +// URLs from QName are provided by winery-support-common.js +function makeArtifactTemplateURL(repoURL, namespace, id) { + return repoURL + "/artifacttemplates/" + encodeID(namespace) + "/" + encodeID(id) + "/"; +} + +if (!window.winery) window.winery = {}; +window.winery.BOOTSTRAP_ANIMATION_DURATION = 400; diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-sugiyamaLayouter.js b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-sugiyamaLayouter.js new file mode 100644 index 0000000000..fa63f56dde --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-sugiyamaLayouter.js @@ -0,0 +1,634 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Kálmán Képes - initial API and implementation and/or initial documentation + *******************************************************************************/ + +/** + * Implements abstractLayouter#layout and uses the Sugiyama method to apply a + * layered layout for TOSCA Topology Template graphs. The Sugiyama method + * proposes four steps to apply the layout:
    + * First: Remove the cycles temporarly of the given graph by finding edges that + * are members of a cycle and reverse them
    + * Second: Layer the nodes by using DFS/BFS and reduce the "height"/"width" of + * the graph
    + * Third: Reduce the crossings of edges, by applying a suitable heuristic
    + * Fourth: Assign the coordinates for the nodes/edges + * + * @param {Array} + * nodeTemplates, an array with div-elements of class + * ".NodeTemplateShape" + */ +define(function() { + + var module = { + layout: layout + }; + return module; + + function layout(nodeTemplates) { + + + // Step 1: "Remove" Cycles + var hasCycle = _hasCycle(nodeTemplates); + var complementEdgesOfSubgraph = null; + if (hasCycle){ + var edgesOfAcyclicSubgraph = _computeAcyclicSubgraph(nodeTemplates); + complementEdgesOfSubgraph = _computeEdgeComplement(nodeTemplates, + edgesOfAcyclicSubgraph); + _reverseEdges(complementEdgesOfSubgraph); + } + + // Step 2: Assign Layers + _assignLayers(nodeTemplates); + + // Step 3: reduce crossing of edges + _reduceCrossing(nodeTemplates); + + // Step 4: assign coordinates + _assignCoordinates(nodeTemplates); + + if(hasCycle){ + _reverseEdges(complementEdgesOfSubgraph); + } + + jsPlumb.repaintEverything(); + // if used twice, edges are drawn straight and not random + jsPlumb.repaintEverything(); + + // cleanup -> remote internal data + $(nodeTemplates).removeAttr("layer"); + $(nodeTemplates).removeAttr("layerPos"); + + } + + + function callsOnLayout(nodeTemplates) { + // TODO start sugiyama layout method with special handling of calls-on + // relations + } + + /** + * Returns true if the given graph contains a cycle + * @param nodeTemplates the vertices of the graph, where cycle detection should be performed. The vertices should be an array of NodeTemplates + * @returns {Boolean} true iff a cycle was detected in the graph, else false + */ + function _hasCycle(nodeTemplates) { + for(var i = 0; i < nodeTemplates.length;i++){ + nodeTemplates[i].cycleMark = "notStarted"; + } + + var hasCycle = false; + var sources = _returnSources(nodeTemplates); + + for(var i = 0; i < sources.length; i++){ + _cycleSearch(sources[i],hasCycle); + if(hasCycle){ + // remove marks + $(nodeTemplates).removeAttr("cycleMark"); + return hasCycle; + } + } + + return hasCycle; + } + + var tarjanCounter = 1; + + /** + * Detects cycles which are reachable by the given NodeTemplate of a graph. Algorithm is based on DFS + * @param nodeTemplate the starting NodeTemplate for the DFS + * @param hasCycle boolean variable to propagate if a cycle was found, init value should be 'false' + */ + function _cycleSearch(nodeTemplate,hasCycle){ + if(nodeTemplate.cycleMark = "inWork"){ + hasCycle =true; + } else if(nodeTemplate.cycleMark ="notStarted") { + nodeTemplate.cycleMark ="inWork"; + var successors = _returnSuccessors(nodeTemplate); + for(var i = 0 ; i < successors.length; i++){ + _cycleSearch(successors[i]); + } + nodeTemplate.cycleMark ="finished"; + } + + } + + /** + * Calculates strongly connected components according to Tarjans algorithm + * @param nodeTemplate a NodeTemplate that is used to begin the algorithm on + * @param foundCycle boolean variable to propagate if a cycle was found, init value should be 'false' + */ + function _findComponent(nodeTemplate, foundCycle){ + if(nodeTemplate.cycleMark == "inWork"){ + foundCycle = true; + } else if(nodeTemplate.cycleMark == "notStarted"){ + nodeTemplate.cycleMark = "inWork"; + nodeTemplate.dfsNum = tarjanCounter; + nodeTemplate.compNum = tarjanCounter; + tarjanCounter++; + var successors = _returnSuccessors(nodeTemplate); + for(var i = 0; i < successors.length;i++){ + var successor = successors[i]; + if(successor.cycleMark != "finished"){ + _findComponent(successor,foundCycle); + if(successor.compNum < nodeTemplate.compNum){ + nodeTemplate.compNum = successor.compNum; + } + } + } + nodeTemplate.cycleMark = "finished"; + } + } + + /** + * Assigns x/y-Coordinates to the given NodeTemplates. It is assumed that the + * NodeTemplates are already layered, e.g. nodeTemplate.layer, + * nodeTemplate.layerPos is set. + * + * @param nodeTemplates + * the nodetemplate to set it's x/y coordinates + */ + function _assignCoordinates(nodeTemplates) { + // get the layers out of the graph and the number of layers + var highestLayerNumber = _returnHighestLayerNumber(nodeTemplates); + var layerMap = {}; + for ( var i = 1; i <= highestLayerNumber; i++) { + layerMap[i.toString()] = _returnLayer(nodeTemplates, i); + } + + // determine the layer with the greatest width, width = {max(|U|) : U is + // layer of V} + var widestLayerWidth = -1; + for (layer in layerMap) { + if (layer.length > widestLayerWidth) { + widestLayerWidth = layer.length; + } + } + + // get maximum node width + var maxNodeWidth = _getMaxWidthOfNodeArray(nodeTemplates); + + // get maximum node height + var maxNodeHeight = _getMaxHeightOfNodeArray(nodeTemplates); + + var editorArea = $("#editorArea")[0]; + var height = editorArea.clientHeight; + var width = editorArea.clientWidth; + + // TODO fine tuning or change the algorithm to handle callsOn Relations + // independently, e.g. draw it in an own tree/list/graph + // distance in height between nodes + var prettyHeight = 75; + for ( var i = highestLayerNumber; i > 0; i--) { + var layer = _returnLayer(nodeTemplates, i); + // distance in width between nodes + var prettyWidth = 75; + for ( var nodeIndex = 0; nodeIndex < layer.length; nodeIndex++) { + var layerNumber = i; + var layerPos = layer[nodeIndex].layerPos; + layer[nodeIndex].style.left = ((layerPos) * maxNodeWidth + prettyWidth) + + "px"; + layer[nodeIndex].style.top = ((highestLayerNumber - layerNumber) + * maxNodeHeight + prettyHeight) + + "px" + prettyWidth += 50; + } + prettyHeight += 100; + } + } + + /** + * Returns the height of the nodeTemplate with the highest height + * @param nodeTemplates an array of NodeTemplates + * @returns {Number} the maximum height of the given NodeTemplates + */ + function _getMaxHeightOfNodeArray(nodeTemplates) { + var maxHeight = -1; + for ( var i = 0; i < nodeTemplates.length; i++) { + // TODO clientHeight responds to the complete page, not only the + // nodetemplate + if (maxHeight < nodeTemplates[i].clientHeight) { + maxHeight = nodeTemplates[i].clientHeight; + } + } + return maxHeight; + } + + /** + * Returns the width of the nodeTemplate with the highest width + * @param nodeTemplates an array of NodeTemplates + * @returns {Number} the maximum width of the given NodeTemplates + */ + function _getMaxWidthOfNodeArray(nodeTemplates) { + var maxWidth = -1; + for ( var i = 0; i < nodeTemplates.length; i++) { + // TODO clientWidth responds to the complete page, not only the + // nodetemplate + if (maxWidth < nodeTemplates[i].clientWidth) { + maxWidth = nodeTemplates[i].clientWidth; + } + } + return maxWidth; + } + + /** + * Reduces crossing between the already layered Graph, given as a Array of NodeTemplates + * @param nodeTemplates the vertices of the layered graph, to reduce crossing between the layers + */ + function _reduceCrossing(nodeTemplates) { + // initialize arbitrary orderings inside layers + _initLayerOrder(nodeTemplates); + var maxlayerlevel = _returnHighestLayerNumber(nodeTemplates); + // variable to reduce crossings of layer-pairs one by one + var layerCount = 1; + // variable to check if some change was made + var changed = true; + while (layerCount < maxlayerlevel | changed) { + // the algorithm should run until no position changes are made + if (layerCount == maxlayerlevel) { + layerCount = 1; + } + changed = false; + + var layer = _returnLayer(nodeTemplates, layerCount + 1); + + // INFO: This piece of code reduces the corssing according to the + // barycenter heuristic + for ( var i = 0; i < layer.length; i++) { + // deg(u), where u = layer[i] + var deg_u = _returnIncomingEdges(layer[i]).length + + _returnOutgoingEdges(layer[i]).length; + + // sum of layerpos(v), for ever v where (u,v) exists in the graph + var outgoingEdges = _returnOutgoingEdges(layer[i]); + var sum = 0.0; + for ( var j = 0; j < outgoingEdges.length; j++) { + var node_v = outgoingEdges[j].target; + sum = sum + node_v.layerPos; + } + + // barycenter heuristic + var bary_u = 1 / deg_u * sum; + layer[i].barycenter = bary_u; + } + + // sorting the nodetemplates in the layer accorindg to the barycenter + layer.sort(function(a, b) { + return a.barycenter - b.barycenter + }); + + // rearrange positions in layer + for ( var i = 0; i < layer.length; i++) { + if (layer[i].layerPos != i + 1) { + // checks whether some change of the position is made + changed = true; + } + layer[i].layerPos = i + 1; + } + + // get ready for the next layer + layerCount++; + } + } + + /** + * Returns an array of NodeTemplates which are in the same Layer (nodeTemplate.layer) + */ + function _returnLayer(nodeTemplates, layerNumber) { + var layer = new Array(); + for ( var i = 0; i < nodeTemplates.length; i++) { + if ("layer" in nodeTemplates[i] + && nodeTemplates[i].layer == layerNumber) { + layer.push(nodeTemplates[i]); + } + } + layer.sort(function(a, b) { + return a.layerPos - b.layerPos; + }); + return layer; + } + + /** + * Returns the number of the highest layer of the given layered graph + * @param nodeTemplates the vertices of the layered graph as an array of NodeTemplates + * @returns {Number} the highest layer number + */ + function _returnHighestLayerNumber(nodeTemplates) { + var layerNumber = -1; + for ( var i = 0; i < nodeTemplates.length; i++) { + if (!"layer" in nodeTemplates[i]) { + // some node has no "layer" property defined <=> graph isn't layered + return -1; + } else { + if (nodeTemplates[i].layer > layerNumber) { + layerNumber = nodeTemplates[i].layer; + } + } + } + return layerNumber; + } + + /** + * Initializes a layering order in each layer of the given graph + * @param nodeTemplates the vertices of the graph to layer, as an array of NodeTemplates + */ + function _initLayerOrder(nodeTemplates) { + // "map" := layerNumber : ordernumber + var orderingCount = {}; + // init with 1 : 1 + orderingCount["1"] = 1; + for ( var i = 0; i < nodeTemplates.length; i++) { + // get layer number of the nodetemplate + var layerNumber = nodeTemplates[i].layer; + // is the layer already in the map ? + if (layerNumber.toString() in orderingCount) { + // if yes, set the pos inside layer and increment for next node + nodeTemplates[i].layerPos = orderingCount[layerNumber.toString()]; + orderingCount[layerNumber.toString()] = orderingCount[layerNumber + .toString()] + 1; + } else { + // if not, set the pos to 1 and add layer to map with count 2 + nodeTemplates[i].layerPos = 1; + // init pos for next node + orderingCount[layerNumber.toString()] = 2; + } + } + } + + /** + * Assigns layer numbers to the given graph + * @param nodeTemplates the vertices of the graph to assign layers to, as an array of NodeTemplates + */ + function _assignLayers(nodeTemplates) { + var sinks = {}; + for ( var i = 0; i < nodeTemplates.length; i++) { + if (_returnOutgoingEdges(nodeTemplates[i]).length == 0) { + sinks[i] = nodeTemplates[i]; + } + } + + // array of DIV delements + var nodesToCompute = new Array(); + + for ( var sink in sinks) { + // set layer level for the sinks and add the nodes which are reachable + // from there + sinks[sink].layer = 1; + var inEdges = _returnIncomingEdges(sinks[sink]); + for ( var i = 0; i < inEdges.length; i++) { + nodesToCompute.push(inEdges[i].source); + } + } + + // set other layer levels + while (nodesToCompute.length != 0) { + var node = nodesToCompute.shift(); + var layerNumber = _returnLayerNumber(node); + if (layerNumber == -1) { + nodesToCompute.push(node); + } else { + node.layer = layerNumber; + // add ingoing nodes to compute + var edgesToNodes = _returnIncomingEdges(node); + for ( var i = 0; i < edgesToNodes.length; i++) { + nodesToCompute.push(edgesToNodes[i].source); + } + } + } + } + + /** + * Returns the number of the layer a NodeTemplate belongs to + * @param nodeTemplate a NodeTemplate with already set layer position + * @returns {Number} the number of the layer the NodeTemplate belongs to + */ + function _returnLayerNumber(nodeTemplate) { + var layerNumber = -1; + var outgoingEdges = _returnOutgoingEdges(nodeTemplate); + for ( var i = 0; i < outgoingEdges.length; i++) { + // we will see if it works here + var successorNode = outgoingEdges[i].target; + if ("layer" in successorNode) { + if (successorNode.layer + 1 >= layerNumber) { + layerNumber = successorNode.layer + 1; + } + } else { + layerNumber = -1; + break; + } + } + return layerNumber; + } + + /** + * Returns all jsPlumb#Connection edges of the graph represented by the + * nodeTemplates array of NodeTemplateShape which aren't referenced in the + * subgraphEdges array of type jsPlumb#Connection. + * + * @param {Object} + * nodeTemplates, array of NodeTemplateShape + * @param {Object} + * subgraphEdges, array of jsPlumb#Connection + * @return {Object} array of jsPlumb#Connection which contains edges that aren't + * in the subgraph + */ + function _computeEdgeComplement(nodeTemplates, subgraphEdges) { + var edgeSet = {}; + for ( var i = 0; i < nodeTemplates.length; i++) { + var incomingEdges = _returnIncomingEdges(nodeTemplates[i]); + var outgoingEdges = _returnOutgoingEdges(nodeTemplates[i]); + for ( var incomingEdgeIndex = 0; incomingEdgeIndex < incomingEdges.length; incomingEdgeIndex++) { + var inSubgraph = false; + for ( var subgraphEdgeIndex = 0; subgraphEdgeIndex < subgraphEdges.length; subgraphEdgeIndex++) { + if (incomingEdges[incomingEdgeIndex] === subgraphEdges[subgraphEdgeIndex]) { + inSubgraph = true; + break; + } + } + if (!inSubgraph) { + edgeSet[incomingEdges[incomingEdgeIndex]] = incomingEdges[incomingEdgeIndex]; + } + } + for ( var outgoingEdgeIndex = 0; outgoingEdgeIndex < outgoingEdges.length; outgoingEdgeIndex++) { + var inSubgraph = false; + for ( var subgraphEdgeIndex = 0; subgraphEdgeIndex < subgraphEdges.length; subgraphEdgeIndex++) { + if (outgoingEdges[outgoingEdgeIndex] === subgraphEdges[subgraphEdgeIndex]) { + inSubgraph = true; + break; + } + } + if (!inSubgraph) { + edgeSet[outgoingEdges[outgoingEdgeIndex]] = outgoingEdges[outgoingEdgeIndex]; + } + } + } + // transform edge-set to array + var edgeArray = new Array(); + for (edge in edgeSet) { + edgeArray.push(edgeSet[edge]); + } + return edgeArray; + } + + /** + * Returns a list of edges which represent an acyclic subgraph of the given + * nodes. The graph is at least of size 1/2*|E|, which can be troublesome in + * some situations. This means the graph could be layouted only on the "half" of + * it. + * + * Info: There are more sophisticated methods that guarantee to produce bigger + * subgraphs, see "Drawing Graphs: Methods and Models". But in this state it is + * a huge undertake, cause Oryx doesn't seem to have any basic graph algorithm + * shipped, like DFS etc.(correct me if i'm wrong, please). + * + * @param {Object} + * nodes of a graph, which are NodeTemplatesShapes + * @return [Object] edges of the contained acyclic subgraph, which are + * jsPlumb#Connection Objects + * @see "Drawing Graphs: Methods and Models", p. 91 + */ + function _computeAcyclicSubgraph(nodeTemplates) { + var subgraphEdges = []; + for ( var i = 0; i < nodeTemplates.length; i++) { + if (_returnOutgoingEdges(nodeTemplates[i]).length >= _returnIncomingEdges(nodeTemplates[i]).length) { + for ( var j = 0; j < _returnOutgoingEdges(nodeTemplates[i]).length; j++) { + subgraphEdges.push(_returnOutgoingEdges(nodeTemplates[i])[j]); + } + } else { + for ( var j = 0; j < _returnIncomingEdges(nodeTemplates[i]).length; j++) { + subgraphEdges.push(_returnIncomingEdges(nodeTemplates[i])[j]); + } + } + } + var filteredArray = subgraphEdges.filter(function(elem, pos) { + return subgraphEdges.indexOf(elem) == pos; + }); + return filteredArray; + } + + /** + * Returns relations having the given NodeTemplate as target + * + * @param nodeTemplate + * a nodeTemplateShape + * @returns Returns an array containing jsPlumb#Connection objects representing + * relations + */ + function _returnIncomingEdges(nodeTemplate) { + var edgeArray = new Array(); + jsPlumb.select().each( + function(connection) { + if (connection.targetId === nodeTemplate.id) { + /*if (connection.getType().length != 0) { + for ( var i = 0; i < connection.getType().length; i++) { + if (connection.getType()[i].toLowerCase().indexOf( + "hostedon") !== -1) { + edgeArray.push(connection); + } + } + } else { + edgeArray.push(connection); + }*/ + edgeArray.push(connection); + + } + }); + return edgeArray; + } + + /** + * Returns relations having the given NodeTemplate as source + * + * @param nodeTemplate + * a nodeTemplateShape + * @returns Returns an array containing jsPlumb#Connections objects representing + * relations + */ + function _returnOutgoingEdges(nodeTemplate) { + var edgeArray = new Array(); + jsPlumb.select().each( + function(connection) { + if (connection.sourceId === nodeTemplate.id) { + /*if (connection.getType().length != 0) { + for ( var i = 0; i < connection.getType().length; i++) { + if (connection.getType()[i].toLowerCase().indexOf( + "hostedon") !== -1) { + edgeArray.push(connection); + } + } + } else { + edgeArray.push(connection); + }*/ + edgeArray.push(connection); + } + }); + return edgeArray; + } + + /** + * Returns the NodeTemplates which can be reached by a outgoing edges of the given NodeTemplate + * @param nodeTemplate the NodeTemplate whose Succesors should be calculated + * @returns {Array} an array of NodeTemplates which are successors of the given NodeTemplate, may be empty + */ + function _returnSuccessors(nodeTemplate){ + var nodeArray = new Array(); + var outgoingEdges = _returnOutgoingEdges(nodeTemplate); + for(var i =0; i < outgoingEdges.length; i++){ + nodeArray.push(outgoingEdges[i].target); + } + return nodeArray; + } + + /** + * Returns all sources of the given graph + * @param nodeTemplates vertices of the graph, as an array of NodeTemplates + * @returns {Array} an Array of NodeTemplates + */ + function _returnSources(nodeTemplates){ + var sourceArray = new Array(); + for(var i = 0; i < nodeTemplates.length; i++){ + if(_returnIncomingEdges(nodeTemplates[i]) == 0){ + sourceArray.push(nodeTemplates[i]); + } + } + return sourceArray; + } + + /** + * Reverses a relationshipTemplate + * + * @param relationshipTemplate + * as we don't have relationshiptemplates modelled here we expect + * jsPlumb#Connection objects + */ + function _reverseEdge(relationshipTemplate) { + // this seems to work + var source = relationshipTemplate["source"]; + var sourceId = relationshipTemplate["sourceId"]; + var target = relationshipTemplate["target"]; + var targetId = relationshipTemplate["targetId"]; + + relationshipTemplate["source"] = target; + relationshipTemplate["sourceId"] = targetId; + relationshipTemplate["target"] = source; + relationshipTemplate["targetId"] = sourceId; + } + + /** + * Reverses relationshipTemplates + * + * @param relationshipTemplates + */ + function _reverseEdges(relationshipTemplates) { + for ( var i = 0; i < relationshipTemplates.length; i++) { + _reverseEdge(relationshipTemplates[i]); + } + } +}); \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-support-common.js b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-support-common.js new file mode 100644 index 0000000000..4e87f22ef7 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-support-common.js @@ -0,0 +1,330 @@ +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ + +/** + * Functions copied from winery-common.js to replace it in the long term + * + * Shared between topology modeler and repository + */ +define([], function() { + var xmlParser = new DOMParser(); + var VALUE_OF_NONE_CHOOSEN = "(none)"; // constant to indicate that nothing is chosen in a select2 + + return { + encodeId: encodeId, + getNamespaceAndLocalNameFromQName: getNamespaceAndLocalNameFromQName, + replaceDialogShownHookForOrionUpdate: replaceDialogShownHookForOrionUpdate, + writeCollectionDefinedByATextArea: writeCollectionDefinedByATextArea, + getDocument: getDocument, + + getURLFragmentOutOfFullQName: getURLFragmentOutOfFullQName, + makeArtifactTypeURLFromQName: makeArtifactTypeURLFromQName, + makeNodeTypeURLFromQName: makeNodeTypeURLFromQName, + makeRelationshipTypeURLFromQName: makeRelationshipTypeURLFromQName, + makeRelationshipTypeURLFromNSAndLocalName: makeRelationshipTypeURLFromNSAndLocalName, + + qname2href: qname2href, + + fetchSelect2DataAndInitSelect2: fetchSelect2DataAndInitSelect2, + removeItemFromSelect2Field: removeItemFromSelect2Field, + + checkXMLValidityAndShowErrorIfInvalid: checkXMLValidityAndShowErrorIfInvalid, + synchronizeNameAndType: synchronizeNameAndType, + + VALUE_OF_NONE_CHOOSEN: VALUE_OF_NONE_CHOOSEN + }; + + /** + * OriginalName: encodeID + */ + function encodeId(id) { + // the URL sent to the server should be the encoded id + id = encodeURIComponent(id); + // therefore, we have to encode it twice + id = encodeURIComponent(id); + return id; + } + + /** + * @param qname a QName in the form {namespace}localname + * @return { namespace: namespace, localname: localname } + */ + function getNamespaceAndLocalNameFromQName(qname) { + var i = qname.indexOf("}"); + var res = { + namespace : qname.substr(1,i-1), + localname : qname.substr(i+1) + }; + return res; + } + + /** + * Orion does not update content if field not fully shown + * therefore, we hook in into the "shown" event + */ + function replaceDialogShownHookForOrionUpdate(diag, orionAreaId, content) { + diag.off("shown.bs.modal"); + diag.on("shown.bs.modal", function() { + var area = window.winery.orionareas[orionAreaId]; + area.editor.setText(content); + area.fixEditorHeight(); + }); + } + + function getURLFragmentOutOfNSAndLocalName(nsAndLocalName) { + var res; + res = encodeID(nsAndLocalName.namespace); + res = res + "/"; + res = res + encodeID(nsAndLocalName.localname); + return res; + } + + /** + * Extracts an URL fragment of the form / out of a full QName + * + * @param qname a QName in the form {namespace}localname + */ + function getURLFragmentOutOfFullQName(qname) { + var d = getNamespaceAndLocalNameFromQName(qname); + return getURLFragmentOutOfNSAndLocalName(d); + } + + /** + * @param w the XMLwriter + * @param elementSet the set of HTML elements to write + * @param elementName the name of the wrapper element (e.g., "Requirements", "Policies") + */ + function writeCollectionDefinedByATextArea(w, elementSet, elementName) { + if (elementSet.length !== 0) { + w.writeStartElement(elementName); + elementSet.each(function(i, element) { + // XML contains element completely + // we do not have to parse reqorcap.children("div.id").children("span.id").text() or the span.name + var text = $(element).children("textarea").val(); + w.writeXML(text); + }); + w.writeEndElement(); + } + } + + function makeArtifactTypeURLFromQName(repoURL, qname) { + return repoURL + "/artifacttypes/" + getURLFragmentOutOfFullQName(qname) + "/"; + } + + function makeNodeTypeURLFromQName(repoURL, qname) { + return repoURL + "/nodetypes/" + getURLFragmentOutOfFullQName(qname) + "/"; + } + + function makeRelationshipTypeURLFromQName(repoURL, qname) { + return repoURL + "/relationshiptypes/" + getURLFragmentOutOfFullQName(qname) + "/"; + } + + function makeRelationshipTypeURLFromNSAndLocalName(repoURL, nsAndLocalName) { + return repoURL + "/relationshiptypes/" + getURLFragmentOutOfNSAndLocalName(nsAndLocalName) + "/"; + } + + /** + * functionality similar to org.eclipse.winery.common.Util.qname2href(String, Class, QName) + */ + function qname2href(repositoryUrl, componentPathFragment, qname) { + var nsAndId = getNamespaceAndLocalNameFromQName(qname); + var absoluteURL = repositoryUrl + "/" + componentPathFragment + "/" + getURLFragmentOutOfNSAndLocalName(nsAndId); + var res = "" + nsAndId.localname + ""; + return res; + } + + /** + * Inspired by + * + * @param field is the jquery field + * @param id_to_remove the id to remove + */ + function removeItemFromSelect2Field(field, id_to_remove) { + // nothing can be done currently + // see https://github.com/ivaynberg/select2/issues/535#issuecomment-30210641 for a disucssion + vShowNotification("The select field shows stale data. Refresh the page to get rid of that.") + } + + /** + * Fetches select2 data from the given URL and initializes the field provided by the fieldId + * + * Calls vShowError if something went wrong + * + * @param onSuccess (optional) + * @param allowAdditions (optional) if set to true, select2 is initalized with the functionality to allow additions during the search + */ + function fetchSelect2DataAndInitSelect2(fieldId, url, onSuccess, allowAdditions) { + $.ajax({ + url: url, + dataType: "json" + }).done(function (result) { + var params = {"data": result}; + if (typeof allowAdditions === "boolean") { + params.createSearchChoice = function(term) { + // enables creation of new namespaces + return {id:term, text:term}; + } + } + + // init select2 and select first item + $("#" + fieldId).select2(params); + if (result.length === 0) { + $("#" + fieldId).select2("val", null); + } else { + $("#" + fieldId).select2("val", result[0].id); + } + + if (typeof onSuccess === "function") { + onSuccess(); + } + }).fail(function(jqXHR, textStatus, errorThrown) { + vShowAJAXError("Could not fetch select2 data from " + url, jqXHR, errorThrown); + }); + + } + + + function getDocument(xmlString) { + var xmlDoc = xmlParser.parseFromString(xmlString, "text/xml"); + return xmlDoc; + } + + /** + * Checks given XML string for validity. If it's invalid, an error message is shown + * Relies on the current browser's XML handling returning a HTML document if something went wrong during parsing + * + * @return XMLdocument if XML is valid, false otherwise + */ + function checkXMLValidityAndShowErrorIfInvalid(xmlString) { + var doc = getDocument(xmlString); + var errorMsg = ""; + if (doc.firstChild.localName == "html") { + errorMsg = new XMLSerializer().serializeToString(doc); + } else { + // at Chrome, the error may be nested in the XML + + // quick hack, only "xhtml" is quered + function nsResolover(x) { + return "http://www.w3.org/1999/xhtml"; + } + + var element = doc.evaluate( '//x:parsererror', doc, nsResolover, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; + if (element !== null) { + errorMsg = new XMLSerializer().serializeToString(element); + } + } + + if (errorMsg !== "") { + vShowError(errorMsg); + return false; + } else { + return doc; + } + } + + /** + * Updates the XML in the orion editor based on the values given in the input fields. + * Shows error if XML is invalid + * + * Works only with SELECT2 fields + * + * @param idPrefix: (new|edit)${shortName}, derived names: [idPrefix]Name, [idPrefix]Id, Orion[idPrefix]XML + * @param hasIdField: whether the Id should be read and written + * @param selectFields: array of {attribute, fieldSuffix}, where attribute is a name of an attribute having a QName. + * Each select box is determined by #[idPrefix][fieldSuffix]. + * The select box content is converted to a QName and the result is written to the attribute [name] + * Default: {attribute: "type", fieldSuffix: "Type"} + * + * @return false if XML is invalid, true: an object if id/name/attribute1/attribute2/... (qname + attribute1FullQName: qname object)/xml (to be used in tmpl-${cssClassPrefix}) + * {id:id, name:name, type: "ns5:type", typeFullQName: "{http://www.example.org}type"} + */ + function synchronizeNameAndType(idPrefix, hasIdField, selectFields) { + if (typeof hasIdField === undefined) { + hasIdField = true; + } + if (typeof selectFields === undefined) { + selectFields = [{attribute: "type", fieldSuffix: "Type"}]; + } + + + var val = window.winery.orionareas["Orion" + idPrefix + "XML"].editor.getText(); + var xmlDoc = checkXMLValidityAndShowErrorIfInvalid(val); + if (xmlDoc) { + // handle name + var name = $("#" + idPrefix + "Name").val(); + // initialize result object + var res = { + name: name + }; + xmlDoc.firstChild.setAttribute("name", name); + + // write id and name to XML + if (hasIdField) { + var id = $("#" + idPrefix + "Id").val(); + if (!id) { + // TODO a checking should be done if the id exists + // probably not here, but at caller's side + id = name; + } + xmlDoc.firstChild.setAttribute("id", id); + res.id = id; + } + + // write each selectField to xml + // for that, we have to determine the QName + $(selectFields).each(function(i, m) { + var content = $("#" + idPrefix + m.fieldSuffix).select2("val"); + + if (content == VALUE_OF_NONE_CHOOSEN) { + // if nothing is chosen do not put it into the result + return; + } + + // determine qname of type + //getQNameOutOfFullQName(type, xmlDoc.firstChild) does not always work as xmlDoc.firstChild does not have ALL *available* namespace prefixes + var typeNSAndId = getNamespaceAndLocalNameFromQName(content); + var prefix = xmlDoc.firstChild.lookupPrefix(typeNSAndId.namespace); + if (!prefix) { + // we have to ask the repo for a prefix + $.ajax({ + type: "GET", + async: false, + "url": winery.repositoryURL + "/admin/namespaces/" + encodeID(typeNSAndId.namespace), + dataType: "text", + error: function(jqXHR, textStatus, errorThrown) { + vShowAJAXError("Could not determine prefix", jqXHR, errorThrown); + }, + success: function(resData, textStatus, jqXHR) { + prefix = resData; + } + }); + // new prefix fetched, xmlns attribute has to be written + xmlDoc.firstChild.setAttribute("xmlns:" + prefix, typeNSAndId.namespace); + } + var qname = prefix + ":" + typeNSAndId.localname; + res[m.attribute] = qname; + res[m.attribute + "FullQName"] = typeNSAndId; + xmlDoc.firstChild.setAttribute(m.attribute, qname); + }); + + var xml = new XMLSerializer().serializeToString(xmlDoc); + res.xml = xml; + + return res; + } else { + return false; + } + } + + + } +); diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-topologymodeler-AMD.js b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-topologymodeler-AMD.js new file mode 100644 index 0000000000..eb6a62580a --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-topologymodeler-AMD.js @@ -0,0 +1,208 @@ +/******************************************************************************* + * Copyright (c) 2012-2014 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + *******************************************************************************/ + +/** + * This file contains supporting functions for the topoplogy modeler + */ +define( + // although XMLWriter ist not an AMD module, requirejs does not complain when loading it + ["winery-support-common", "XMLWriter"], + function (w) { + // has to be consistent with {@link org.eclipse.winery.common.constants.Namespaces} + var TOSCA_NAMESPACE = "http://docs.oasis-open.org/tosca/ns/2011/12"; + var TOSCA_WINERY_EXTENSIONS_NAMESPACE ="http://www.opentosca.org/winery/extensions/tosca/2013/02/12"; + + var topologyTemplateURL; + + var module = { + save: save, + setTopologyTemplateURL: function(url) { + topologyTemplateURL = url; + }, + + TOSCA_NAMESPACE: TOSCA_NAMESPACE, + TOSCA_WINERY_EXTENSIONS_NAMESPACE: TOSCA_WINERY_EXTENSIONS_NAMESPACE + }; + return module; + + function writeReqOrCaps(elements, xmlw, globalWrapperElementName, singleElementWrapperName) { + if (elements.length != 0) { + xmlw.writeStartElement(globalWrapperElementName); + + $.each(elements, function(i,e) { + xmlw.writeStartElement(singleElementWrapperName); + e = $(e); + xmlw.writeAttributeString("id", e.children(".id").text()); + xmlw.writeAttributeString("name", e.children(".name").text()); + writeType(xmlw, e.children(".type").children("a").data("qname")); + savePropertiesFromDivToXMLWriter(e.children("div.propertiesContainer"), xmlw); + xmlw.writeEndElement(); + }); + + xmlw.writeEndElement(); + } + + } + + /** + * "doSave" + */ + function save() { + $("#saveBtn").button('loading'); + var xmlw = new XMLWriter("utf-8"); + xmlw.writeStartDocument(); + xmlw.writeStartElement("TopologyTemplate"); + xmlw.writeAttributeString("xmlns", TOSCA_NAMESPACE); + xmlw.writeAttributeString("xmlns:winery", TOSCA_WINERY_EXTENSIONS_NAMESPACE); + $("div.NodeTemplateShape").not(".hidden").each (function() { + xmlw.writeStartElement("NodeTemplate"); + + var id = $(this).attr("id"); + + var headerContainer = $(this).children("div.headerContainer"); + var name = headerContainer.children("div.name").text(); + var typeQNameStr = headerContainer.children("span.typeQName").text(); + var minmaxdiv = headerContainer.children("div.minMaxInstances"); + var min = minmaxdiv.children("span.minInstances").text(); + var max = minmaxdiv.children("span.maxInstances").text(); + if (max == "∞") { + max = "unbounded"; + } + var x = $(this).css("left"); + x = x.substring(0, x.indexOf("px")); + var y = $(this).css("top"); + y = y.substring(0, y.indexOf("px")); + + xmlw.writeAttributeString("id", id); + if (name != "") { + xmlw.writeAttributeString("name", name); + } + writeType(xmlw, typeQNameStr); + if (min != "") { + xmlw.writeAttributeString("minInstances", min); + } + if (max != "") { + xmlw.writeAttributeString("maxInstances", max); + } + xmlw.writeAttributeString("winery:x", x); + xmlw.writeAttributeString("winery:y", y); + + /** Properties **/ + savePropertiesFromDivToXMLWriter($(this).children("div.propertiesContainer"), xmlw); + + /** Requirements **/ + writeReqOrCaps( + $(this).children("div.requirementsContainer").children("div.content").children("div.reqorcap"), + xmlw, + "Requirements", + "Requirement"); + + /** Capabilities **/ + writeReqOrCaps( + $(this).children("div.capabilitiesContainer").children("div.content").children("div.reqorcap"), + xmlw, + "Capabilities", + "Capability"); + + /** Policies **/ + w.writeCollectionDefinedByATextArea(xmlw, + $(this).children("div.policiesContainer").children("div.content").children("div.policy"), + "Policies"); + + /** Deployment Artifacts **/ + // DAs do not store all data in the HTML, a global JavaScript variable is also used + var das = $(this).children("div.deploymentArtifactsContainer").children("div.content").children("div.deploymentArtifact"); + if (das.length != 0) { + xmlw.writeStartElement("DeploymentArtifacts"); + das.each(function(i,e) { + // the textarea contains a valid deployment artifact xml + var xml = $(e).children("textarea").val(); + xmlw.writeXML(xml); + }); + xmlw.writeEndElement(); + } + + // End: Nodetemplate + xmlw.writeEndElement(); + }); + jsPlumb.select().each(function(connection) { + xmlw.writeStartElement("RelationshipTemplate"); + var id = connection.id; + var typeQNameStr = connection.getType()[0]; + + var connData = winery.connections[id]; + if (!connData) { + vShowError("Error in the internal data structure: Id " + id + " not found"); + return; + } + + xmlw.writeAttributeString("id", connData.id); + if (connData.name != "") { + xmlw.writeAttributeString("name", connData.name); + } + writeType(xmlw, typeQNameStr); + + if (typeof connData.propertiesContainer !== "undefined") { + savePropertiesFromDivToXMLWriter(connData.propertiesContainer, xmlw); + } + + xmlw.writeStartElement("SourceElement"); + if (connData.req) { + // conn starts at a requirement + xmlw.writeAttributeString("ref", connData.req); + } else { + // conn starts at a node template + xmlw.writeAttributeString("ref", connection.sourceId); + } + xmlw.writeEndElement(); + xmlw.writeStartElement("TargetElement"); + if (connData.cap) { + // conn ends at a capability + xmlw.writeAttributeString("ref", connData.cap); + } else { + // conn ends at a node template + xmlw.writeAttributeString("ref", connection.targetId); + } + xmlw.writeEndElement(); + + xmlw.writeEndElement(); + }); + xmlw.writeEndDocument(); + $.ajax({ + url: topologyTemplateURL, + type: "PUT", + contentType: 'text/xml', + data: xmlw.flush(), + success: function(data, textStatus, jqXHR) { + $("#saveBtn").button('reset'); + vShowSuccess("successfully saved."); + }, + error: function(jqXHR, textStatus, errorThrown) { + $("#saveBtn").button('reset'); + vShowAJAXError("Could not save", jqXHR, errorThrown); + } + }); + } + + function writeQNameAttribute(w, nsPrefix, qnameStr) { + var qname = getQName(qnameStr); + w.writeAttributeString("xmlns:" + nsPrefix, qname.namespace); + w.writeAttributeString("type", nsPrefix + ":" + qname.localName); + } + + function writeType(w, typeQNameStr) { + writeQNameAttribute(w, "ty", typeQNameStr); + } + + } +); + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-topologymodeler.js b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-topologymodeler.js new file mode 100644 index 0000000000..a38c13f965 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/js/winery-topologymodeler.js @@ -0,0 +1,309 @@ +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ + +function getQName(qnameStr) { + var pos = qnameStr.indexOf("}"); + var namespace = qnameStr.substring(1, pos); + var localName = qnameStr.substring(pos+1); + var res = { + "namespace": namespace, + "localName": localName + }; + return res; +} + +/** + * @param attributeName an attribute with a value in the form prefix:localname + * @param xmlElement a DOM element (offering the method lookupNamespaceURI) + * @return { ns: namespace, id: id } + */ +function getNSAndId(attributeName, xmlElement) { + var attributeValue = xmlElement.getAttribute(attributeName); + var i = attributeValue.indexOf(":"); + var prefix = attributeValue.substring(0, i); + var localName = attributeValue.substring(i+1); + var ns = xmlElement.lookupNamespaceURI(prefix); + var res = { + ns : ns, + id: localName + }; + return res; +} + +/** + * @param el a href element + * @param pathComponent the path element "artifacttemplates" or "artifacttypes" + * @param attributeName the name of the attribute to read from the given xmlElement + * @param xmlElement used to resolve a namespace prefix to a full namespace URI + */ +function addHref(el, pathComponent, attributeName, xmlElement) { + var nsAndId = getNSAndId(attributeName, xmlElement); + var loc = winery.repositoryURL + "/" + pathComponent + "/" + encodeID(nsAndId.ns) + "/" + encodeID(nsAndId.id); + el.attr("href", loc); +} + +var currentlySelectedDeploymentArtifactDiv; + +/** + * Sets global variables currentlySelectedNodeTemplate and currentlySelectedDeploymentArtifactDiv + */ +function showDeploymentArtifactInformation(nodeTemplateId, deploymentArtifactName) { + currentlySelectedNodeTemplate = nodeTemplateId; + var daDiv = $("#" + nodeTemplateId).children("div.deploymentArtifactsContainer").children("div.content").children("div.deploymentArtifact").children("div.name:contains(" + deploymentArtifactName + ")").parent(); + currentlySelectedDeploymentArtifactDiv = daDiv; + var xml = daDiv.children("textarea").val(); + + // get values to display directly from the "UI" instead of parsing the XML and asking the server for appropriate names + var daArtifactTemplateName = daDiv.children("div.artifactTemplate").text(); + var daArtifactTypeName = daDiv.children("div.artifactType").text(); + + // determine URLs + require(["winery-support-common"], function(wsc) { + xmlDoc = wsc.getDocument(xml); + da = xmlDoc.firstChild; + + $("#DAname").text(deploymentArtifactName); + + $("#DAArtifactType").text(daArtifactTypeName); + addHref($("#DAArtifactType"), "artifacttypes", "artifactType", da); + + var at = $("#DAArtifactTemplate"); + if (daArtifactTemplateName != "") { + at.text(daArtifactTemplateName); + addHref(at, "artifacttemplates", "artifactRef", da); + } else { + at.text("No template associated"); + at.removeAttr("href"); + } + + $("#DAXML").val(xml); + + $("#DeploymentArtifactInfo").modal("show"); + }); +} + +/** + * Adds the given data to the deployment artifacts table of the currently active node template + * + * @param xmlAsDOM XML DOM document, TDeploymentArtifact. Produced by org.eclipse.winery.resources.artifacts.GenericArtifactsResource.onPost(String, String, String, String, String, String, String, String) + * @param xmlAsString + */ +function addDeploymentArtifact(xmlAsDOM, xmlAsString) { + var da = xmlAsDOM.firstChild; + var daName = da.getAttribute("name"); + + // we do NOT extract artifactType / artifactTemplate from the XML, but use the user input + // showDeploymentArtifactInformation will extract its data directly from the XML without querying some input at the other HTML elements + var daArtifactTemplateName = $("#artifactTemplateName").val(); + var daArtifactTypeName = $("#artifactType option:selected").text(); + + // add information to node template shape + var daData = { + nodeTemplateId : currentlySelectedNodeTemplate, + name : daName, + xml : xmlAsString, + artifactTypeName: daArtifactTypeName + }; + if (daArtifactTemplateName != "") { + daData.artifactTemplateName = daArtifactTemplateName; + } + addDeploymentArtifactInfoToNodeTemplate(daData); +} + +function addDeploymentArtifactInfoToNodeTemplate(daData) { + require(["tmpl"], function(tmpl){ + var data = tmpl("tmpl-deploymentArtifact", daData); + var element = $("#" + currentlySelectedNodeTemplate).children(".deploymentArtifactsContainer").children(".content").children(".addDA:first"); + element.before(data); + }); +} + +/** + * This function directly accesses the fields of the dialog, because the return value of the server is XML and we do not want to parse XML + * + * @param artifactInfo = {name, interfaceName (may be undefined), operationName (may be undefined), artifactTemplate (QName, may be undefined), artifactType} + */ +function artifactAddedSuccessfully(artifactInfo) { + var typeNsAndId = getNamespaceAndLocalNameFromQName(artifactInfo.artifactType); + var artifactTemplateNSAndId; + if (artifactInfo.artifactTemplate) { + artifactTemplateNSAndId = getNamespaceAndLocalNameFromQName(artifactInfo.artifactTemplate); + } else { + artifactTemplateNSAndId = undefined; + } + + var daData = { + nodeTemplateId : currentlySelectedNodeTemplate, + name : artifactInfo.name, + artifactTypeName: typeNsAndId.localname, + artifactTypeNSAndId: typeNsAndId, + artifactTemplateName: artifactInfo.artifactTemplateName, + artifactTemplateNSAndId: artifactTemplateNSAndId + }; + require(["tmpl"], function(tmpl){ + daData.xml = tmpl("tmpl-deploymentArtifactXML", daData); + addDeploymentArtifactInfoToNodeTemplate(daData); + $("#addDeploymentArtifactDiagForLinking").modal("hide"); + }); +} + +// variables used for creation of deployment artifacts +var artifactTemplateAutoCreationEnabled = true; +var syncDAnameWithATname; + +// introduced by the handling of deployment and implementation artifacts +// holds the ID only (!) +var currentlySelectedNodeTemplate; + +/** + * FIXME: this function is not updated to the the new dialog design and not included any more + * + * It should be used if the checkbox for at creation changes its checked status or if the at name is not valid + * + */ +function updateArtifactTemplateCreationEnablement(value) { + // remove field highlights + // (currently, no intelligent removal and addition is made) + $("#artifactName").removeClass("highlight"); + $("#artifactTemplateName").removeClass("highlight"); + + if (value) { + // enable it + artifactTemplateAutoCreationEnabled = true; + $("#artifactTemplateName").removeAttr("disabled"); + $("#artifactTemplateNS").removeAttr("disabled"); + $("#createWithoutFilesBtn").attr("disabled", "disabled"); + $("#createWithFilesBtn").removeAttr("disabled"); + } else { + // disable it + artifactTemplateAutoCreationEnabled = false; + $("#artifactTemplateName").attr("disabled", "disabled"); + $("#artifactTemplateNS").attr("disabled", "disabled"); + $("#createWithoutFilesBtn").removeAttr("disabled"); + $("#createWithFilesBtn").attr("disabled", "disabled"); + } +} + +function isShownNodeTemplateShapeChangeBoxes(shape) { + return (shape.find(".endpointContainer").is(":visible")); +} + +/** + * @param shape jQuery object + */ +function showNodeTemplateShapeChangeBoxes(shape) { + shape.find(".addDA").show(); + shape.children(".endpointContainer").show(); + shape.find(".addnewreqorcap").show(); + shape.find(".addnewpolicy").show(); +} + +/** + * @param shape jQuery object + */ +function hideNodeTemplateShapeChangeBoxes(shape) { + shape.find(".addDA").hide(); + shape.children(".endpointContainer").hide(); + shape.find(".addnewreqorcap").hide(); + shape.find(".addnewpolicy").hide(); +} + +// indicates if a connection is currently drawn +// used to decide whether the node template boxes should be displayed +var isInConnectionMode = false; + +function wineryMoveSelectedNodeTemplateShapes(dX, dY) { + var shapes = $("div.NodeTemplateShape.selected"); + hideNodeTemplateShapeChangeBoxes(shapes); + shapes.each(function(i, nodeTemplate) { + nodeTemplate = $(nodeTemplate); + var offset = nodeTemplate.offset(); + offset.left += dX; + offset.top += dY; + nodeTemplate.offset(offset); + }); + jsPlumb.repaint(shapes); +} + + +/** + * Simple eventing framework + * + * use + * winery.events.register(name, function) to register on an event + * and + * winery.events.fire(name) to fire all registered functions + */ + +winery = {}; +winery.events = { + _events : {}, + + /** + * Registers a function + * + * @return the registered function + */ + register : function(eventName, f) { + if (!winery.events._events[eventName]) { + winery.events._events[eventName] = {}; + } + winery.events._events[eventName][f] = f; + return f; + }, + + /** + * Fires all functions associated with the given event name + */ + fire : function(eventName) { + if (winery.events._events[eventName]) { + $.each(winery.events._events[eventName], function(index, value) { + value(); + }); + } + return true; + } +}; + +/** + * Determines whether a key combo is allowed. + * + * For instance, when a modal dialog is opened or a input is selected, DEL should not delete node template shapes + */ +function keyComboAllowed() { + return ((!$(document.activeElement).is("input")) && ($("div.modal:visible").size() == 0)); +} + +function keyComboAllowedAndNodeTemplatesSelected() { + return (keyComboAllowed() && ($("div.NodeTemplateShape.selected").size() != 0)); +} + + + + +/* list of event names */ +winery.events.name = {}; +winery.events.name.command = {}; + +winery.events.name.SELECTION_CHANGED = "selectionchanged"; +winery.events.name.command.SELECT_ALL_NODETEMPLATES = "selectAllNodeTemplates"; +winery.events.name.command.UNSELECT_ALL_NODETEMPLATES = "unselectAllNodeTemplates"; +winery.events.name.command.DELETE_SELECTION = "deleteSelection"; + +winery.events.name.command.MOVE_DOWN = "moveDown"; +winery.events.name.command.MOVE_UP = "moveUp"; +winery.events.name.command.MOVE_LEFT = "moveLeft"; +winery.events.name.command.MOVE_RIGHT = "moveRight"; + +winery.events.name.command.SAVE = "save"; + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/jsp/shared/README.md b/org.eclipse.winery.topologymodeler/src/main/webapp/jsp/shared/README.md new file mode 100644 index 0000000000..4cb255e9fd --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/jsp/shared/README.md @@ -0,0 +1 @@ +This folder is shared between repository and topology modeler \ No newline at end of file diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/jsp/shared/dialogs.jsp b/org.eclipse.winery.topologymodeler/src/main/webapp/jsp/shared/dialogs.jsp new file mode 100644 index 0000000000..21a7fec24f --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/jsp/shared/dialogs.jsp @@ -0,0 +1,83 @@ +<%-- +/******************************************************************************* + * Copyright (c) 2012-2013 University of Stuttgart. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and the Apache License 2.0 which both accompany this distribution, + * and are available at http://www.eclipse.org/legal/epl-v10.html + * and http://www.apache.org/licenses/LICENSE-2.0 + * + * Contributors: + * Oliver Kopp - initial API and implementation and/or initial documentation + * Yves Schubert - switch to bootstrap 3 + *******************************************************************************/ +--%> +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + + + + + + diff --git a/org.eclipse.winery.topologymodeler/src/main/webapp/logback.xml b/org.eclipse.winery.topologymodeler/src/main/webapp/logback.xml new file mode 100644 index 0000000000..6602380ab3 --- /dev/null +++ b/org.eclipse.winery.topologymodeler/src/main/webapp/logback.xml @@ -0,0 +1,15 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}:%line %method - %msg%n + + + + + + + + + diff --git a/org.eclipse.winery.topologymodeler/src/test/java/.gitkeep b/org.eclipse.winery.topologymodeler/src/test/java/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000..d96224abdc --- /dev/null +++ b/pom.xml @@ -0,0 +1,78 @@ + + + + 4.0.0 + org.eclipse.winery + winery + 0.1.37-SNAPSHOT + pom + Winery + Winery is a Web-based environment to graphically model TOSCA topologies and plans managing these topologies. + http://www.eclipse.org/winery + + Eclipse.org - Winery Project + http://www.eclipse.org/winery + + + bugzilla + https://bugs.eclipse.org/bugs/enter_bug.cgi?product=Winery + + 2012 + + + Winery Developer List + winery-dev@eclipse.org + http://dev.eclipse.org/mhonarc/lists/winery-dev + + + + + Eclipse Public License v1.0 + http://www.eclipse.org/legal/epl-v10.html + repo + Standard Eclipse Licence + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + repo + + + + scm:git:http://git.eclipse.org/gitroot/winery/org.eclipse.winery.winery.git/ + HEAD + + + 3.0.3 + + + org.eclipse.winery.generators.ia + org.eclipse.winery.common + org.eclipse.winery.repository + org.eclipse.winery.repository.client + org.eclipse.winery.topologymodeler + + + + + org.codehaus.mojo + versions-maven-plugin + 2.1 + + + +
    + Dump Repository + + +